第 33 章 供应链与依赖逆向
现代软件 90% 的代码来自第三方依赖。供应链逆向 = 分析"你代码里其实运行了什么":依赖漏洞、恶意包、镜像漂移、构建产物与源码不一致。逆向视角 + 治理框架结合。
📍 知识点地图 | 主题:供应链逆向 | 前置:第3章 | 后续:第77章 | 核心概念:SBOM、SCA、镜像漂移、可达性验证
33.1 供应链风险全景(知识架构)
供应链攻击面:
┌──────────────────────────────────────┐
│ 上游 交付物 下游 │
│ 开源包 编译产物 运行时 │
│ 注册表 二进制镜像 生产环境 │
│ 源码提交 安装包 内部系统 │
│ CI/CD 管道 签名产物 供应链伙伴 │
└──────────────────────────────────────┘
攻击点: 依赖投毒 / 构建篡改 / 镜像漂移 / 账号劫持 / 伪包 / 凭据窃取
33.2 六层治理框架(方法论的骨架)
| 层 | 内容 | 逆向分析怎么做 |
|---|---|---|
| 1. SBOM | 软件物料清单(列出所有组件) | 生成 SBOM → 全量清单化 |
| 2. SCA | 依赖漏洞扫描 | 匹配已知漏洞库 |
| 3. 来源可达性验证 | 漏洞真的可达? | 逆向调用链确认(不是扫到就完) |
| 4. CI/CD 管道安全 | 构建环境是否可信 | 检查管道/构建日志/产物 |
| 5. 容器与镜像安全 | 镜像内容 vs Dockerfile 是否一致 | 解镜像对比层/文件 |
| 6. 构建完整性 | 签名/溯源(SLSA/Cosign) | 验签、对比 buildinfo |
33.3 工具链速查
# SBOM 生成(三选一)
syft . -o cyclonedx-json
syft docker:alpine -o spdx-json
# 或 trivy 自带 SBOM 输出
# SCA 扫描
osv-scanner -r . # Google 维护,OSV 数据库
trivy fs . # 文件系统扫描
trivy image alpine:latest # 容器镜像扫描
grype . # Anchore
# 密钥/凭据扫描
gitleaks detect
trufflehog filesystem --only-verified .
# 签名/溯源
cosign verify <image> # 镜像签名验证
# SLSA 可执行性评估(slsa-verifier)
33.4 依赖逆向的核心场景
场景 1:恶意包/投毒分析
触发点: SCA 扫描发现未知包 / 行为异常 / 审计需求
分析流程:
1. 提取包(npm/pip/maven 缓存或下载)
2. 包 = 代码 → 直接读源码(JS/Python)或逆二进制(native 扩展)
3. 找恶意特征:
- 安装脚本(postinstall/requirements 执行逻辑)
- 混淆代码(字符串编码/隐藏逻辑)
- 可疑网络调用(C2/数据外带)
- 环境变量/凭据窃取
4. 逆向混淆层 → 还原行为(第 8/13 章)
5. 产出: 行为报告 + 检测规则(YARA/恶意包特征)
场景 2:二进制镜像漂移
问题: Dockerfile 写的和实际镜像内容不一致(供应链篡改)
方法: 解镜像逐层对比
skopeo copy docker://img dir:out
# 或 docker save 后解 layer
# 对比: 每层文件清单 vs Dockerfile 声明
# 检查: 意外文件/修改的二进制/新增入口点
场景 3:漏洞可达性验证(逆向视角的价值)
SCA 扫到 CVE ≠ 真正危险(可能不可达/不执行)
逆向分析:
1. 定位漏洞组件加载/调用点
2. 确认调用路径可达(入口→调用链)
3. 评估实际利用条件
4. 输出: 真实风险等级(而不是纸面等级)
这是"逆向工程师在供应链安全里的独特价值"
场景 4:构建产物 vs 源码一致性
问题: 宣称开源/可信,但交付二进制与源码不符
方法:
1. 按源码构建(复现构建: 同样工具链/参数)
2. 对比产物哈希/二进制 diff(radiff2/BinDiff)
3. 差异 = 被篡改/额外注入的内容
4. 逆向差异部分 → 确认恶意逻辑
33.5 恶意依赖分析检查清单
□ 包的来源可信?(包名相似性/作者/发布时间异常)
□ 安装时执行了什么(postinstall 等钩子)
□ 代码中是否有混淆/隐藏逻辑
□ 网络行为(域名/IP/回连)
□ 访问了哪些敏感数据(环境变量/密钥/配置文件)
□ 与依赖树中其他包的关系(传递依赖)
□ 版本范围是否锁定
□ 与上游源码是否一致
33.6 决策树
审计一个依赖/镜像
├─ 来源可疑? → 提取包 → 源码审计 + 混淆逆向
├─ 有已知 CVE? → 可达性验证(逆向调用链)
├─ 镜像与声明不符? → 逐层对比 + diff 差异部分
├─ 构建产物存疑? → 复现构建对比哈希
└─ 结论: 风险等级 + 处置建议(升级/移除/隔离)
动手练习
- 对一个开源项目跑
osv-scanner+trivy fs,把扫描结果分类(直接依赖/传递依赖)。 - 从 npm 下载一个小包,阅读它的源码,找 postinstall 或可疑行为。
- 用 syft 生成一个项目的 SBOM,对比"你以为是依赖"和"实际依赖"的差异。
- 选一个已知 CVE 的组件,用逆向方法确认它在目标项目中是否可达。
深入阅读
- 仓库:
skills/supply-chain-security/SKILL.md(六层治理框架全量) - 仓库:
skills/supply-chain-security/references/cicd-pipeline-security.md(管道安全) - 仓库:
skills/supply-chain-security/references/sbom-sca-methodology.md(SBOM/SCA 方法论) - 仓库:
skills/attack-chain/SKILL.md(供应链攻击视角) - 仓库:
CTF-Sandbox-Orchestrator/competition-supply-chain/(供应链 CTF 子技能) - 仓库:
CTF-Sandbox-Orchestrator/competition-container-runtime/(容器运行时漂移专项)