Windows注册表漏洞实战利用:内存损坏与权限提升

本文深入探讨Windows注册表内存损坏漏洞的实战利用技术,详细分析如何通过越界单元格索引实现内核内存读写,最终完成从普通用户到SYSTEM权限的完整提权过程。

Windows注册表漏洞实战利用:内存损坏与权限提升

引言

在之前的博客文章中,我们重点讨论了注册表的安全分析以及如何有效发现其中的漏洞。本文将重点关注基于hive的内存损坏漏洞的利用,即允许攻击者覆盖活动hive映射中数据的漏洞。这是Windows注册表特有的一类问题,但也具有足够的通用性,本文描述的技术适用于我过去的17个漏洞,以及未来可能出现的任何类似漏洞。

内存损坏漏洞分类

与任何其他类型的内存损坏一样,绝大多数hive内存损坏问题可以分为两类:

  • 空间违规(如缓冲区溢出)
  • 时间违规(如释放后使用)

利用策略

利用经典内存损坏漏洞通常涉及以下步骤:

  1. 初始内存损坏原语
  2. 利润(以任意代码执行、权限提升等形式)

开发人员的任务是填补此列表中的空白,设计实现所需目标的中间步骤。在当前的安全状态和缓解措施下,漏洞很少能一步到位地从内存损坏直接导致代码执行。

系统hive攻击

要仅通过损坏regf格式数据(无需访问其他内核内存或实现任意代码执行)成功执行攻击并提升权限,必须满足两个条件:

  1. 漏洞必须仅通过API/系统调用即可触发,并且不需要对hive进行二进制控制
  2. 目标hive必须包含至少一个具有足够宽松访问权限的键

根据我的测试,在当前Windows 11系统中,HKLM下大约有1678个键授予普通用户创建子键的权限。其中1660个位于HKLM\SOFTWARE,18个位于HKLM\SYSTEM。

利用技术:越界单元格索引

单元格索引是hive中等价于指针的32位值,允许分配的单元格相互引用。将单元格索引转换为其对应的虚拟地址是通过称为单元格映射的特殊3级结构实现的。

关键发现是:对于小于2 MiB的hive,Windows应用称为"small dir"的额外优化。在这种情况下,攻击者可以通过完全控制32位单元格索引值,使转换逻辑通过从越界内存获取的两个指针进行跳转,然后向结果添加受控的12位偏移。

实战利用步骤

步骤0:选择漏洞

从大约17个与hive内存损坏相关的漏洞中,我们选择CVE-2023-23420进行演示。此漏洞涉及键节点单元格的释放后使用条件,可以通过仅使用API/系统调用触发,使其成为攻击任何攻击者具有写权限的hive的理想候选。

步骤1:滥用UAF建立动态控制的值单元格

我们的攻击将针对HKCU hive,特别是其易失存储空间。利用过程从键节点释放后使用开始,我们的目标是在第一阶段结束时完全控制两个注册表值的_CM_KEY_VALUE表示。

步骤2:获取对CMHIVE内核对象的读写访问权限

通过精心构造的越界单元格索引,我们可以获取对hive的_CMHIVE结构在内核池中的读写访问权限。这需要绕过HvpReleaseCellPaged中的边界检查。

步骤3:获取对整个内核地址空间的任意读写访问权限

此时,我们可以通过魔法值读取和写入_CMHIVE结构,也可以操作解析为有效地址的任何其他越界单元格索引。这意味着我们不再需要担心内核ASLR。

步骤4:提升进程安全令牌

通过任意内核读写原语和ntoskrnl.exe地址,提升权限已成为形式化过程。最简单的方法可能是遍历由_EPROCESS结构组成的所有进程的链表,找到"System"进程和我们自己的进程,然后将前者的安全令牌复制到后者。

结论

通过本文,我们展示了如何利用Windows注册表中的内存损坏漏洞,从初始的内存损坏原语逐步发展到完整的内核内存读写能力,最终实现从普通用户到SYSTEM权限的完整提权过程。这些技术不仅具有学术价值,在实际攻击中也具有很高的实用性。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计