HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

本文讲的是 HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

到目前为止,我们还没有完全实现漏洞的攻击。让我们回顾一下第2篇里为DoS PoC创建的漏洞利用步骤,现在我们可以修改其中一些步骤,来实现SYSTEM shell。

第一步,生成cmd.exe进程

虽然这一步非常简单,但是要在Python中实现,还是需要一些额外的代码,与C语言代码相比,我们将使用Kernel32.dll中的CreateProcess API来启动shell。查看函数原型,该函数需要为调用设置两个结构体,其中一个将使用我们启动的cmd.exe进程的PID返回给我们。稍后我们需要使用shellcode来设置我们的结构体。

第一个是STARTUPINFO结构体(STARTUPINFO是用于指定新进程的主窗口特性的一个结构)。使用Python ctypes可以在我们的脚本中重新创建STARTUPINFO结构体,如下所示:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

我们可以在脚本中引用这个结构体,如下所示:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

我们需要的是一个PROCESS_INFORMATION结构,因为这个结构更易于管理,在ctypes中看起来是这样:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

这里包含了dwProcessId dword中创建的进程PID。通过创建这两个结构,我们可以参考CreateProcess函数原型并将我们的API调用放在一起:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

第二步和第三步和第2篇里的过程一模一样,大家可以爬楼。

第四步,使用shellcode分配缓冲区

首先将shellcode翻译成Python。这也包括将cmd.exe进程的PID动态插入到shellcode中,这样我们就创建了一个可以接收我们需要的PID并创建shellcode的函数:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

利用VirtualAlloc函数复制我们的shellcode区域,当然前提是确保指定的分配缓冲区是可执行的。假设一切顺利,我们就可以将shellcode复制到缓冲区(ctypes提供一个memmove()函数),然后返回shellcode所在的地址:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

第五步,创建shellcode的缓冲区

这一步又与第2章提到的DoS PoC非常相似。不过,这一次,我们的函数还需要收到shellcode所在的分配地址,以便我们可以将它添加到我们的缓冲区。我们的DoS PoC缓冲区由2048“A”组成,其后是8“B”和8“C”。 “C”是在rip寄存器中结束的,所以我们要用我们的shellcode地址来替换它:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

第六步,触发漏洞

首先生成cmd.exe并获取它的PID,然后分配shellcode并将该地址插入到我们创建的缓冲区。

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

如果一切顺利的话,会出现以下的情景:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

至此,漏洞就可以完全实现了。不过,我们在实际的测试中发现,这些漏洞攻击只是在Windows 8以前的系统版本中运行的很好,由于Windows 8及更高版本上已经配置了一些新的缓解措施,所以这些漏洞利用就会被禁止。

主管模式执行保护(SMEP)有点像ring 0模式下的DEP,是内核的一种缓解措施,我们可以将它简单的理解成禁止在内核态下执行用户空间的代码。换句话说,当以内核模式运行时,处理器将不会运行映射到用户模式存储器的指令。

在Windows 7版本中,我们是将shellcode复制到内存中。一旦我们劫持了内核中的执行流程,我们就会将其指向带有shellcode的用户内存缓冲区,但如果我们在启用了SMEP的系统上也这么做,那么一旦处理器试图执行用户内存缓冲区的任何指令,则运行就会中断。

正如开始的时候我说SMEP有点像DEP,绕过DEP比较常见的方法就是ROP链,因此绕过SMEP的常见方法也是比较简单的方法也是ROP链,在DEP中构造ROP链需要dll的基址,其实在SMEP中构造ROP链需要动态链接库内核的地址,而获取内核地址的一种非常好用的方法就是NtQuerySystemInformation。

那么我们如何绕过SMEP呢?最简单的途径就是简化CR4寄存器,以便让Windows认为是处理器不支持SMEP。这与我们的Windows 7 HEVD堆栈溢出漏洞大致相同,但在我们触发溢出之前,我们必须首先执行ROP链以禁用SMEP。为了构建我们的ROP链,我们必须找到内核的基址,总共分8步:

1.Spawn cmd.exe进程
2.使用shellcode分配缓冲区
3.获取内核基地址
4.构建ROP链
5.获取容易受到攻击的设备句柄
6.获取正确的IOCTL的堆栈溢出功能
7.创建一个将执行重定向到ROP链及shellcode的缓冲区
8.触发漏洞

以上只有第3步和第4步是新步骤,所以我们就直接来叙述这两个步骤,其余的步骤,请参看前文。

第三步,获取内核基址

就像绕过DEP比较常见的方法就是ROP链一样,我们可以使用ASLR,使用ROP来破坏内核中的SMEP可能会受到KASLR的阻碍。当然有各种方法来击败KASLR,但这不在本文的讨论范围之内。

简单来说,利用psapi.dll的EnumDeviceDrivers功能就可以实现这一目标,EnumDeviceDrivers可以检索系统中每个设备驱动程序的加载地址,其中包括返回结果中的实际内核:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

第四步,建立ROP链

使用这一步的前提是,假设大家已经很熟悉ROP技术了。

现在我们已经得到了内核基地址,接下来我们将继续构建绕过SMEP的ROP链。这不是很难,因为这是一个非常小的ROP链,只需要把ntoskrnl.exe解析为几个字节数组。

我们的目的就是将控制值弹出到CR4寄存器中。在搜索到可用的ROP后,我们发现没有很多与CR4进行交互的指令,这时 ntoskrnl.exe中的KiFlushCurrentTbWorker函数实际上可以被利用起来:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

接下来,我们只需要在内核的地址空间中找到POP RCX就可以了。最后,我们可以构建一个函数,该函数采用内核的基地址和shellcode的用户地址,将CR4值放在该函数中,最后在shellcode缓冲区得到以下代码:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)

至此,在Windows 8及更高版本上我们也实现了最终的漏洞利用:

HEVD 内核攻击:漏洞攻击的完全实现及SMEP绕过(四)




原文发布时间为:2017年3月30日
本文作者:xiaohui 
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值