逆向工程实战手册 第 19 章

第 19 章 补丁差分与 N-day 分析

N-day = 已知 CVE 编号但还没人公开 PoC。思路:厂商发补丁 → 对比补丁前后二进制 → 从新增安全检查反推漏洞点 → 写 PoC。与"跨版本符号迁移"(binary-diff)分工:一个偏防御分析(迁移符号),一个偏攻击(定位漏洞)。

📍 知识点地图 | 主题:补丁差分N-day | 前置:第18章 | 后续:— | 核心概念:BinDiff、Diaphora、根因反推、PoC

19.1 N-day 武器化全流程

1. 获取补丁前后二进制(Patch Tuesday / MSRC / 供应商网站)
2. 对齐符号(同一函数对应起来)
3. 二进制 diff → 定位变更函数
4. 分析新增检查 → 反推漏洞根因
5. 写 PoC 触发
6. 武器化(Metasploit 模块 / exploit 脚本)

19.2 获取补丁材料

渠道 说明
Microsoft Update Catalog 官方补丁下载
Patch Tuesday 每月第二个周二,MSRC 公告
厂商安全公告 附补丁链接
GitHub Security Advisories 开源项目补丁 commit(最容易)
# 开源项目: 直接 diff 前后 commit
git log --oneline -5
git diff v1.0.0 v1.0.1 -- src/vuln.c

19.3 二进制 diff 工具对比

工具 特点
BinDiff IDA 插件,业界标准(Google)
Diaphora 免费开源,支持 IDA/Ghidra,相似度+图匹配
ghidriff Ghidra 原生 diff
DeepDiff 新秀,自动定位函数级变更
radiff2 radare2 自带,快速粗对比
LLM 结构化 diff 大规模函数级对比 + 语义理解(本仓库特色)
# 快速对比
radiff2 old.exe new.exe
radiff2 -C old.exe new.exe      # 代码对比

# Diaphora: IDA 中 File → Script file → diaphora.py
# 先导出第一个,再打开第二个 diff

19.4 从 diff 到漏洞根因(核心方法)

新增安全检查往往长这样:

// 补丁前
memcpy(dst, src, len);          // 无长度检查

// 补丁后
if (len > MAX) return -1;       // ← 新增检查!
memcpy(dst, src, len);

反推思路

□ 新增的 if/边界检查 → 对应的未检查路径就是漏洞
□ 新增的校验/清理函数 → 调用它的入口是攻击面
□ 新增的解锁/锁 → 竞态问题
□ 替换的 API(strcpy→strncpy)→ 缓冲区溢出
□ 新增的编码/转义 → 注入类漏洞
□ 新增的初始化 → 未初始化使用

19.5 Patch Tuesday 工作流(微软专项)

1. 公告日: 拉取 MSRC 公告列表
2. 筛选: 目标产品(如 Windows 内核/Exchange/IIS)
3. 下载更新包: Update Catalog
4. 解包: 提取更新后的 DLL/exe
5. 与旧版本 diff(Diaphora/BinDiff)
6. 定位变更函数 → 分析 → PoC

19.6 写 PoC 的工程要点

□ 先证明崩溃(sanitizer/调试器观察到内存破坏)
□ 再证明控制流劫持(RIP/EIP 可控)
□ 最后提升为 RCE(结合第 18 章利用链)
□ 每个阶段最小化:能触发就不多余
□ 多平台/多版本验证

19.7 LLM 批量符号迁移(binary-diff 技能)

场景:旧版有符号、新版无符号(缺 PDB),需要把旧函数名迁移到新偏移。

方法:
1. 提取旧版符号表(函数名+特征)
2. 提取新版函数结构特征(哈希/图结构/常量)
3. 批量匹配(200 函数成本约 1 元量级)
4. 输出迁移映射(YAML)

适用:内核补丁分析、商业软件升级分析、恶意软件家族版本对比。

19.8 检查清单

□ 获取补丁前后二进制
□ 符号对齐(结构/导入/字符串相似度)
□ diff 定位变更函数(BinDiff/Diaphora/ghidriff)
□ 分析新增检查 → 根因归类(溢出/注入/竞态/逻辑)
□ 确认攻击面可达性(谁调用、什么输入)
□ 写 PoC(触发 → 崩溃 → 劫持)
□ 多版本验证
□ 出报告 + 沉淀经验

动手练习

  1. 找一个小型开源项目的两个版本(含安全修复 commit),手动对比修复 diff 理解根因。
  2. 用 radiff2 对比一个程序的新旧版本,感受二进制级 diff 的输出。
  3. 练习"从新增检查反推漏洞":读 3 个 CVE 的官方修复补丁,写下每个的漏洞类型。
  4. 用 Diaphora 跑一次两个相似二进制函数的 diff。

深入阅读

  • 仓库:skills/patch-diff-exploit/SKILL.md(N-day 武器化总纲)
  • 仓库:skills/patch-diff-exploit/references/diff-tools-comparison.md(工具选型)
  • 仓库:skills/patch-diff-exploit/references/patch-tuesday-workflow.md(微软专项)
  • 仓库:skills/patch-diff-exploit/references/root-cause-and-poc.md(LLM 辅助根因 + PoC)
  • 仓库:skills/binary-diff/SKILL.md(LLM 批量符号迁移,与 19.7 对应)
  • 仓库:skills/binary-diff/references/prompt-template.md