WindowKernelExploit00

最近因为工作原因看了Windows Subsystem for Linux相关的内容(之后也整理到博客上吧),顺手就看到一个EXP,讲的是可以从 WSL 中实现 Windows 层面的提权。当时就想好好的研究了一下Window内核Exploit,于是趁热打铁搞了个HACKSYS EXTREME VULNERABLE DRIVER来玩


Window Kernel Exploit 00

HEVD(HACKSYS EXTREME VULNERABLE DRIVER)

HEVD这个东西是2017年就在blackhat上就提出来的,一个用来帮助大家学习Windows Kernel Exploit的项目,在这个项目中会提到很多Windows 内核漏洞利用的技巧,以此来辅助对Windows Kernel Exploit的基础学习。

安装踩坑

这个玩意儿其实本身还是蛮好弄得,下下来之后的文件目录如下:

其中根据README,首先安装Windows Driver Kit(并非SDK),然后从Builder中找到对应的Build_HEVD_Secure_*Build_HEVD_Vulnerable_*,简单修改之后,就能对驱动进行编译。然后还有一个叫做Build_HEVD_Exploit的文件,可以编译一个用于 exploit 的 exe。然而实际操作的时候却没那么简单,因为现在的WDK目录结构和当初的版本有点不一样,所以导致给出的bat脚本需要做出一定的调整,才能整个完成编译

Build HEVD Exploit

这个比较简单,只有以下几个地方需要修改:

1
2
3
4
5
6
7
8
REM store the local symbol server path
set localSymbolServerPath=C:\Xtra\Symbols\Custom\

set VC_PATH="%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat"
echo.
echo **************************************************
@call %VC_PATH% x86
echo **************************************************

这个localSymbolServerPath README 中也提到了,就放到一个自定义的目录就好了,重点是后面这个 VC_PATH,这个其实可以根据不同的visual studio版本自定义位置,因为这里使用的是VS100COMNTOOLS这个环境变量,相当于是使用的VS2012 进行编译的,如果是VS 2017的话,应该是叫做VS140COMNTOOLS,然而目录其实也不对了,所以这里建议直接改成Visual Studio的真是安装目录下的vcvarsall.bat的路径。我这边是改成了

1
set VC_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"

这里设置这个变量,之后会调用@call %VC_PATH% x86,设置编译环境为x86的文件

之后还有一出需要更改的地方

1
2
3
cd "C:\Program Files\Debugging Tools for Windows (x86)"
echo.
symstore.exe add /r /f %currentDir%\..\compile\exploit\ /s %localSymbolServerPath% /t "ExploitSymbol" /v "1.0"

这个调用我这边总是失败,所以最后我直接强行指定了symstore.exe的真实路径:

1
"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\symstore.exe" add /r /f %currentDir%\..\compile\exploit\ /s %localSymbolServerPath% /t "ExploitSymbol" /v "1.0"

Build HEVD Secure/Vulnerable

从字面上其实可以理解,其实这两个驱动版本分别是带有漏洞的驱动以及修复后的驱动。其实两个脚本的区别就是是否设置SECURE这个编译变量。在源码中,设置了SECURE全局变量的代码将会使用安全措施,修补当前漏洞,具体来说就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        DbgPrint("[+] UserDoubleFetch: 0x%p\n", UserDoubleFetch);
DbgPrint("[+] KernelBuffer: 0x%p\n", &KernelBuffer);
DbgPrint("[+] KernelBuffer Size: 0x%X\n", sizeof(KernelBuffer));

#ifdef SECURE
UserBuffer = UserDoubleFetch->Buffer;
UserBufferSize = UserDoubleFetch->Size;

DbgPrint("[+] UserDoubleFetch->Buffer: 0x%p\n", UserBuffer);
DbgPrint("[+] UserDoubleFetch->Size: 0x%X\n", UserBufferSize);

if (UserBufferSize > sizeof(KernelBuffer)) {
DbgPrint("[-] Invalid Buffer Size: 0x%X\n", UserBufferSize);

Status = STATUS_INVALID_PARAMETER;
return Status;
}

// Secure Note: This is secure because the developer is fetching
// 'UserDoubleFetch->Buffer' and 'UserDoubleFetch->Size' from user
// mode just once and storing it in a temporary variable. Later, this
// stored values are passed to RtlCopyMemory()/memcpy(). Hence, there
// will be no race condition
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, UserBufferSize);
#else

将这些有漏洞的程序以IOCTLHandle的形式注册为Driver Routine,于是就能够通过IOCTL选择此时需要触发的漏洞程序。
然而这个给出的编译脚本使用的是早期WDK,大约是 WDK7 前后的版本,从之后的版本之中就不再使用这个脚本来设置编译选项,也不会使用build来进行编译(使用的是MSBuild)。如果依然想用命令行进行编译的话,可以参考
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/100cee1b-30b6-46ec-b3aa-729142f60285/how-to-build-a-driver-using-the-command-line-msbuild?forum=wdk
并且还需要修改原先的.sln文件,不然的话编译过程还是会出问题。。。
为了图方便,这里就使用了Visual Studio自带的编译器进行编译。安装了WDK之后,新建项目的时候可以直接从VS中找到Driver的Solution

由于是Driver(并且是.sys文件),这里就使用Kernel Mode Driver,Empty这个选项,之后将所有的源代码都拷贝进去。然后在项目->属性->C/C++->常规处,把警告等级设置的低一些(不然会警告未生成obj文件),然后在项目->属性->Driver Settings->General根据自己的需要设置需要编译的平台。之后再去编译就能完成对驱动的编译了。

测试结果

如果都编译完成之后,将README中用于(load driver)[https://www.osronline.com/article.cfm?article=157]的工具下载一下(建议再搞一个dbgview用来查看内核的log输出),基本上就大功告成。然后将这些东西都扔到虚拟机里面,首先使用工具,将驱动安装上去,之后可以用sc query HackSysExtremeVulnerableDriver对驱动进行检测。如果打印当前驱动的状态是Running,那就说明安装成功,此时我们可以尝试运行之前编译好的HackSysEVDExploit.exe,然后随便选取一个攻击手法进行攻击(也就是它后面跟着的那些参数),然后用-c cmd弹出一个计算器,就能够知道是否攻击成功了。