reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,271 @@
# 二进制差分工具对比
补丁差分的核心工具是二进制 diff 引擎。本文档对比当前主流工具的强项、安装、典型命令、输出解读,以及组合工作流。
---
## 工具总览
| 工具 | 作者/厂商 | 底座 | License | 强项 | 弱项 |
|------|---------|------|---------|------|------|
| **BinDiff** | Google (zynamics) | IDA Pro / Ghidra / Binary Ninja | 免费 | 业界标杆,函数级匹配最稳,GUI 视图清晰 | 需要 IDA 才能玩到极致 |
| **Diaphora** | Joxean Koret | IDA Pro | GPL | 老牌、活跃维护、SQLite 持久化、支持伪代码 diff | 重度依赖 IDA Pro,对超大二进制慢 |
| **ghidriff** | Clearbluejar | Ghidra headless | Apache 2.0 | 纯 CLI,CI 友好,输出 markdown,免费开源 | 准确度依赖 Ghidra 反编译 |
| **DeepDiff** (Karambit) | Karambit.AI | 自带 | 商业 | LLM 辅助、变量名重命名感知 | 商业授权 |
| **radiff2** | radare2 项目 | radare2 | LGPL | 全开源、嵌入 r2 工作流 | 函数匹配能力弱于 BinDiff |
| **patchdiff2** | tetrane | IDA | GPL | IDA 老插件,年代久 | 已基本被 BinDiff/Diaphora 取代 |
---
## BinDiff
### 安装
Linux:
```bash
wget https://github.com/google/bindiff/releases/latest/download/bindiff_8-amd64.deb
sudo dpkg -i bindiff_8-amd64.deb
```
Windows:
```powershell
# 从 https://github.com/google/bindiff/releases 下 .msi
msiexec /i bindiff_8.msi /quiet
# 自动注册到 IDA Pro 插件目录
```
### IDA 内使用
1. 在 IDA 里加载 unpatched 二进制,分析完,`File → Produce file → BinExport` 导出 `old.BinExport`
2. 加载 patched 二进制,同样导出 `new.BinExport`
3. `Edit → Plugins → BinDiff` → 选 new.BinExport 对比 → 输出 .BinDiff 数据库
### CLI 用法
```bash
# 直接两个二进制 diff(先用 binexport 提取)
bindiff old.exe new.exe
# 或显式给 BinExport
bindiff --primary=old.BinExport --secondary=new.BinExport \
--output_dir=./bindiff_out/
# 输出: ./bindiff_out/old_vs_new.BinDiff (SQLite)
```
### 输出读法
打开 .BinDiff 文件后,关键列:
- `similarity` — 0.0 ~ 1.0,函数相似度
- `confidence` — 算法信心
- `algorithm` — 匹配算法 (name hash, function hash, MD index 等)
聚焦工作区:
- **similarity 1.0 + confidence 1.0** — 完全不变,跳过
- **similarity 0.0 (unmatched)** — 新增或重大重构,留意但通常是新功能
- **similarity 0.5 ~ 0.95** — 重点目标,多半是修了 bug
- **similarity 0.95 ~ 0.99** — 微调,可能是 mitigation 或 cleanup
GUI 内:双击函数 → 看 graph view 的 basic block 着色:
- 灰:完全相同
- 黄:相似但有指令差异
- 红:新增或删除
- 蓝:仅 patched 有的 block — **重点看这种**
---
## Diaphora
### 安装
```bash
cd ~/idapro/plugins/
git clone https://github.com/joxeankoret/diaphora.git
# 在 IDA 里 File → Script file → ~/idapro/plugins/diaphora/diaphora.py
```
### 工作流
1. IDA 打开 unpatched → 跑 `diaphora.py` → 选 "Export current database" → 保存 `old.sqlite`
2. IDA 打开 patched → 跑 `diaphora.py` → 选 "Diff against another database" → 选 `old.sqlite` → 输出对比报告
### 输出读法
Diaphora 输出多个 tab:
- **Best matches** — 高置信度匹配,跳过
- **Partial matches** — 部分匹配,**重点看这里**
- **Unreliable matches** — 算法不确定,可能误报
- **Unmatched in primary / secondary** — 单边出现的函数
每个函数支持 side-by-side 伪代码 diff(IDA 反编译输出)。
### 关键 SQL 查询
Diaphora 用 SQLite 存数据,可写 SQL 找目标:
```sql
-- 找出 diff 比例在中等区间的函数
SELECT f1.name, f2.name, ratio
FROM results
WHERE ratio BETWEEN 0.5 AND 0.9
ORDER BY ratio DESC;
```
---
## ghidriff
### 安装
```bash
pip install ghidriff
# ghidriff 会自动下载 Ghidra 到 ~/.ghidra/ (首次运行需要联网)
# 或指定 Ghidra 路径:
export GHIDRA_INSTALL_DIR=/opt/ghidra_11.0
```
### 基础用法
```bash
# 最小命令
ghidriff old.so new.so
# 指定输出目录 + 引擎
ghidriff old.exe new.exe \
-o ./diff_out/ \
--engine VersionTrackingDiff \
--threaded \
--max-section-funcs-analyze 5000
# 看所有可用引擎
ghidriff --list-engines
# 常见: VersionTrackingDiff (默认), SimpleDiff, StructualGraphDiff
```
### 输出格式
ghidriff 默认输出三种产物:
1. **Markdown 报告** — 人类可读,包含 added / deleted / modified 函数清单 + 伪代码 diff 块
2. **JSON 报告** — 程序化消费
3. **GhidraProject** — 可以打开继续手工分析
报告关键章节:
- `## Summary` — 总体统计 (匹配率)
- `## Strings Diff` — 字符串变化(信息泄漏类 CVE 经常字符串变了)
- `## Functions` → `### Modified` — 重点
- 每个函数下: `before` / `after` 伪代码 + unified diff
### 推荐参数
```bash
# Windows 内核大文件:限制单 section 分析数量,避免 OOM
ghidriff ntoskrnl_old.exe ntoskrnl_new.exe \
-o /tmp/nt_diff/ \
--max-section-funcs-analyze 8000 \
--max-section-funcs-full 800 \
--threaded
# 大量小函数(驱动):开启所有 diff
ghidriff afd_old.sys afd_new.sys -o /tmp/afd_diff/ --side-by-side
```
### 配 LLM 自动总结
ghidriff 支持插件式输出,可以喂给 LLM 自动生成根因分析(见 root-cause-and-poc.md 的 LLM 章节)。
```bash
# 输出 JSON 给下游 LLM 脚本消费
ghidriff old new -o out/ --json-format
python my-llm-summarizer.py out/diff.json
```
---
## radiff2
### 安装
```bash
# 通常随 radare2 安装
sudo apt install radare2
# 或源码
git clone https://github.com/radareorg/radare2 && radare2/sys/install.sh
```
### 用法
```bash
# 字节级 diff
radiff2 old.bin new.bin
# 函数级 diff (需要先各自 r2 分析)
radiff2 -A -C old.bin new.bin # -A 分析, -C 函数级
# 输出 graph (Graphviz)
radiff2 -g main old new | dot -Tpng -o diff.png
# JSON 输出
radiff2 -j -A -C old new > diff.json
```
适合:与 radare2 工作流深度集成的场景,或者 BinDiff/Ghidra 跑不动的小文件。
---
## DeepDiff (Karambit.AI, 商业)
特点:
- 不依赖 IDA / Ghidra
- 自带反编译器
- 用 ML 模型做函数匹配,对 inline / rename / 控制流变化更鲁棒
- 自动生成 root cause 假设
适合资金充足的团队批量处理 Patch Tuesday。本文档不展开,因需要商业授权。
---
## 工具组合工作流
### 推荐组合(按场景)
```text
场景 A: 有 IDA Pro 授权,质量优先
BinDiff (主) + Diaphora (副验证) + LLM 辅助根因
场景 B: 无 IDA,纯开源
ghidriff (主) + LLM 辅助根因
场景 C: 批量 Patch Tuesday 流水线
ghidriff CLI + JSON → 脚本筛选 → 人工 review top N
场景 D: 小型驱动 / 嵌入式 firmware
radiff2 / ghidriff 都行
```
### 粗筛 → 精看 流程
```text
Step 1 (粗筛): 跑 ghidriff,过滤
- 整体 matched 比例 < 90% → 警惕,多半对齐失败 (可能是不同编译器、不同混淆)
- matched 比例 > 99% → 补丁很微小,可能只动 1-2 个函数
- 列出 Modified 函数清单,按变更行数排序
Step 2 (优先级): 按以下加权
- 函数名含敏感词 (Ioctl / DispatchIoCtrl / Probe / Copy / Length) +5
- 出现在已知攻击面驱动 (afd/clfs/win32k) +5
- 变更涉及 if 边界 / lock / refcount +3
- 仅做字符串 / 日志变更 -3
Step 3 (精看): 把 top 10 函数喂给 BinDiff GUI 或 IDA 手工,
或贴 before/after 伪代码给 LLM 反推 bug class
```
---
## 常见坑
- **对齐失败**:matched 比例 < 90% 时不要继续。先确认两个二进制是同一编译器版本、同一架构、同一优化等级。常见原因:跨大版本编译器、PGO/LTO 不同、ASLR rebase 没对齐
- **inline 函数把 diff 撑大**:编译器决定 inline 的函数变了会让父函数大范围变红,但根本没改逻辑。要看真实控制流分支
- **switch table 重排**:编译器可能重排 case,看着像新增 block,其实只是顺序变化
- **Profile-Guided Optimization (PGO) 抖动**:连续两个版本的二进制即使源码一字不改也可能 layout 不同
- **stripped Linux 内核**:没 debuginfo 时所有函数名都是 `FUN_xxxx`,必须先吃 BTF / kallsyms 或用 binary-diff 迁移符号

