盒子
盒子
文章目录
  1. 前言:
  2. 正文:
  3. 修复:

CVE-2012-0158

前言:

整完这个cve就去整堆方面的cve去了,堆整完整fuzz去。。

正文:

运行之后崩溃在此处:

30E0B0E0-A85D-4293-8659-1492B5385A28

栈回溯一下发现栈被破坏了:
EE7217DB-1BB3-4947-8952-8D30B3D8CD93

没办法知道回调函数是什么了,换个思路,回看一下栈中的内容:

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,在此处下一个内存访问断点,断在:

5C3F6772-EC76-49C0-8794-750F94BADCFB

可以确定漏洞点在此处。查看之后发现该函数是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就报错即可。

支持一下
扫一扫,支持v1nke
  • 微信扫一扫
  • 支付宝扫一扫