0%

CVE-2012-0158 Microsoft Office MSCOMCTL.ocx栈溢出漏洞

漏洞描述:Windows通用控件MSCOMCTL.OCX存在栈溢出漏洞。

打开word,用windbg附加,运行poc文件后,程序中断。由于不知道程序出现问题的模块,查看esp附近的返回地址。
这里先复习一下栈中函数调用的流程

参数入栈,返回地址入栈,前ebp入栈,跳转到函数起始位置,申请扩大栈空间,执行函数,执行完后返回返回地址。
这就是说之前调用过的函数的返回地址可以通过查看esp之前的栈空间看到。

0:000> dps esp-0x50
00127adc 08d007dc
00127ae0 0cc306b0
00127ae4 00008282
00127ae8 00127b1c
00127aec 275c8a0a MSCOMCTL!DllGetClassObject+0x41cc6
00127af0 00127b14
00127af4 08d00e88
00127af8 00008282
00127afc 00000000
00127b00 08d007dc
00127b04 0cc306b0
00127b08 6a626f43
00127b0c 00000064
00127b10 00008282
00127b14 00000000
00127b18 00000000
00127b1c 00000000
00127b20 41414141
00127b24 00000000
00127b28 00000000
00127b2c 00000000
00127b30 00000000

因此定位函数漏洞发生在MSCOMCTL模块,而且可以通过275c8a0a定位到漏洞函数的上级函数275C89C7。在MSCOMCTL.ocx模块中的275C89C7中下断点,可以看到漏洞触发的流程(sxe ld:MSCOMCTL.ocx,bp 275C89C7)。
动态调试程序,在第二次call MSCOMCTL!DllGetClassObject+0x41a29 (275c876d)溢出,如图所示:5-1

观察275c876d函数,使用IDA反汇编发现该函数中存在敏感函数qmemcpy(void dest, const void src, size_t n);且size_t参数由上级函数的第三个参数传入为8282。如图5-2

观察该函数以及上级函数,并没有对该参数的大小进行检查,导致了这次溢出。
分析文档格式,发现shellcode位于\object\objocx{*\objdata
根据官方rtf格式描述如图
5-5

并且通过https://github.com/decalage2/oletools oletools来分析OLE数据.
rtfobj.py poc.doc -s all来从poc文档中提取出objole数据保存为poc.doc_object_000000A5.bin
olebrowse.py poc.doc_object_000000A5.bin分析可以看出来
clsid
5-7
data
5-8
此时mscomctl处理data中的数据时发生溢出,而进入漏洞触发点的流程如下图5-10

配合动态调试得知函数开始时分配了0X14大小的空间,
第一次调用sub_275C876D,使用了0xC的栈空间大小,将ebp-0x14位置赋值为0x6a626f43(Cobjd),返回值为0
之后比较[ebp-0x14]是否为6A626F43h(确定是Cobjd结构)后,比较 [ebp-0xc]是否大于8(漏洞产生原因,大于应该改成小于)
这里[ebp-0xc]为0x8282大于8,因此第二次调用sub_275C876D而[ebp-0xc]为次函数的第三个参数即复制长度,远远超过8导致溢出。