Windows注册表漏洞实战利用:深入解析Hive内存破坏技术
在之前的博客文章中,我们重点讨论了注册表的安全分析以及如何有效查找其中的漏洞。在这里,我们将注意力转向基于Hive的内存破坏漏洞的利用,即那些允许攻击者覆盖活动Hive内存映射中数据的漏洞。这是Windows注册表特有的一类问题,但又足够通用,本文描述的技术适用于我过去的17个漏洞,也可能适用于未来的任何类似漏洞。
漏洞分类与利用策略
与其他类型的内存破坏一样,绝大多数Hive内存破坏问题可以分为两类:空间违规(如缓冲区溢出)和时间违规(如释放后使用)。
我们的目标是从这些漏洞中选择最有希望的候选者,然后为其创建分步利用程序,将常规用户的权限从Medium IL提升到系统级权限。我们的目标是Windows 11,并且需要成功绕过所有现代安全缓解措施。
利用路径分析
利用经典内存破坏漏洞通常涉及以下步骤:
- 初始内存破坏原语
- 逐步开发更强的原语
- 最终目标(任意代码执行、权限提升等)
在Hive内存破坏的情况下,我们的选择似乎有限:我们假设可以完全控制Hive中任何单元格的表示,但问题是从利用的角度来看,其中没有立即有趣的数据。然而,这并不意味着Hive内存破坏不可利用。
跨Hive内存破坏
虽然Hive内存映射在一定程度上是隔离和自包含的,但它们并非存在于真空中。Windows内核在内核池空间中分配和管理许多与注册表相关的附加对象。这些对象的内存安全性与Hive映射中相应数据的一致性密切相关。
用户空间中的Hive映射
在Registry进程的用户空间中映射Hive的section视图是绝大多数注册表的默认行为。通过WinDbg可以轻松观察到内存中各个映射的布局。测试表明,受信任和不受信任的Hive映射会交错排列,每个2 MiB长度,紧密打包了512个16 KiB的bin。
基于池的Hive映射中的相邻内存攻击
尽管Hive文件视图通常映射在Registry进程的用户模式空间中,但在某些情况下,这些数据直接存储在内核模式池中。这些情况包括:
- 所有易失性Hive
- 整个HKLM\SYSTEM Hive
- 最近通过在先前不存在的文件上调用NtLoadKey*系统调用创建的所有Hive
- 系统中每个活动Hive的易失性存储空间
终极原语:越界单元格索引
单元格索引是Hive的指针等价物:它们是32位值,允许分配的单元格相互引用。通过完全控制32位单元格索引值,我们可以使转换逻辑通过从越界内存获取的两个指针跳转,然后将受控的12位偏移量添加到结果中。
这种技术特别强大,因为对于小于2 MiB的Hive,Windows应用了称为"small dir"的额外优化。在这种情况下,内核将_CMHIVE.Hive.Storage[…].Map指针设置为_CMHIVE.Hive.Storage[…].SmallDir字段的地址,该字段模拟单元素数组。
实际漏洞利用编写
步骤0:选择漏洞
在约17个与Hive内存破坏相关的漏洞中,我们选择CVE-2023-23420进行演示利用。这是一个关于键节点单元格的释放后使用条件,由事务性键重命名操作中的某些问题引起。
步骤1:滥用UAF建立动态控制的值单元格
我们的攻击将针对HKCU Hive,更具体地说是其易失性存储空间。利用过程始于键节点释放后使用,我们的目标是在第一阶段结束时完全控制两个注册表值的_CM_KEY_VALUE表示。
步骤2:获取对CMHIVE内核对象的读写访问权限
通过精心构造的OOB单元格索引,我们可以获取对_CMHIVE结构的读写访问权限。但是,在HvpReleaseCellPaged函数中存在边界检查,会阻止使用OOB索引。
通过将_CMHIVE.Hive.Storage[1].Length字段覆盖为非常大的值(如0xFFFFFFFF),我们可以绕过此边界检查,从而无限制地读写任何OOB索引。
步骤3:获取对整个内核地址空间的任意读写访问权限
此时,我们可以通过魔法值读写_CMHIVE结构,也可以操作解析为有效地址的任何其他OOB单元格索引。通过巧妙设置"KernelAddr"和"KernelData"值,我们可以创建一个独特的设置,用户可以在默认Windows安装可用的图形界面工具中查看和修改内核内存。
步骤4:提升进程安全令牌
通过任意内核读写原语和ntoskrnl.exe地址,提升权限只是一个形式。最简单的方法可能是迭代从nt!KiProcessListHead开始的所有进程链表(由_EPROCESS结构组成),在列表中找到"System"进程和我们自己的进程,然后将前者的安全令牌复制到后者。
利用缓解措施
越界单元格索引在注册表中是一种强大的利用技术,其主要优势在于其确定性。在特定版本的操作系统中,给定的OOB索引将始终导致引用_CMHIVE结构的相同字段,这消除了使用任何概率性利用方法(如内核池喷洒)的需要。
由于单元格索引边界检查已经存在于HvpReleaseCellPaged中,将其移动到HvpGetCellPaged应该在系统性能方面完全中立,并且将完全防止将OOB索引用于任何恶意目的。
结论
通过本文,我们展示了如何将初始的Hive内存破坏原语逐步升级为完整的权限提升攻击链。从初始内存破坏到内核权限提升,我们涵盖了OOB Cell索引、内核对象操纵和现代安全缓解措施绕过等高级技术。这些技术不仅具有学术价值,而且在实际攻击场景中具有高度实用性。