如何利用Windows内核漏洞实现提权(上篇) - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

如何利用Windows内核漏洞实现提权(上篇)

fanyeee 系统安全 2017-12-04 10:05:33
323420
收藏

导语:

在这个系列文章中,我们将为读者详细介绍如何利用Google Project Zero最近公布的一个Windows内核漏洞来实现特权提升。这里之所以使用这个漏洞,不仅在于它“好使”,而且易于理解,最重要的是32位的Windows 10 Creator版本仍然存在该漏洞。

所以....让我们开始吧。

漏洞概述

通过阅读该漏洞的相关报告,发现它涉及Windows 10的32位Creators Update版本。之所以会出现这个漏洞,是由于被添加到NtQuerySystemInformation中的一个新的信息类(名为“WARBIRD”)在32位版本的Windows 10上没有得到正确处理所导致的。

当漏洞被触发时,内核指令指针被设置为NULL。通常来说,在现代操作系统中,为了避免这种类型的漏洞被攻击者所利用,会限制使用内存地址0h。然而,谷歌的研究人员发现,在Windows上启用了16位支持的情况下,特别是通过NTVDM使用NULL地址来支持16位应用程序的执行的情况下,这类漏洞仍然是可以加以利用的。

在编写我们的漏洞利用代码之前,我们需要复现这个漏洞。所以,下面先来介绍如何搭建实验环境。

搭建实验环境

为了搭建实验环境,我们需要用到一些VM:

Windows 10 Creators Update x86——这是含有内核漏洞的主机
Windows与WinDBG——这是我们的内核调试主机

在含有内核漏洞的主机上,我们需要使用以下命令来启用16位支持:

FONDUE.exe /enable-feature:NTVDM

我们还需要启用内核调试,为此可以使用下列命令:

bcdedit /debug on
bcdedit /dbgsettings NET HOSTIP:<WINDBG_HOST> PORT:50000

在执行上述命令时,会为您提供一个密钥,当WinDBG在启动过程中连接主机时会用到该密钥。在我们的内核调试主机中,启动WinDBG,并通过“File -> Kernel Debug”来设置内核调试会话,这时会用到上面提到的密钥:

windbg_kernel-1

重新启动含有内核漏洞的主机,这时会在WinDBG中打开内核调试器会话,这样有助于在漏洞利用过程中更加轻松地了解内核状态:

windbg_established

完成上述操作之后,我们再来介绍在利用这个安全漏洞过程中涉及到的一个重要概念:进程注入。

进程注入

在该漏洞的报告中,研究人员指出:

如果我们生成一个16位的应用程序(例如debug.exe),并将我们的漏洞利用代码注入ntvdm的话,在通过nt!WbAddLookupEntryEx对地址0进行写入操作时,系统就不会立即崩溃了。

它对于这里的漏洞利用代码来说是非常重要的,因此,我们需要了解进程注入是如何工作的,以及如何使用这种技术让NTVDM在其地址空间内执行我们的代码,从而允许我们利用NULL映射页面。

Windows上的进程注入通常涉及许多Win32 API,具体为:

OpenProcess
VirtualAllocEx
WriteProcessMemory
CreateRemoteThread

下面,我们对这些调用进行详尽的说明:

OpenProcess:这个调用可以通过PID来获取Windows进程的句柄,我们可以通过这个句柄对相应的进程采取进一步的操作。

VirtualAllocEx:这个调用用于在目标进程中分配内存,为我们预留空间,以便存放我们的自定义代码,或者将参数传递给远程线程。

WriteProcessMemory:提供一个地址和一个进程句柄,我们可以通过这个调用将数据复制到远程进程地址空间。

CreateRemoteThread:我们可以通过它在远程进程中创建一个新的线程,并指定执行的起始位置。

使用这些API调用,我们可以将shellcode注入到NTVDM进程中,但是为了简单起见,我们这里将把一个DLL加载到NTVDM中。这样做的好处是,我们可以直接使用诸如Visual Studio之类的工具来创建一个DLL,在其中保存我们的漏洞利用代码,这样的话,在运行时就不必担心诸如API解析之类的问题了。

为了加载我们的DLL,将用到另一个Win32 API调用LoadLibrary,它的作用是获取DLL的路径,并将其动态加载到进程地址空间中。因此,我们需要构造一个注入工具,以便:

使用OpenProcess获取NTVDM进程的句柄。

使用VirtualAllocEx分配足够的空间来复制我们的LoadLibrary参数值,这个值就是我们的漏洞利用DLL的路径。

使用WriteProcessMemory将我们的漏洞利用DLL路径写入远程分配的内存中。

最后,使用CreateRemoteThread生成一个线程并在远程进程中执行LoadLibrary调用,将我们复制的DLL路径地址作为参数进行传递。

构建完成后,我们的注入代码如下所示:

如果我们用一个非常简单的DLL来完成上述任务的话,NTVDM就能够顺利调用我们的代码:

dll_injection_test

构建漏洞利用代码

现在,我们已经可以将任意DLL加载到NTVDM进程中了,接下来,我们开始考虑如何构建漏洞利用代码了。下面是触发该漏洞的示例代码:

BYTE Buffer[8];
DWORD BytesReturned;
RtlZeroMemory(Buffer, sizeof(Buffer));
NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)185, Buffer, sizeof(Buffer), &BytesReturned);
RtlCopyMemory(NULL, "xcc", 1);
RtlZeroMemory(Buffer, sizeof(Buffer));
NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)185, Buffer, sizeof(Buffer), &BytesReturned);

如果将这段代码添加到一个DLL中,并将其注入到NTVDM进程中,我们会发现WinDBG将触发下面的断点:

interrupt_hit

我们可以看到,EIP是00000000h,我们的中断已经被触发了....真棒,我们现在已经控制了内核代码的执行:)

小结

在这个系列文章中,我们将为读者详细介绍如何利用Google Project Zero最近公布的一个Windows内核漏洞来实现特权提升。首先,我们就本文中利用的内核漏洞进行了介绍,然后为读者介绍了如何搭建实验环境,然后对进程注入的概念进行了说明,最后详细介绍了如何构建弄懂利用代码。

接下来,我们将开始着手编写shellcode——也就是我们的漏洞利用代码执行的shellcode。

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务