-
-
[翻译]Windows exploit开发系列教程第十五部分:内核利用程序之UAF
-
发表于: 2018-3-14 20:32 4748
-
点击查看原文
欢迎回到Windows exploit开发系列教程的第十五部分。今天我们来学习基于@HackSysTeam's驱动漏洞的另一种利用姿势。本文我们将写一个UAF(释放后重用)漏洞的exp,这也是首个较为复杂的漏洞课程。我建议读者耐心回顾一下下方列出的资料,它们提供了内核池内存以及保留对象相关知识的易于理解的说明。搭建环境的更多细节请参考本系列教程的第十部分。
本文的侦查这部分有点不太一样,该UAF漏洞中有相当数量的驱动函数卷入进来。我们会逐一审视,最终酌情提供一些细节。
函数分配了非分页内存池块,并用'A'字符填充,指派了一个回调函数指针并添加了一个null结束符。IDA中基本一致,下面的截图可以用来参考。注意对象尺寸是0x58字节,池标签为"Hack"(小端)。
我们可以用下面的PowerShell POC来调用这个函数。
对等考虑,上面的函数对引用标签值的内存池块进行了释放。这个函数包含了UAF漏洞的关键点——在对象被释放后,"g_UseAfterFreeObject"没有置空。这就留下了一个野指针。我们再次试试下面的POC。
注意到该内存块地址和前面分配的是同一个。
该函数从"g_UseAfterFreeObject"读取值并执行该对象的回调函数。如果我们通过下面的POC调用该函数,那么最终以调用到一个不稳定的内存地址而告终,这是因为系统可以自由的把前面释放掉的内存块用于其他目的,只要它合适。
最终,经过一些谋划,我们找到这样一个驱动函数:它允许我们在非分页内存池上分配一个伪造的对象;更为方便的,该函数允许我们把对象分配到原本的UAF对象所在的位置上。
调用该函数的POC在下方。注意,这里我们需要精心制作一个缓冲区并提供一个输入长度。
很好,基本原理上面已经说明。
非常好,也非常简单!
唯一的麻烦在于我们可能遇到内存对齐以及内存池块合并的问题,这里我再次推荐你阅读Tarjei的paper。本质上来说,如果我们释放掉的UAF对象与其他空闲的内存池块毗邻的话,出于性能的考虑,内存分配器会合并这些块。一旦发生这种情况,我们很可能就无法用伪造的对象来占坑了。为了避免这种情况,我们需要对非分页内存池的状态有一个全盘的预测,强制驱动在UAF对象的位置分配内存给我们,以便于后面的覆盖!
我们的第一个目标在于填充,尽可能的把所有非分页内存池“起始”的空闲空间填满。为此我们需要创建一大堆与UAF对象尺寸相近的对象。IoCompletionReverse对象是一个完美的候选者,它在非分页内存池上分配且尺寸为0x60!
首先,在喷射(Spray)内存池之前,让我们先看看IoCompletionReserve的对象类型(对象类型可以通过"!object \ObjectTypes"来查看)。
我们可以使用NtAllocateReserveObject函数来创建IoCo对象。该函数返回一个创建对象的句柄,只要我们不释放该句柄,这个对象将永远在内存池中保留分配态。在下面的POC中我喷射了这些对象到两个位置:
出于调试的目的,该脚本转储了最后的10个句柄到标准输出并且会在WinDBG中自动设置一个断点。
你可以看到这些输出,并在WinDBG上命中断点。
如果我们再看看IoCompletionReserve类型,就可以发现实际上分配了15000个对象!
让我们观察一个标准输出中转储的句柄。
如期所致,这是个IoCompletionReserve对象。同时,考虑到这是我们喷射的最后一批句柄,它们应该在非分页内存池上被连续的分配。
很好,我们看到对象的尺寸是0x60(96)个字节,它们稳定的在内存池中连续分配!最后一步我们会在POC中添加一个例程,用于释放第二次喷射中偶数次分配的IoCompletionReserve对象(一共2500个)来在非分页内存池上挖坑。
这2500个0x60字节大小的空闲内存池块现在就处于一个可预测的位置,它们中的每一个都被两个已分配块所包围,阻止了他们的合并操作!
是时候把所有的过程整合在一起了。
在UseUaFObject函数上下个断点,这里有回调函数的调用并执行到我们最终的POC。
真是好大一盘棋。为了武装我们的POC,我们需要替换回调函数指针成我们的shellcode地址。更多细节请参考下方完整的exp。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
- [翻译]Windows 10 Segment Heap内部机理 19880
- [翻译]Windows 8堆内部机理 7159
- [翻译]深入理解LFH 7787
- [翻译]Bitmap轶事:Windows 10纪念版后的GDI对象泄露 9296
- [翻译]理解池污染三部曲 6821