译者注:年前曾经翻译过本系列的第十部分 ,后来因为一些事情一度断更。从春节到现在陆陆续续翻译了后续的一些章节,发到看雪论坛,供二进制安全初学者学习。 在翻译的过程中,原本是想用自己的截图对原文进行替换(第十部分即是如此),但考虑到本地的一些表现和原文有一定出入,所以最终决定一概保留原文的截图,特此说明。 点击查看原文
欢迎来到Windows exp开发系列的第十一部分。今天我们会使用HEVD来编写一个内核层任意位置任意写的漏洞exp。关于调试环境安装的细节请参考第十部分。因为时间有限,我一般会非常快速的过一遍这些邮件,但如果你有任何疑问的话请依然让我知晓,我们开始吧!
HackSysExtremeVulnerableDriver (hacksysteam) - here
Driver write-what-where vulnerability - here
Arbitrary Memory Overwrite exploitation using HalDispatchTable - here
让我们看一看含有该漏洞的函数(here )。
该驱动持有两个指针,一个用于展示驱动将写入内存的值,另一个提供了驱动将要写的位置。同样的,显示了漏洞的同时也显示了安全的实现体。这里的问题在于驱动没有检查目标指针的地址是否在用户空间,因此我们可以用任意4字节值覆写任意内核4字节地址。
此前我们看到过如何通过分析IrpDeviceIoCtlHandler表来获取函数的IOCTL。这里我们将学习一种不同的方法。驱动头文件driver header 展示了所有的定义的函数。
I/O控制码(IOCTL's)又一些不同的组件(类型,码值,方法,访问权限)构成。有意思的是WDK有一个标准的宏可以用于定义新的IOCTL。我们实际上可以通过仿真该宏的功能来提取出所有的有效的IOCTL。
阅读更多关于宏的说明here 。现在我们有了IOCTL,让我们使用IDA的图形显示板快速的检查一下。
看起来不错,有个稍微让我困惑的事情是函数要如何决定它将要写哪些字节。它不会写你给它的4字节,它会把这4字节当成一个指针并写入该指针指向的地址处开始的4字节值。缓冲区结构如下。
记住这一点,如果你简单的指定你的shellcode的地址,它实际上会写你的shellcode的前4个字节。
我快速组织了一个POC来测试能否顺利调用这个函数。
很好,我们有了exp的原型。
真正的问题是到底要覆盖哪个地址(在内核空间),如何找到可信赖的地址,执行后不会BSOD(蓝屏)。幸运的是这项艰巨的工作已经有人做过了,我们可以覆盖一个内核的分发表指针,这相对来说安全(在Ruben Santamarta的2007年发表的“Exploiting common flaws in drivers”论文中第一次描述)。它揭示出有一个未文档化(罕用)的函数——NtQueryIntervalProfile用于量度计数滴答之间的性能。这个函数内部调用了KeQueryIntervalProfile系统调用。反汇编KeQueryIntervalProfile,看起来没什么特别的。
NtQueryIntervalProfile最终会调用一个在HalDispatchTable+0x4处的指针。如果我们可以覆盖该指针使其指向我们的shellcode,那么当调用NtQueryIntervalProfile时我们的shellcode就可以在内核层运行了。
现在我们知道了想要覆盖的地方,我们还需要弄清楚如何找到HalDispatchTable的地址。幸运的是,我们可以利用一个有用的未文档化的函数——NtQuerySystemInformation。如果我们调用NtQuerySystemInformation且指定SystemModuleInformation类我们可以获取一个加载的模块列表以及他们各自的基地址(包括NT内核)。我将节约读者去看关于该函数糟糕的细节的时间,我写了一个PowerShell脚本来做这一项工作, Get-SystemModuleInformation 。
它有效的绕过了内核中的ASLR,因为我们可以使用加载模块的基地址来计算任意函数的偏移。下面你会看到使用简单的指针算术运算来获取HalDispatchTable偏移的过程。
我们可以重用上一节创建的窃取token的shellcode,完善其中的一部分。
我们无需还原那些此前所用的额外说明。此外,我们劫持了一个函数调用,所以需要保存寄存器的状态,shellcode执行后需要返回到执行流继续正常执行。
这就是完整的运行体,设置指针以及分配shellcode的过程中海有一些次要的细节。可以参考下面完整的exp来了解更多信息。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-3-15 20:25
被玉涵编辑
,原因: