漏洞描述
该漏洞发生在MSCOMCTL.OCX模块中,在一段内存拷贝时,由于检查条件错误造成基于栈的缓冲区溢出
分析环境
环境 | 版本 |
---|---|
操作系统 | W7 x64 |
调试器 | windbg |
反汇编器 | IDA Pro |
漏洞软件 | Office 2003 SP3 |
Office格式分析工具 | OffVis |
漏洞分析
寻找漏洞函数
首先用windbg附加WINWORD.EXE,接着打开漏洞样本,输入g命令运行
此时触发异常崩溃,触发异常的模块为C:\Windows\SysWOW64\MSCOMCTL.OCX,奔溃的地址是0x41414141
接下来查看 一下函数的堆栈,发现堆栈地址已经被破坏了
接着查看一下前面的堆栈,接着又看到了41414141这个地址
接着在IDA中查看MSCOMCTL.OCX,发现275c8a0a是漏洞模块的返回地址
验证漏洞函数
接下来我们来验证一下sub_275C876D这个函数是不是漏洞函数,重新用windbg附加WINWORD.EXE。用sxe ld命令给MSCOMCTL.OCX下模块断点
断下来之后在漏洞函数地址下bp断点
断下来之后,需要分析堆栈中的内容
这里发现了MSCOMCTL模块内的一个地址275e701a,用IDA查看下是不是外层函数的返回地址
接着我们进到sub_275C89C7这个函数
发现这个函数就是我们之前找到的漏洞函数,那么说明这个地址就是外层函数的返回地址
F10步过这个函数,再查看esp,发现这个返回地址已经被修改为41414141,这也就验证了这个函数就是触发漏洞的函数
缩小漏洞范围
用IDA F5查看这个函数内部,通过猜测加验证可以得出,触发漏洞的函数就是这个qmemcpy这个函数
重新用windbg附加WINWORD.EXE,继续在刚才验证过的漏洞函数下断点。
断下之后,查看esi和edi的内容
275e701a是我们刚才验证过的函数的返回地址,这里在进行内存拷贝的时候被41414141覆盖。这样,我们就确定了溢出点
探究漏洞本质
我们在IDA中在往外回溯一层,找到调用这个漏洞函数的地方,触发这个漏洞的根本原因就在这一句
if ( v5 == 1784835907 && dwBytes >= 8 )
当dwBytes >= 8时,条件成立,走下面的漏洞函数。这一句本来是用来控制memcpy函数拷贝的变量的大小的。结果缺因为程序员的代码逻辑错误,将原本是<=8写成了>=8。如果说这个地方是<=8的话,那么内存拷贝的字节数也就不存在溢出的可能了
总结:
CVE2012-0158之所以经典不是因为它是一个栈溢出,而是一个很典型的由于程序员代码逻辑的失误导致的栈溢出漏洞。
漏洞修复
直接用IDA查看修复后的模块
我们发现这里判断了拷贝的大小是否等于8,如果不等于8,则函数直接返回。