windows内核系列六: 从windows 7撸到windows 10(下)
字数 2026 2025-08-18 11:35:38

Windows内核漏洞利用:从Windows 7到Windows 10(下)

前言

本文是Windows内核漏洞利用系列的第六篇,重点讨论在Windows 10 RS1、RS2和RS3版本中的利用技术。我们将分析微软引入的缓解措施以及相应的绕过方法。

回顾:Windows 7到Windows 8.1 1503的利用

在之前的版本中,我们主要利用bitmap对象实现读写原语:

  1. 泄露hmanager bitmap和hworker bitmap地址
  2. 泄露出它们的pvScan0地址
  3. 利用write-what-where将hmanager的pvScan0改为hworker pvScan0地址
  4. 读操作:
    • 对hmanager setbitmapbits使worker的pvScan0变为任意地址
    • 使用hworker getbitmapbits对任意地址进行读操作
  5. 写操作:
    • 对hmanager setbitmapbits使worker的pvScan0变为任意地址
    • 使用hworker getbitmapbits对任意地址进行写操作

Windows 10 RS1(1607)的缓解措施

在RS1版本中,微软修改了GdiShreadHandleTable的行为:

  • 1511版本:GdiShreadHandleTable指向真实指针
  • 1607版本:GdiShreadHandleTable不再指向真实指针,导致之前的利用方法失效

绕过方法:泄露bitmap地址

虽然直接获取bitmap地址的方法失效,但我们可以通过gSharedInfo结构来泄露内核地址:

  1. gSharedInfo结构包含aheList表,存放与句柄关联的信息
  2. 每个HANDLE_ENTRY结构包含指向该句柄的内核地址
  3. 通过计算可以获取内核对象地址

具体实现步骤

  1. 使用CreateAcceleratorTableDestroyAcceleratorTable进行堆喷

    • 不断分配和释放pool,观察地址重用情况
    • bitmap对象也位于paged pool session,大小相似
  2. 通过分配相同大小的bitmap,利用地址重用泄露bitmap地址

    • 实验表明,传入参数700时重用稳定性较好
  3. 泄露基地址

    • 使用NtQuerySystemInformation获取内核模块信息
    • 第二个参数指定查询类型(内核模块信息)

Windows 10 RS2的利用

在RS2版本中,微软进一步限制了信息泄露:

  • HANDLE_ENTRY结构体的pkernel字段被禁用
  • gSharedInfo泄露bitmap地址的方法失效

替代方法:使用tagCLS对象

  1. 利用tagCLS对象及其lpszMenuName字段
  2. 方法与第四章中描述的类似
  3. 通过精心构造的对象布局实现信息泄露

Windows 10 RS3的利用

在RS3版本中,微软对bitmap对象做了重大修改:

  • pvScan0pvBits指向的对象移到heap中
  • 传统的bitmap利用技术失效

替代方法:使用Palette对象

  1. Palette对象具有与bitmap类似的结构
  2. 即使在RS3版本上仍然可用
  3. 利用步骤:
    • 创建Palette对象
    • 研究其pool分配大小关系(类似第四章对bitmap的分析)
    • 实现类似的读写原语

总结与思考

项目经验

  1. 从Windows 7到Windows 10各版本都找到了可利用的方法
  2. 通过阅读paper+调试+阅读源码的方式完成研究
  3. 后期项目可以直接复用代码,专注于WWW(write-what-where)构造

缓解措施演进

绕过思路的演进过程:

  1. 最初使用bitmap(通过GDISHAREDHANDLETABLE)
  2. GDISHAREDTABLE被限制 → 改用gSharedInfo
  3. gSharedInfo被限制 → 改用fengshui预判
  4. bitmap被限制 → 改用palette对象

关于RS4和RS5

在RS4/RS5中:

  1. HmValidateHandle失去效果,失去泄露GDI对象的直接方法
  2. 可能有新的思路待验证(作者提到有想法但尚未实验)

关键代码与技术要点

RS1泄露bitmap地址

// 堆喷加速器表
for(int i=0; i<1000; i++) {
    hAccel = CreateAcceleratorTable(accel, 1);
    DestroyAcceleratorTable(hAccel);
}

// 分配bitmap
hManager = CreateBitmap(0x1000, 0x1000, 1, 8, NULL);
hWorker = CreateBitmap(0x1000, 0x1000, 1, 8, NULL);

// 通过gSharedInfo泄露地址
PSHAREDINFO gSharedInfo = GetSharedInfo();
PHANDLEENTRY entry = &gSharedInfo->aheList[handle_index];
ULONG_PTR kernelAddr = entry->phead;

RS3使用Palette对象

// 创建Palette对象
HPALETTE hPal = CreatePalette(pal);

// 利用Palette实现读写原语
// 类似bitmap的操作,但使用Palette特有字段

