CVE-2012-0158
2018.11.13
V1NKe
 热度
℃
前言:
整完这个cve就去整堆方面的cve去了,堆整完整fuzz去。。
正文:
运行之后崩溃在此处:
栈回溯一下发现栈被破坏了:
没办法知道回调函数是什么了,换个思路,回看一下栈中的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 0:000> dds esp-70 001216cc 09ff0810 001216d0 00008282 001216d4 00121708 001216d8 275c8a0a MSCOMCTL!DllGetClassObject+0x41cc6 001216dc 00121700 001216e0 08cfa9e8 001216e4 00008282 001216e8 00000000 001216ec 08cc1acc 001216f0 09ff0810 001216f4 6a626f43 001216f8 00000064 001216fc 00008282 00121700 00000000 00121704 00000000 00121708 00000000 0012170c 41414141 00121710 00000000
|
可以看到最近的返回地址在0x275c8a0a
处。
反汇编一下:
1 2 3 4 5 6 7 8 9 10
| 0:000> ub MSCOMCTL!DllGetClassObject+0x41cc6 MSCOMCTL!DllGetClassObject+0x41ca9: 275c89ed 0f8592a60000 jne MSCOMCTL!DllGetClassObject+0x4c341 (275d3085) 275c89f3 837df408 cmp dword ptr [ebp-0Ch],8 275c89f7 0f8288a60000 jb MSCOMCTL!DllGetClassObject+0x4c341 (275d3085) 275c89fd ff75f4 push dword ptr [ebp-0Ch] 275c8a00 8d45f8 lea eax,[ebp-8] 275c8a03 53 push ebx 275c8a04 50 push eax 275c8a05 e863fdffff call MSCOMCTL!DllGetClassObject+0x41a29 (275c876d)
|
在0x275c89ed
处下个断点,但是这时候的MSCOMCTL.Dll
是动态加载的,没办法直接下断,所以硬件断点:
ba e 1 275c89ed
这时候的返回地址是0x12170c
,在此处下一个内存访问断点,断在:
可以确定漏洞点在此处。查看之后发现该函数是0x275c876d
。该函数中的参数有:
1
| 00121700 09ff0810 00008282
|
这三个参数,大致可以猜测是字符串复制函数。
看一下引发漏洞的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 275c89c7 55 push ebp 275c89c8 8bec mov ebp,esp 275c89ca 83ec14 sub esp,14h < -- 0x14堆栈大小 275c89cd 53 push ebx 275c89ce 8b5d0c mov ebx,dword ptr [ebp+0Ch] 275c89d1 56 push esi 275c89d2 57 push edi 275c89d3 6a0c push 0Ch 275c89d5 8d45ec lea eax,[ebp-14h] 275c89d8 53 push ebx 275c89d9 50 push eax 275c89da e88efdffff call MSCOMCTL!DllGetClassObject+0x41a29 (275c876d) 275c89df 83c40c add esp,0Ch < -- 使用了0xc大小 275c89e2 85c0 test eax,eax 275c89e4 7c6c jl MSCOMCTL!DllGetClassObject+0x41d0e (275c8a52) 275c89e6 817dec436f626a cmp dword ptr [ebp-14h],6A626F43h 275c89ed 0f8592a60000 jne MSCOMCTL!DllGetClassObject+0x4c341 (275d3085) 275c89f3 837df408 cmp dword ptr [ebp-0Ch],8 275c89f7 0f8288a60000 jb MSCOMCTL!DllGetClassObject+0x4c341 (275d3085) 275c89fd ff75f4 push dword ptr [ebp-0Ch] 275c8a00 8d45f8 lea eax,[ebp-8] 275c8a03 53 push ebx 275c8a04 50 push eax 275c8a05 e863fdffff call MSCOMCTL!DllGetClassObject+0x41a29 (275c876d)
|
栈中应该只剩余了8字节大小的栈空间,但是超长复制导致溢出。
后面观察poc的文件格式来分析解析哪个字段导致溢出。
1 2 3 4 5 6
| {\rtf1 {\fonttbl{\f0\fnil\fcharset0 Verdana;}} \viewkind4\uc1\pard\sb100\sa100\lang9\f0\fs22\par \pard\sa200\sl276\slmult1\lang9\fs22\par {\object\objocx {\*\objdata
|
导致漏洞的是\object
标签内容,其中的\objocx
代表在OLE容器中嵌入OCX控件。后面可以利用OffVis工具来分析文档的各个具体字段,具体就不细说了。
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
| int __stdcall sub_275C89C7(int a1, BSTR bstrString) { BSTR v2; // ebx@1 int result; // eax@1 int v4; // esi@4 int v5; // [sp+Ch] [bp-14h]@1 SIZE_T dwBytes; // [sp+14h] [bp-Ch]@3 int v7; // [sp+18h] [bp-8h]@4 int v8; // [sp+1Ch] [bp-4h]@8
v2 = bstrString; result = sub_275C876D((int)&v5, bstrString, 0xCu); if ( result >= 0 ) { if ( v5 == 'jboC' && dwBytes >= 8 ) < -- 漏洞点 { v4 = sub_275C876D((int)&v7, v2, dwBytes); if ( v4 >= 0 ) { if ( !v7 ) goto LABEL_8; bstrString = 0; v4 = sub_275C8A59((UINT)&bstrString, (int)v2); if ( v4 >= 0 ) { sub_27585BE7(bstrString); SysFreeString(bstrString); LABEL_8:
|
样本字段数据:
1 2 3 4 5
| struct collstreamhdr{ dword dwMagic = 0x6a626f43("Cobj"); dword dwVersion = 0x64; dword dwBytes = 0x8282; }
|
这里只要dwBytes>=8即可执行第二次调用复制函数,0x8282远大于0x8导致溢出。
修复:
控制dwBytes字段,判断是否为0x8,不为0x8就报错即可。