在上一篇文章中,我们为读者介绍了实现提权过程中需要了解的关键数据结构,以及实现提权的相关shellcode;在本文中,我们将为读者介绍如何维护驱动程序的完整性等方面的知识。
现在,我们已经了解了实现令牌窃取功能的payload的所执行的过程(最终将获得NT AUTHORITY\SYSTEM权限);接下来,我们来考察一下该payload的最后一段代码。
最后一段代码的作用是恢复驱动程序中的执行流程。如果我们不执行这最后一步的话,将无限期地导致系统崩溃。
这里的想法是将一切恢复到原来的路径上面。幸运的是,在这种攻击情况下,我们可以在执行实现令牌窃取功能的payload之前保存寄存器的状态。然后,在这个payload完成后,我们可以恢复寄存器的状态。在x86架构上,可以通过PUSHAD/POPAD指令来实现这一点。一旦我们恢复了寄存器的状态,我们就可以将驱动程序指向调用包含相关漏洞的子程序后的一组指令。
为此,可以在WinDBG中执行如下命令:u HEVD!StackOverflowIoctlHandler+10。
在这里我们可以看到,从HEVD!TriggerStackOverflow返回后,紧接的两条指令是POP EBP; RET 0x8;。所以,我们需要在实现令牌窃取功能的payload末尾引入这两条指令,同时还需要设置STATUS_SUCCESS代码,以恢复驱动程序的完整性。
现在,我们已经了解实现令牌窃取功能的payload所执行的操作,之后,我们可以用Nasm处理代码,并使用Hexdump来检索payload的内容。
下面是我们要在exploit中实现的令牌窃取shellcode:
数据执行保护(DEP)最早是在Windows XP SP2和Windows Server 2003 SP1发布时引入的一种安全保护机制,用于阻止从不可执行的内存区域中执行代码。
DEP有两种工作模式:
1. 硬件强制模式:适用于支持将内存页标记为不可执行的CPU。
2. 软件强制模式:适用于没有相关硬件支持的CPU(不在本文介绍范围之内)。
硬件强制模式的DEP启用了非可执行性(NX)位,它可以区分内存中的数据和代码区域。该位告诉CPU是接受还是拒绝执行内存区域内的代码。
在全局层面上,操作系统可以被配置为在如下所示的模式下运行:
1. OptIn模式--只在系统进程和自定义应用程序上启用DEP。
2. OptOut模式--除明确豁免的应用外,所有应用都启用DEP。
3. AlwaysOn模式--DEP永久启用
4. AlwaysOff模式--永久禁用DEP
从Windows XP SP3/Windows Vista SP1及更高版本开始,微软实现了一种安全机制,以防止在运行时禁用DEP。这种机制被称为“永久性DEP”。让我们简单地介绍一下DEP,以及它在HEVD驱动程序的漏洞利用过程中是如何发挥作用的。
在debuggee机器上,让我们打开cmd.exe并检查硬件强制模式的DEP是否可用。如果硬件强制模式的DEP可用,让我们进一步检查一下,看看支持哪种模式。这些检查可以使用以下命令完成:wmic OS Get DataExecutionPrevention_Available与wmic OS Get DataExecutionPrevention_SupportPolicy。
在上面的屏幕截图中,我们可以看到硬件强制模式的DEP是可用的(输出为TRUE),并且操作系统支持的策略级别是OptIn(输出为2)。
现在我们已经知道:硬件强制模式的DEP已经启用并设置为OptIn模式,下面,让我们仔细研究一下cmd.exe进程,看看DEP是如何在该进程中起作用的。为此,我们可以在WinDBG中通过检查cmd.exe进程的_KPROCESS数据结构中的Flags成员来完成该任务,具体如下所示:
要递归地查看KPROCESS数据结构,请使用以下命令:dt nt!_KPROCESS [process address] -r,命令运行结果如下所示:
在前面的WinDBG代码片段中,突出显示的四个标志都与DEP相关。不过,我们只关心其中的三个。如果启用了DEP功能,则设置ExecuteDisable标志。第二个标志ExecuteEnable是在DEP被禁用时设置的。我们感兴趣的最后一个标志是Permanent标志。如果设置了该标志,则不允许在运行时更改执行选项。
启动DEP功能后,如果我们原封不动的引入实现令牌窃取功能的shellcode,系统会将其标记为不可执行,这将最终导致系统崩溃。请看下面的屏幕截图,它展示了未正确处理DEP的情况下,实现令牌窃取功能的shellcode的运行结果。
如您所见,实现令牌窃取的shellcode所在的内存区域被标记为不可执行。因此,如果我们允许继续执行,一旦我们跳转到实现令牌窃取的shellcode并尝试执行第一条指令(PUSHAD),我们就会触发访问违规错误。
根据我们收集到的信息,可以得出如下结论:我们必须实现一种绕过DEP保护机制的方法,才能让这个exploit发挥作用。当然,我们有许多方法都可以做到这一点;就这里来说,我们将使用VirtualAlloc()和RtlMoveMemory() API函数来实现该任务。
通过VirtualAlloc(),我们可以创建一个新的可执行内存区域来存放实现令牌窃取功能的shellcode。在通过VirtualAlloc()函数创建可执行内存区域之后,我们将使用RtlMoveMemory()函数将实现令牌窃取功能的shellcode复制到该内存区域中。
在exploit代码中添加了实现令牌窃取功能的shellcode、VirtualAlloc()和RtlMoveMemory()函数之后,最终的代码如下所示:
C语言版本:
Python语言版本:
现在,让我们在Windows 7 SP1(x86)机器上运行最终版本的exploit代码。我们可以在TriggerStackOverflow中调用memcpy后马上中断,并检查shellcode所在的内存区域,看看它是否被标记为可执行的。
C语言版本:
Python语言版本:
我们已经成功获得了一个具有NT Authority/System权限的shell!
总结一下漏洞的利用过程:
l 触发崩溃,覆盖EIP。
l 控制EIP和执行流程
l 将执行流程重定向到包含LPE payload的、由用户生成的可执行内存区域中。
在这篇文章中,我们为读者提供了非常详尽的信息,所以,本文特别适合初次接触到内核漏洞利用的读者。
在这个系列的未来文章中,我计划涵盖更多的漏洞类型、特权提升技术和更多的现代安全机制(SMEP、CFG等)。此外,我还计划将相关代码迁移到x64架构。
最后,向HackSys Team致敬,感谢他们让本文成为可能。
如果您有任何问题/评论,不要犹豫,请联系我们。
未完待续……
原文地址:https://jb05s.github.io/HEVD-Driver-Exploitation-Part-2-Stack-Overflow-Presented-in-Python-and-C/
本文作者:mssp299
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/149170.html