View File

@@ -0,0 +1,253 @@
# Patch Tuesday 工作流
每月第二个周二 (Pacific Time) 微软发布安全更新,俗称 Patch Tuesday。这是 N-day 研究最稳定的输入源:补丁数量大、价值高、披露口径统一。本文档给出从订阅公告到拿到可对比二进制的完整流程。
---
## 1. 信息源订阅
| 来源 | 用途 | 备注 |
|------|------|------|
| MSRC Security Update Guide | 当月所有 CVE 列表 + CVSS + 受影响产品 | https://msrc.microsoft.com/update-guide/ 有 API |
| MSRC CVRF API | 程序化拉当月 CVE JSON | `https://api.msrc.microsoft.com/cvrf/v3.0/cvrf/{YEAR}-{Mon}` |
| Microsoft Update Catalog | 下 MSU/MSP 实物 | https://www.catalog.update.microsoft.com/ |
| Patch Tuesday Dashboard (Tenable / Trend / Rapid7) | 第三方汇总优先级 | 看哪些标了 "exploited in the wild" |
| ZDI advisories | ZDI 提交的 CVE 详细描述 | 经常有比 MSRC 更详细的 root cause hint |
| Project Zero 周期性 issue tracker | 半年后会公开细节 | 可作为历史对照 |
### 拉当月 CVE 列表 (PowerShell)
```powershell
$year = '2026'; $mon = 'May'
$url = "https://api.msrc.microsoft.com/cvrf/v3.0/cvrf/$year-$mon"
Invoke-RestMethod $url | ConvertTo-Json -Depth 10 | Out-File "C:\patches\msrc-$year-$mon.json" -Encoding utf8
```
---
## 2. 锁定高价值补丁
按以下顺序过滤当月公告:
1. **CVSS >= 7.0**
2. **Exploitation: Exploitation Detected / More Likely**
3. **组件白名单**(高价值攻击面):
- `Windows Kernel` (ntoskrnl.exe)
- `Win32k` (win32k.sys, win32kfull.sys, win32kbase.sys)
- `Ancillary Function Driver for WinSock` (afd.sys) — 历史 LPE 大户
- `Common Log File System` (clfs.sys) — 过去三年多次被野利用
- `Print Spooler` (spoolsv.exe, win32spl.dll)
- `Cloud Files Mini Filter Driver` (cldflt.sys)
- `NTFS` (ntfs.sys)
- `Hyper-V` (vmswitch.sys, hvix64.exe, hvax64.exe)
- `Cryptography Services` / `NTLM` / `Kerberos`
- `RDP` (rdpcorets.dll, rdpbase.dll)
4. **本地提权 (EoP) > RCE > Info Disclosure** — EoP 武器化门槛最低
5. **是否有 KB 直接对应** — 没有 KB 号的(例如纯 Defender 定义更新)跳过
---
## 3. 下载 patched / unpatched 二进制
### 3.1 Microsoft Update Catalog 手动下
```text
1. 访问 https://www.catalog.update.microsoft.com/Search.aspx?q=KB5052000
2. 按 Products 过滤 (Windows 11, Server 2022 等)
3. 选目标架构 (x64 / arm64),下载 .msu
4. 同时下 N-1 版本 (上个月的 KB 号) 作为 unpatched 基线
```
### 3.2 程序化批量下
```powershell
# msdownload 第三方脚本
git clone https://github.com/JaschaUrbach/msu-downloader.git
python msu-downloader.py --kb KB5052000 --arch x64 --out C:\patches\
```
### 3.3 wsuspect-proxy 拦截真实流量取最新补丁
适用于:MSRC 还没在 Catalog 上架,但已通过 WU 推送给客户端的早期窗口。
```bash
git clone https://github.com/ctxis/wsuspect-proxy.git
cd wsuspect-proxy
# 在被测机器上手工设 WSUS = http://attacker:8530,触发 wuauclt /detectnow
python wsuspect-proxy.py --listen 0.0.0.0:8530 --dump-cabs C:\patches\dump\
```
### 3.4 Delta 包 vs Cumulative 包
- 微软现在主推 `.msu` cumulative update — 体积大但完整
- 也有 `.msu` Express / Delta 包 — 体积小但只含差异,对差分研究不友好
- 优先下 cumulative
---
## 4. 解包 MSU / CAB / MSP
### 4.1 MSU 解包(Windows)
```powershell
# Step 1: MSU 是 cab 套娃,先解外层
expand.exe Windows-KB5052000-x64.msu -F:* C:\patches\out\
# Step 2: 解里面的 .cab
expand.exe C:\patches\out\Windows-KB5052000-x64.cab -F:* C:\patches\out\
# Step 3: 关键文件在 amd64_microsoft-windows-{component}_*\ 下
# 例如 ntoskrnl.exe 在:
# C:\patches\out\amd64_microsoft-windows-os-kernel_*\ntoskrnl.exe
```
### 4.2 用 dism 装到离线镜像(拿干净的 patched 二进制)
```powershell
# 挂载离线 WIM
dism /mount-image /imagefile:install.wim /index:1 /mountdir:C:\mnt
# 应用补丁
dism /image:C:\mnt /add-package /packagepath:Windows-KB5052000-x64.msu
# 提取目标二进制
copy C:\mnt\Windows\System32\ntoskrnl.exe C:\patches\patched\
# 卸载
dism /unmount-image /mountdir:C:\mnt /commit
```
### 4.3 MSP (Office 等) 解包
```powershell
# MSP 是 Windows Installer Patch
msiexec /a base.msi /p update.msp TARGETDIR=C:\patches\office_patched
# 或用 lessmsi (推荐, 不动注册表)
lessmsi x update.msp C:\patches\office_msp\
```
### 4.4 用第三方工具一站式拆包
```powershell
# PatchExtract by Greg Linares - 一条命令解多层
.\PatchExtract.ps1 -PatchFile Windows-KB5052000-x64.msu -ExtractedFolder C:\patches\extracted\
```
---
## 5. 取符号 (PDB)
```powershell
# Windows SDK 自带 symchk
symchk /v /r C:\patches\patched\ntoskrnl.exe /s SRV*C:\sym*https://msdl.microsoft.com/download/symbols
symchk /v /r C:\patches\unpatched\ntoskrnl.exe /s SRV*C:\sym*https://msdl.microsoft.com/download/symbols
```
注意:微软偶尔会延迟或下架某个版本 PDB。如果当前下不到 N-1 的 PDB,用 `binary-diff` skill 把 N-2 的 PDB 符号迁移到 N-1。
---
## 6. Windows 高价值二进制路径速查
| 文件 | 路径 | 关注组件 |
|------|------|---------|
| ntoskrnl.exe | System32\ | 内核核心、对象管理、Ob*、Ps*、Mm*、Io* |
| win32k.sys | System32\ | GUI 子系统入口 |
| win32kfull.sys | System32\ | GUI 完整版(桌面会话) |
| win32kbase.sys | System32\ | GUI 基础库 |
| afd.sys | System32\drivers\ | WinSock AFD,LPE 高发 |
| clfs.sys | System32\drivers\ | CLFS,0-day 高发 |
| cldflt.sys | System32\drivers\ | Cloud Files mini filter |
| spoolsv.exe | System32\ | Print Spooler |
| dwm.exe | System32\ | Desktop Window Manager |
| lsass.exe | System32\ | LSA 认证 |
| ntdll.dll | System32\ | syscall stub、PE loader |
| ksecdd.sys | System32\drivers\ | Kernel security driver |
---
## 7. Linux 等价流程
### 7.1 信息源
| 来源 | 适用 |
|------|------|
| Ubuntu USN | https://ubuntu.com/security/notices |
| Red Hat RHSA | https://access.redhat.com/security/security-updates/ |
| Debian DSA | https://www.debian.org/security/ |
| CentOS / Rocky / Alma announce list | 通常 mirror Red Hat |
| upstream kernel CVE list | https://cve.kernel.org/ |
### 7.2 拉补丁包
```bash
# Debian/Ubuntu
apt download linux-image-5.15.0-101-generic
apt download linux-image-5.15.0-100-generic
apt download linux-image-unsigned-5.15.0-101-generic-dbgsym
# CentOS/Rocky
dnf download --downloadonly --downloaddir=./patched kernel-5.14.0-362.18.1.el9_3
dnf download --downloadonly --downloaddir=./unpatched kernel-5.14.0-362.13.1.el9_3
```
### 7.3 解包
```bash
# .deb
dpkg-deb -x linux-image-5.15.0-101-generic_*.deb ./patched/
# .rpm
rpm2cpio kernel-5.14.0-362.18.1.el9_3.x86_64.rpm | cpio -idmv -D ./patched/
```
### 7.4 从 vmlinuz 还原 vmlinux
```bash
# 用内核自带 scripts/extract-vmlinux
wget https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux
chmod +x extract-vmlinux
./extract-vmlinux ./patched/boot/vmlinuz-5.15.0-101-generic > vmlinux_5.15.0-101
./extract-vmlinux ./unpatched/boot/vmlinuz-5.15.0-100-generic > vmlinux_5.15.0-100
```
### 7.5 关注子系统路径
| 子系统 | 历史 N-day 高发函数前缀 |
|--------|----------------------|
| net/ | `__skb_*`、`sk_*`、`tcp_*`、`udp_*`、`nf_*` |
| fs/ | `do_*`、`vfs_*`、`__lookup_*` |
| io_uring/ | 整个子系统(近三年漏洞王) |
| netfilter/ | `nft_*`、`nf_tables_*` |
| net/sched/ | tc 各 qdisc |
| drivers/net/ | 各 NIC 驱动 |
| bpf/ | verifier 类 |
---
## 8. 真实公开 CVE 案例参考
| CVE | 组件 | 类型 | 用于练手原因 |
|------|------|------|------------|
| CVE-2025-62215 | Windows Kernel | race condition + double free | 2025-11 公开,公告说"race + double free",差分入门题 |
| CVE-2023-28252 | CLFS | OOB write → LPE | 野外利用,PoC 已公开,可对照学习方法 |
| CVE-2022-37969 | CLFS | type confusion → LPE | 同样有公开分析 |
| CVE-2021-40449 | Win32k | UAF → LPE | 公开报告完整 |
| CVE-2022-21882 | Win32k | type confusion,由 CVE-2021-1732 不完整修复变出 | 经典"一鱼多吃"案例 |
练习建议:拿一个已经有公开分析的 CVE,按本流程独立差出来一次,再对照公开 writeup 校准方法论。
---
## 9. 速查清单
- [ ] MSRC 月度公告已读,筛出 CVSS≥7 且组件在白名单内的 CVE
- [ ] 从 Catalog 下到 unpatched (N-1) 和 patched (N) 的 MSU
- [ ] 用 expand / dism 取出目标 .exe / .sys / .dll
- [ ] symchk 把 PDB 都吃到(吃不到走 binary-diff 迁移)
- [ ] 用 BinaryNinja / IDA / Ghidra 各开两个工程
- [ ] 跑 BinDiff / ghidriff,导出 diff 报告
- [ ] 按相似度过滤函数,进 `references/root-cause-and-poc.md` 反推根因
- [ ] 写 PoC,验证 unpatched 崩、patched 不崩
- [ ] 回写 field-journal 记录复用经验

