Windows 注册表 Hive 利用 原语
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
为什么 hive 损坏很特殊
Windows registry hives 是由自定义分配器 (HvAllocateCell, HvReallocateCell, HvFreeCell) 管理的内存映射 .regf 文件。该分配器:
- 不随机化分配 – cell 的放置仅取决于先前 registry API 调用的顺序/大小,因此布局在不同主机上是可重现的。
- 缺乏完整性检查 – 手动修改的 header/data 字段会被内核消费者(
Cmp*routines)和注册表进程自身信任。 - 与特权 hive 共享地址空间 – 在许多情况下,攻击者控制的 hive 会映射到与 HKLM/HKU hive 相同的 user-mode 地址范围,从而能触发跨 hive 的溢出。
这使得基于 hive 的内存损坏漏洞(例如 CVE-2023-23420 / CVE-2023-23423)在 LPE 场景下特别可靠。
使用 registry APIs 进行确定性布局整理
因为 hive 分配是确定性的,你可以纯粹通过 Win32 APIs 来整理 cell 放置。一个典型工作流程是:
- 重置目标键(删除/重建),使 hive bin 仅包含已知的 cells。
- 通过创建具有精心选择大小的值来分配可预测的 cell 连续段:
- Key/value 元数据 cell 是 8 字节的倍数。
- 写入
0x3FD8字节的值会强制创建一个新的0x4000字节 bin(0x3FD8数据 +_HBINheader/填充),便于后续交错 bins。
- 使用易于调整大小的类型(例如
REG_BINARY),这样你可以仅通过使用不同长度调用RegSetValueEx来释放/扩展单个 cell。 - 记录操作序列(create/delete/resize)。重放该序列会在其他系统上重现相同布局,因为分配器没有随机性。
示例布局整形器(简化的 C)
```c void MakeBin(HKEY base, const wchar_t *name, size_t bytes) { std::vectorvoid Groom(HKEY hive) { for (int i = 0; i < 0x20; ++i) { wchar_t value[32]; swprintf(value, L“bin_%02d“, i); MakeBin(hive, value, 0x3FD8); RegDeleteKeyValueW(hive, NULL, value); // leaves holes for victim cells } }
</details>
## 通过错误配置的后代实现对特权 hive 的仅 API 访问
Windows 只会评估注册表路径的 **最终组件上的 ACL**。如果 HKLM/HKU 下的任一后代项向低权限用户授予 `KEY_SET_VALUE`、`KEY_CREATE_SUB_KEY` 或 `WRITE_DAC`,即使所有父项都被锁定,你仍然可以访问它。Project Zero 在 Windows 11 的 HKLM 中发现了 **>1000 个这样的可写键**,包括长期存在的条目如 `HKLM\SOFTWARE\Microsoft\DRM` 和若干 `HKLM\SYSTEM` 分支。
实用的枚举策略:
1. 从提权的上下文,遍历 `\Registry\Machine` 和 `\Registry\User`,导出每个键的安全描述符。保存那些 DACL 允许非特权 SID 的项。
2. 作为普通用户,针对记录的路径尝试用 `RegOpenKeyEx` 请求 `KEY_SET_VALUE|KEY_CREATE_SUB_KEY`。打开成功的路径是可行目标,适用于需要攻击者可控数据写入系统 hive 的损坏漏洞。
3. 维护一份指向 **稳定可写位置** 的打开句柄缓存,以便 PoC 能直接部署损坏的元数据。
```powershell
$targets = Get-ChildItem Registry::HKEY_LOCAL_MACHINE -Recurse |
Where-Object { (Get-Acl $_.PsPath).Access.IdentityReference -match 'S-1-5-32-545' } |
Select-Object -ExpandProperty PsPath
foreach ($path in $targets) {
try { Get-Item -Path $path -ErrorAction Stop | Out-Null }
catch {}
}
一旦路径已知,利用时就不需要离线 hive 篡改——标准 registry APIs 就足够 在由 SYSTEM 服务触及的特权 hive 中布置损坏的 cells。
Cross-user hive abuse via HKCU\Software\Microsoft\Input\TypingInsights
每个用户 hive 都包含 HKCU\Software\Microsoft\Input\TypingInsights,其 ACL 授予 KEY_ALL_ACCESS 给 Everyone (S-1-1-0). 在 Microsoft 采取收紧措施之前,任意用户可以:
- 将另一个用户的 hive 填满 直到 2 GiB 限制,导致登录失败或强制 hive 截断(可用于强制分配器行为或 DoS)。
- 向其他用户的
NTUSER.DAT投放损坏的 cells,为横向利用做准备,当受害进程读取被破坏的键时触发。 - 修改差异 hive(differencing hives),针对依赖于每用户 overlay hives 的沙箱应用,迫使它们使用恶意元数据。
这使得 hive 损坏漏洞适用于 lateral movement,不仅限于同一账户内的权限提升。
Turning metadata corruption into paged pool overflows
Large registry values are stored in _CM_BIG_DATA records:
_CM_KEY_VALUE.DataLength保存逻辑大小。其高位表示 payload 是在 cell 内还是在 big-data 存储中。_CM_BIG_DATA.Count计数通过 chunk table 引用的 16 KiB chunk(16384 字节减去元数据)。
当任何组件调用 CmpGetValueData 时:
- 内核按
DataLength严格分配一个 paged pool buffer。 - 它从 hive 存储复制
Count * 0x4000字节到该缓冲区。
如果你能破坏 cell 使 DataLength < 16344 * (Count - 1),复制会线性地越界写入相邻的 paged-pool 对象。一个可靠的 exploit 链是:
- 使用确定性的 groom 将易受攻击的
_CM_KEY_VALUE放置在可控元数据附近。 - 将
DataLength翻小(例如 0x100),同时保持_CM_BIG_DATA.Count不变。 - 从用户态进行 pool-groom(pipes、ALPC ports、section objects),使选定对象(如
EPROCESS->Token所在者或SRVNET_BUFFER)在步骤 1 的分配之后占据下一个 chunk。 - 触发读取(例如
RegQueryValueEx、NtQueryValueKey),使CmpGetValueData复制所有 chunk 并用来自 hive 的攻击者控制数据覆盖邻居的字段。 - 利用被破坏的内核对象转向任意读/写或直接窃取 SYSTEM token。
由于 overflow 长度等于 (Count * 0x4000) - DataLength,你获得了一个精确的字节预算并对写入的字节拥有完全控制,优于许多基于驱动的 pool overflow。
Inter-hive linear overflows via tightly packed HBINs
Hives mounted by the Registry process are mapped in 2 MiB-aligned views with no guard gaps。你可以强制两个不同的 hive 同步增长,直到它们的 _HBIN 区域接触:
- 选择一个可由攻击者写入的 hive(app hive 或 user hive)和一个特权目标(例如
HKLM\SOFTWARE)。 - 在两个 hive 中持续创建/删除
0x3FD8字节的值。每次分配会添加一个0x4000字节的 bin,所以并行运行两个写入者会在虚拟内存中交错它们的 bins(可使用!process Registry+!vad观察到)。 - 一旦攻击者 hive 的最后一个 bin 紧邻属于 HKLM 的 HBIN,使用 hive 损坏 bug 从攻击者 hive 溢出,破坏 HKLM 内的 HBIN 头或 cells。
- 在控制了 HKLM 元数据后你可以:
- 在特权 hive 中直接部署 big-data 不一致原语。
- 在数据离开内核之前破坏被 SYSTEM 服务消费的配置数据。
由于缺少 guard pages,来自非特权 hive 的线性覆盖可以直接破坏 SYSTEM 拥有的 hive 结构,从而在 HKLM/HKU 内实现仅数据的攻击或设置上文所述的 pool overflow。
Operational tips
- 使用
!vad(用户态)和!reg view/!pool(内核)监视 hive 的布局,确认在触发 overflow 前已相邻。 - 缓存枚举期间发现的可写 HKLM 路径,以便在重启后也能迅速部署损坏原语。
- 将 hive grooming 与标准的 pool feng shui(pipe pair freelists、
NtAllocateVirtualMemory在Registryprocess 上)结合,以稳定溢出后的原语。
References
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
HackTricks

