CVE-2010-3333
---恢复内容开始---
漏洞描述
CVE-2010-3333漏洞是Microsoft Office RTF分析器堆栈溢出漏洞,对应的Microsoft安全公告是MS10-087。远程攻击者可以借助特制的RTF数据执行任意代码,该漏洞又名"RTF栈缓冲区溢出漏洞"。
漏洞分析
通过exp文件来定位漏洞位置在进一步分析漏洞原因。先直接运行漏洞文档用监控工具观察触发漏洞后的行为。
可以看出漏洞触发后WINWORD.EXE进程中的shellcode释放了文件到%temp%目录命名为iexplore.exe并运行之。很容易想到可以断创建文件或者创建进程的函数,由于CreateFile调用较多(使用条件断点也可以),断创建进程的函数能更快的定位shellcode位置,常用的创建进程的函数ShellExecute,WinExec,CreateProcess,而shellcode中创建进程多使用CreateProcess,WinExec,不放心都可以打上断点。运行WINWORD.EXE,用OD附加下断打开exp文件,可以看到程序断在了WinExec。也可以看到00123FAF就是shellcode段,同时也是栈空间。
返回到shellcode段一直向上找,可以找到这段shellcode的开始位置
上面的代码可以看出这是这段shellcode的开始位置,再用十六进制编辑器打开exp文件,搜索EB105A4A这个特征码,把开始位置的地方的十六进制当特征码是因为后面的代码可能为解密出来的代码,在exp文件中只有加密后的代码。这段shellcode也的确如此,从上面的代码中也可以看出解密过程,只是简单的与0xEE异或。
可以看到上面就是shellcode,在shellcode的前面可以看到一个特殊的值77C60AFC,跳转到这个地址查看代码,可以看到这就是一个jmp esp的跳转方式。
上面找到了77C60AFC,我们知道exp文件在执行中先触发漏洞,然后在某一时刻将00123DD4所在的内存位置的值修改为77C60AFC,然后执行并跳转到shellcode,进而执行shellcode。因此,要想找到该存在漏洞的函数,就需要先找到何时对内存位置00123DD4的值进行的修改,修改前的值是多少,之后就能确定存在漏洞的函数。
因为00123DD4这个地址在栈上,所有修改该位置的地方会比较多,如果直接下内存写入断点将会断下很多次,所以使用windbg调试直接下条件写入断点ba w1 00123dd4 "j(poi(00123dd4)==0x77c60afc)'';'gc'",该断点只有在00123dd4地址写入0x77c60afc才会断下,因为00123dd4为系统分配的栈地址,所有重新加载的时候栈地址可能会变,最好用虚拟机做好快照。
程序断在了30ED442C的位置,可以看出是该位置将shellcode拷贝到了栈上。重新运行,在30ED442C下断查看栈回溯,查看是哪个函数调用到该位置
可以看出拷贝函数是在30F0B5C2中调用的,在对30F0B5C2和30ED442C下断并单步步过,在30F0B5F8的位置调用30ED4406函数进行数据拷贝。用IDA打开MSO.DLL查看30ED4406函数的汇编代码
可以看到保存数据的地址为函数的第二个参数,在看上一个函数可以看出传入的第二个参数为局部变量地址在栈上,而该函数在开始的时候只申请了0x14字节的栈空间,传入30ED4406的时候只传递了一个最大0x10大小的缓冲区,所以当数据长度足够大时将造成栈溢出。
从代码上可以看出复制数据的时候理论上的最大值应该为FFFF,但是在进行复制之前,有一个移位运算(shr ecx,2),因此ECX的最大值为3FFF,因此能够达到的最大复制为4*3FFF=FFFC字节。在调试的时候可以看出实际复制的时候长度只需要0x500就够了。
在回去看exp的十六进制,可以看到0x0500也是样本中的数据,它位于pFragements属性值的后面,用2字节的长度标识复制的数据大小。所以漏洞的原因为word中的RTF解析器在解析pFragements属性值时,没有正确的计算属性值所占用的空间大小导致栈溢出。