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对象实现读写原语:
- 泄露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地址
// 堆喷加速器表
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特有字段
调试技巧
- 使用调试器验证
gSharedInfo结构 - 观察pool分配和重用模式
- 比较不同Windows版本中关键结构的变化
- 使用
!pool命令检查对象内存布局
后续研究方向
- RS4/RS5版本的利用方法探索
- 新的信息泄露技术
- 绕过最新缓解措施的其他思路
- 从利用技术反推漏洞分析技术
结论
Windows内核漏洞利用是一个不断演进的过程,随着微软引入新的缓解措施,研究者需要不断寻找新的绕过方法。从bitmap到palette的转变展示了漏洞利用技术的适应性和创造性。理解这些技术的演进过程对于开发新的利用方法至关重要。