Windows内核漏洞利用

来源:岁月联盟 编辑:猪蛋儿 时间:2020-01-29

堆栈缓冲区溢出
在第一部分中,我们会从HackSysExtremeVulnerableDriver中的普通堆栈缓冲区溢出开始。
当堆栈上存在的缓冲区获取的数据超出其存储容量时(例如,在一个16字节缓冲区中复制20个字节,就可以是字符数组或类似对象),其余数据将写入附近位置,从而有效覆盖或破坏堆栈。
其核心思想是控制此溢出,这样我们可以覆盖堆栈上保存的返回地址,并且在执行当前(易受攻击的)函数后,它将返回我们的覆盖值,其中包含我们的shellcode。
注意:执行完shellcode后,代码执行必须返回到应用程序,在本例中是内核,否则将破坏应用程序。通常,应用程序崩溃了,我们可以重新启动它,但是如果内核内存损坏,内核会发出内核恐慌,并且将显示“蓝屏死机”,这是我们最不希望发生的事情。
为了解决这个问题,我们需要恢复执行路径,以便在执行完shellcode之后,它返回到执行易受攻击的函数后应该返回的函数。
易受攻击性
现在我们已经清除了它,让我们看一下易受攻击的代码(位于StackOverflow.c中的函数TriggerStackOverflow)。最初,该函数创建可容纳512个成员元素的ULONG数组(在common.h头文件中,BufferSize设置为512)。

易受攻击性的函数
然后,内核检查缓冲区是否驻留在用户区域中,然后在非页面缓冲池中为其分配内存。
一旦完成,内核便将数据从用户模式缓冲区复制到内核模式KernelBuffer,该模式实质上是一个ULONGs数组。

溢出
注意RtlCopyMemory的第三个参数,它本质上是memcpy,Size参数是用户模式缓冲区的大小,而不是内核模式缓冲区的大小,这正是缓冲区溢出发生的地方。
漏洞验证
现在,要验证错误是否真正存在,我们将编写一个函数,该函数调用函数StackOverflowIoctlHandler的IOCTL。 IOCTL代码在Exploit / common.h文件中给出。
注意:我们可以从编译的驱动程序本身获取IOCTL代码,既然我们有自己的优势,所以为什么不使用它?
什么是IOCTL代码?
I/O控制代码(IOCTL)用于用户模式应用程序和驱动程序之间的通信,或用于堆栈中驱动程序内部的通信,I/O控制代码是使用IRP发送的。
基本上,如果驱动程序具有与之关联的IOCTL代码,则可以直接在该驱动程序中调用内核函数。要使用IOCTL代码,我们使用DeviceIoControl函数,函数可在此处找到。
DeviceIoControl函数的原型为:

DeviceIoControl的原型
我用C++编写了一个函数,该函数调用DeviceIoControl来调用StackOverflowIoctlHandler,后者依次调用TriggerStackOverflow,这是易受攻击的函数。
由于我们知道缓冲区有512个ULONG,因此可以肯定的是,此后,我们将添加Metasploit框架中pattern_create.rb生成的100字节模式。
最后,将此缓冲区发送到HEVD,看看会发生什么?
注意:此函数在标头文件StackOverflow.h中,主函数调用它,你可以在我的代码库中找到整个代码。

利用堆栈溢出的POC

利用堆栈溢出的POC
在Win7设备上编译并执行二进制文件后,我们可以在WinDbg中获得它:

在WinDbg中崩溃
我们可以看到有一个访问冲突,EIP指向31624130。
在此模式上使用Metasploit的pattern_offset.rb之后,我们找到它的偏移量32,让我们继续进行开发。
利用溢出
现在剩下的就是使用HEVD中提供的TokenStealingPayloadWin7 shellcode覆盖保存的返回地址,然后完成。
注意:你可能需要稍微修改shellcode,以免崩溃。
获取Shell
首先验证我们是否是普通用户:

普通用户
可以看出,我只是一个普通的用户。运行漏洞利用程序后,我成为了NT权限/系统。

NT Authority/SYSTEM Shell
类型混淆
在第二部分中,我们将绕过常见的内存损坏漏洞(在我们正在利用的驱动程序中,内存损坏漏洞占大多数)。因为利用起来很容易,我还要使其成为本文的第一部分。
什么是类型混淆?
类型混淆是一个漏洞,其中应用程序不验证对象的类型(函数,数据类型等),然后按预期方式对其进行处理,但传递的对象是其他对象。
漏洞
现在我们已经清除它,让我们看一下易受攻击的代码(位于TypeConfusion.c中的函数TriggerTypeConfusion)。
内核首先检查缓冲区是否驻留在用户域中,然后在非页面缓冲池中为其分配内存。完成此操作后,内核将用户模式缓冲区中的ObjectID分配给内核模式缓冲区,并对对象类型执行相同的操作。

[1] [2] [3]  下一页