View File

@@ -0,0 +1,198 @@
# 根因反推与 PoC 编写
拿到 diff 报告只是第一步。真正的工作是看着 before/after 反推出 bug class,然后写出能稳定触发的 PoC。本文档给出反推模式表、LLM 辅助 prompt、PoC 编写模板、验证方法。
---
## 1. 补丁修复模式 → 漏洞类型反查
### 1.1 整数溢出 / 下溢
**新增模式**:
```c
// 加法溢出检查
if (a > UINT_MAX - b) goto error;
if (a + b < a) goto error;
__builtin_add_overflow(a, b, &sum);
// 乘法溢出检查
if (a != 0 && b > UINT_MAX / a) goto error;
__builtin_mul_overflow(a, b, &prod);
// 减法下溢检查
if (a < b) goto error;
```
**反推**:
- 看 `a` 和 `b` 是否来自用户态可控输入
- 通常前后会有 `kmalloc(a+b)` / `RtlAllocateHeap(size)` 等分配,溢出后分配过小 → 后续 memcpy → 堆 OOB 写
**PoC 思路**:
- 让 `a + b` 实际溢出回小值,但拷贝长度还按未溢出的算
- 边界值: `a = 0xFFFFFFF0, b = 0x100` (32 位) / `a = 0xFFFFFFFFFFFFFFF0, b = 0x100` (64 位)
---
### 1.2 越界读 / 越界写
**新增模式**:
```c
if (idx >= ARRAY_SIZE(arr)) return -EINVAL;
if (offset + len > buf_size) return STATUS_INVALID_PARAMETER;
if (len > sizeof(local_buf)) return -E2BIG;
// Windows 内核典型
if (InputBufferLength < sizeof(MY_STRUCT)) return STATUS_BUFFER_TOO_SMALL;
if (req->Length > KERNEL_MAX) return STATUS_INVALID_PARAMETER;
```
**反推**:
- 看新增 if 守护了哪个后续操作(memcpy / memmove / 数组下标)
- 没守护前的版本可以传超大 length / 超大 index
**PoC 思路**:
- 把 length 字段设成超过 buf 的值
- 把 index 字段设成 array_size + N
- 用 IOCTL InputBufferLength 调到刚好绕过旧检查但触发新检查
---
### 1.3 竞争条件 (Race / TOCTOU)
**新增模式**:
```c
// 加锁
KeAcquireSpinLockAtDpcLevel(&obj->Lock);
mutex_lock(&inode->i_mutex);
spin_lock(&list->lock);
// 引用计数原子化
InterlockedIncrement(&obj->RefCount);
ObReferenceObject(obj);
get_file(file);
// 检查 - 操作之间不再释放锁
```
**反推**:
- 加锁说明此前同一对象在并发场景下被改了
- 引用计数加 ref 说明此前对象可能在用的时候被释放
- 找两个 syscall 路径,其中一个会修改 / 释放对象,另一个会用对象
**PoC 思路**:
```c
// 经典 hammer
DWORD WINAPI thread_close(LPVOID arg) {
while (running) CloseHandle((HANDLE)arg);
return 0;
}
DWORD WINAPI thread_use(LPVOID arg) {
while (running) DeviceIoControl((HANDLE)arg, IOCTL_X, ...);
return 0;
}
// CreateThread 各开几个,sleep 30s 等崩
```
- 多线程绑核 (SetThreadAffinityMask) 提高竞争概率
- 用 `_mm_pause()` / `sched_yield()` 控制窗口
- 配合 syscall pinning(同一对象的两个不同入口)
---
### 1.4 未初始化内存信息泄漏
**新增模式**:
```c
// 字段清零
RtlZeroMemory(&output, sizeof(output));
memset(buf, 0, sizeof(buf));
output.reserved = 0;
output.padding = 0;
output._pad1 = 0;
// 整个结构归零再赋值
KeStackAttachProcess; output = (MY_STRUCT){0};
```
**反推**:
- 旧版从内核栈 / 内核堆拷数据到用户态时没清 padding / reserved 字段
- padding 内残留前一次函数调用的栈数据 → 内核地址泄漏 (绕 KASLR)
**PoC 思路**:
- 反复调 IOCTL 取 output buffer
- 把每个字节按 8 字节解析,找像内核地址的值(Windows: 0xFFFFxxxx / Linux: 0xFFFFFFFFxxxxxxxx)
- 找规律 → 推 kbase
---
### 1.5 UAF / 引用计数错误
**新增模式**:
```c
// Windows
if (InterlockedDecrement(&obj->RefCount) == 0) {
Free(obj);
return;
}
// Linux
if (refcount_dec_and_test(&obj->ref)) {
kfree(obj);
}
// 或新增 ObReferenceObject 在某条路径上(之前漏加 ref)
```
**反推**:
- 旧版某条出错路径 free 了对象但调用者还会用
- 或者多路径同时持有指针,其中一条 free 后其他没感知
**PoC 思路**:
```c
// spray → free → reuse
HANDLE objs[1000];
for (int i = 0; i < 1000; i++) objs[i] = CreateObject(...);
trigger_free(objs[500]); // 触发漏洞 free
spray_kernel_pool(0xDEADBEEFDEADBEEF, target_sz); // 占住被 free 的洞
use_after_free(objs[500]); // 触发用 -> 控数据
```
- Windows 内核常用 `NtAllocateReserveObject` / Pipe 属性 / Window Class 名称喷
- Linux 常用 `msgsnd` / `setxattr` / `userfaultfd`-stalled vma 喷
---
### 1.6 用户态指针未校验
**新增模式**:
```c
// Windows
ProbeForRead(UserBuffer, Length, sizeof(ULONG));
ProbeForWrite(UserBuffer, Length, sizeof(ULONG));
// __try/__except 包裹访问
__try {
Probe...
RtlCopyMemory(KernelBuf, UserBuffer, Length);
} __except(EXCEPTION_EXECUTE_HANDLER) { ... }
// Linux
if (!access_ok(VERIFY_WRITE, ptr, size)) return -EFAULT;
copy_from_user(kbuf, uptr, len);
```
**反推**:
- 旧版直接 deref 用户态指针没 ProbeForRead/access_ok
- 用户态可以传内核地址 → 任意地址读 / 任意地址写
**PoC 思路**:
- 传一个内核空间指针(例如 ntoskrnl 某个全局变量地址)作为输入指针
- 内核执行 `*UserBuffer = X` 时实际写到内核地址 → 任意写
---
### 1.7 权限校验缺失
**新增模式**:
```c
if (!SeAccessCheck(...)) return STATUS_