调试技巧

  1. 使用调试器验证gSharedInfo结构
  2. 观察pool分配和重用模式
  3. 比较不同Windows版本中关键结构的变化
  4. 使用!pool命令检查对象内存布局

后续研究方向

  1. RS4/RS5版本的利用方法探索
  2. 新的信息泄露技术
  3. 绕过最新缓解措施的其他思路
  4. 从利用技术反推漏洞分析技术

结论

Windows内核漏洞利用是一个不断演进的过程,随着微软引入新的缓解措施,研究者需要不断寻找新的绕过方法。从bitmap到palette的转变展示了漏洞利用技术的适应性和创造性。理解这些技术的演进过程对于开发新的利用方法至关重要。

Windows内核漏洞利用:从Windows 7到Windows 10(下) 前言 本文是Windows内核漏洞利用系列的第六篇,重点讨论在Windows 10 RS1、RS2和RS3版本中的利用技术。我们将分析微软引入的缓解措施以及相应的绕过方法。 回顾:Windows 7到Windows 8.1 1503的利用 在之前的版本中,我们主要利用bitmap对象实现读写原语: 泄露hmanager bitmap和hworker bitmap地址 泄露出它们的pvScan0地址 利用write-what-where将hmanager的pvScan0改为hworker pvScan0地址 读操作: 对hmanager setbitmapbits使worker的pvScan0变为任意地址 使用hworker getbitmapbits对任意地址进行读操作 写操作: 对hmanager setbitmapbits使worker的pvScan0变为任意地址 使用hworker getbitmapbits对任意地址进行写操作 Windows 10 RS1(1607)的缓解措施 在RS1版本中,微软修改了 GdiShreadHandleTable 的行为: 1511版本: GdiShreadHandleTable 指向真实指针 1607版本: GdiShreadHandleTable 不再指向真实指针,导致之前的利用方法失效 绕过方法:泄露bitmap地址 虽然直接获取bitmap地址的方法失效,但我们可以通过 gSharedInfo 结构来泄露内核地址: gSharedInfo 结构包含 aheList 表,存放与句柄关联的信息 每个 HANDLE_ENTRY 结构包含指向该句柄的内核地址 通过计算可以获取内核对象地址 具体实现步骤 使用 CreateAcceleratorTable 和 DestroyAcceleratorTable 进行堆喷 不断分配和释放pool,观察地址重用情况 bitmap对象也位于paged pool session,大小相似 通过分配相同大小的bitmap,利用地址重用泄露bitmap地址 实验表明,传入参数700时重用稳定性较好 泄露基地址 使用 NtQuerySystemInformation 获取内核模块信息 第二个参数指定查询类型(内核模块信息) Windows 10 RS2的利用 在RS2版本中,微软进一步限制了信息泄露: HANDLE_ENTRY 结构体的 pkernel 字段被禁用 gSharedInfo 泄露bitmap地址的方法失效 替代方法:使用tagCLS对象 利用 tagCLS 对象及其 lpszMenuName 字段 方法与第四章中描述的类似 通过精心构造的对象布局实现信息泄露 Windows 10 RS3的利用 在RS3版本中,微软对bitmap对象做了重大修改: 将 pvScan0 和 pvBits 指向的对象移到heap中 传统的bitmap利用技术失效 替代方法:使用Palette对象 Palette对象具有与bitmap类似的结构 即使在RS3版本上仍然可用 利用步骤: 创建Palette对象 研究其pool分配大小关系(类似第四章对bitmap的分析) 实现类似的读写原语 总结与思考 项目经验 从Windows 7到Windows 10各版本都找到了可利用的方法 通过阅读paper+调试+阅读源码的方式完成研究 后期项目可以直接复用代码,专注于WWW(write-what-where)构造 缓解措施演进 绕过思路的演进过程: 最初使用bitmap(通过GDISHAREDHANDLETABLE) GDISHAREDTABLE被限制 → 改用gSharedInfo gSharedInfo被限制 → 改用fengshui预判 bitmap被限制 → 改用palette对象 关于RS4和RS5 在RS4/RS5中: HmValidateHandle 失去效果,失去泄露GDI对象的直接方法 可能有新的思路待验证(作者提到有想法但尚未实验) 关键代码与技术要点 RS1泄露bitmap地址 RS3使用Palette对象 调试技巧 使用调试器验证 gSharedInfo 结构 观察pool分配和重用模式 比较不同Windows版本中关键结构的变化 使用 !pool 命令检查对象内存布局 后续研究方向 RS4/RS5版本的利用方法探索 新的信息泄露技术 绕过最新缓解措施的其他思路 从利用技术反推漏洞分析技术 结论 Windows内核漏洞利用是一个不断演进的过程,随着微软引入新的缓解措施,研究者需要不断寻找新的绕过方法。从bitmap到palette的转变展示了漏洞利用技术的适应性和创造性。理解这些技术的演进过程对于开发新的利用方法至关重要。