测试环境:Windows 7
测试工具:VMWare + Windbg + IDA
首先下载漏洞的利用程序,在虚拟机中测试一下,发现程序可以正常运行:
下面开始寻找漏洞的成因。
为了减少工作量,应该尽可能地确定漏洞产生的准确位置,在这里采用的方法是在poc的源代码的shellcode起始位置添加0xcc,对应的是"int 3"指令,这样shellcode一运行,就会立刻断下来,然后就可以进行分析了。
修改过程就不废话了,直接运行修改后的程序,当windbg断下来之后,查看调用堆栈,却发现调用堆栈被破坏了
此时可以通过对当前栈进行分析粗略估计出错位置。当然,还有一种比较好的方法,考虑到程序可以正常执行,故shellcode运行完毕后必定会返回调用位置,那么在shellcode返回位置下断,运行再次断下来之后查看堆栈可以得到
看到上面的信息,再结合poc源码中的漏洞触发代码,就能确定问题就是出现在win32k!GreEnableEUDC函数里面了,那么就从它开始分析查找漏洞成因吧!
为了减少工作量,这里采用了一种比较笨的方法,多次尝试来准确判定出错原因及位置。过程如下:
在win32k!GreEnableEUDC处下断点,运行修改后的程序,然后单步跟踪,直至触发shellcode中"int 3"指令,多次尝试之后可以确定如下调用信息:
即在调用win32k!bAppendSysDirectory+0x209函数之后返回时跳入shellcode,同时在返回时查看堆栈可以发现返回地址被修改了,也就是说在该函数运行过程中栈空间被修改,即栈溢出。
结合网上的信息,多次尝试后可以确定整个漏洞的产生流程:
那么只要分析上面所列出函数的行为,就应该能确定漏洞的成因了。
接下来我们挨个来分析以上函数,实际分析过程中是Windbg动态调试和IDA静态分析同时进行的,在此为了书写方便,仅对Windbg代码进行分析。
对于win32k!GreEnableEUDC,涉及到一些不知道什么意思的变量,不过并不影响分析过程。
在此只简单提一下,调用参数均为1,毕竟漏洞产生的原因并不在此。
win32k!BuildAndLoadLinkedFontRoutine+0xeb函数依旧不是重点,在此只贴出相关代码:
关于win32k!MALLOCOBJ,个人感觉就像一个字符串的类,而在整个漏洞分析过程中,该对象也是扮演了一个字符串的角色,同时在内存起始位置记录了字符串信息。
下面这个函数就比较关键了,最终出错也是在这个函数当中,win32k!bAppendSysDirectory+0x209