首页
社区
课程
招聘
[原创] cve-2012-0158漏洞分析
2016-11-10 10:45 4240

[原创] cve-2012-0158漏洞分析

2016-11-10 10:45
4240
参考《漏洞战争》分析下,记下自己的心得,主要还是汇编代码比较麻烦。

环境是xpsp3+word2003(11.8324.8324):
打开windbg、word软件,windbg附加word软件进程,word打开poc.doc文件,发现windbg已经断下,eip指向0x41414141,说明已经发生了溢出,eip被控制了。
0:009> g
(15c.510): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=024957b8 ecx=7c93005d edx=00140608 esi=0022ed4c edi=00000000
eip=41414141 esp=0012170c ebp=00000000 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
41414141 ??              ???

看一下栈回溯:
0:000> kvn
 # ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 00121708 00000000 00000000 00000000 00000000 0x41414141
0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
00121708 00000000 00000000 00000000 00000000 0x41414141

说明栈回溯已经被破坏掉了,看一下栈中的信息:
dps esp-0x50:
0:000> dps esp-0x50
001216bc  0022ed4c
001216c0  024957b8
001216c4  00008282
001216c8  001216fc
001216cc  275a273d MSCOMCTL!DllGetClassObject+0xb456
001216d0  001216f4
001216d4  001c8008
001216d8  00008282
001216dc  00000000
001216e0  0022ed4c
001216e4  024957b8
001216e8  6a626f43
001216ec  00000064
001216f0  00008282
001216f4  00000000
001216f8  00000000
001216fc  00000000
00121700  41414141
00121704  00000000
00121708  00000000
0012170c  00000000
00121710  00000000
00121714  00000000

根据相关资料,可以知道这个漏洞就是在组件mscomctl.ocx中的,所以275a273d MSCOMCTL!DllGetClassObject+0xb456保存的可能是返回地址,查看一下这个地址之前的汇编代码:
0:000> ub 275a273d
MSCOMCTL!DllGetClassObject+0xb439:
275a2720 0f8539030300    jne     MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)
275a2726 837df408        cmp     dword ptr [ebp-0Ch],8
275a272a 0f822f030300    jb      MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)
275a2730 ff75f4          push    dword ptr [ebp-0Ch]
275a2733 8d45f8          lea     eax,[ebp-8]
275a2736 53              push    ebx
275a2737 50              push    eax
275a2738 e863fdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)


可以看到漏洞很可能出现在0x275a2738地址call的函数里边。
反编译一下函数MSCOMCTL!DllGetClassObject+0xb1b9 :
0:000> uf MSCOMCTL!DllGetClassObject+0xb1b9
MSCOMCTL!DllGetClassObject+0xb1b9:
275a24a0 55              push    ebp
275a24a1 8bec            mov     ebp,esp
275a24a3 51              push    ecx
275a24a4 53              push    ebx
275a24a5 8b5d0c          mov     ebx,dword ptr [ebp+0Ch]
275a24a8 56              push    esi
275a24a9 33f6            xor     esi,esi
275a24ab 8b03            mov     eax,dword ptr [ebx]
275a24ad 57              push    edi
275a24ae 56              push    esi
275a24af 8d4dfc          lea     ecx,[ebp-4]
275a24b2 6a04            push    4
275a24b4 51              push    ecx
275a24b5 53              push    ebx
275a24b6 ff500c          call    dword ptr [eax+0Ch]
275a24b9 3bc6            cmp     eax,esi
275a24bb 7c78            jl      MSCOMCTL!DllGetClassObject+0xb24e (275a2535)

MSCOMCTL!DllGetClassObject+0xb1d6:
275a24bd 8b7d10          mov     edi,dword ptr [ebp+10h]
275a24c0 397dfc          cmp     dword ptr [ebp-4],edi
275a24c3 0f8533150300    jne     MSCOMCTL!DllGetClassObject+0x3c715 (275d39fc)

MSCOMCTL!DllGetClassObject+0xb1e2:
275a24c9 57              push    edi
275a24ca 56              push    esi
275a24cb ff3520e06227    push    dword ptr [MSCOMCTL!DllUnregisterServer+0x2dfe8 (2762e020)]
275a24d1 ff1568115827    call    dword ptr [MSCOMCTL+0x1168 (27581168)]
275a24d7 3bc6            cmp     eax,esi
275a24d9 89450c          mov     dword ptr [ebp+0Ch],eax
275a24dc 0f8424150300    je      MSCOMCTL!DllGetClassObject+0x3c71f (275d3a06)

MSCOMCTL!DllGetClassObject+0xb1fb:
275a24e2 8b0b            mov     ecx,dword ptr [ebx]
275a24e4 56              push    esi
275a24e5 57              push    edi
275a24e6 50              push    eax
275a24e7 53              push    ebx
275a24e8 ff510c          call    dword ptr [ecx+0Ch]
275a24eb 8bf0            mov     esi,eax
275a24ed 85f6            test    esi,esi
275a24ef 7c31            jl      MSCOMCTL!DllGetClassObject+0xb23b (275a2522)

MSCOMCTL!DllGetClassObject+0xb20a:
275a24f1 8b750c          mov     esi,dword ptr [ebp+0Ch]
275a24f4 8bcf            mov     ecx,edi
275a24f6 8b7d08          mov     edi,dword ptr [ebp+8]
275a24f9 8bc1            mov     eax,ecx
275a24fb c1e902          shr     ecx,2
275a24fe f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
275a2500 8bc8            mov     ecx,eax
275a2502 8b4510          mov     eax,dword ptr [ebp+10h]
275a2505 83e103          and     ecx,3
275a2508 6a00            push    0
275a250a 8d5003          lea     edx,[eax+3]
275a250d 83e2fc          and     edx,0FFFFFFFCh
275a2510 2bd0            sub     edx,eax
275a2512 f3a4            rep movs byte ptr es:[edi],byte ptr [esi]
275a2514 8b0b            mov     ecx,dword ptr [ebx]
275a2516 52              push    edx
275a2517 68e03f6327      push    offset MSCOMCTL!DllUnregisterServer+0x33fa8 (27633fe0)
275a251c 53              push    ebx
275a251d ff510c          call    dword ptr [ecx+0Ch]
275a2520 8bf0            mov     esi,eax

MSCOMCTL!DllGetClassObject+0xb23b:
275a2522 ff750c          push    dword ptr [ebp+0Ch]
275a2525 6a00            push    0
275a2527 ff3520e06227    push    dword ptr [MSCOMCTL!DllUnregisterServer+0x2dfe8 (2762e020)]
275a252d ff1574115827    call    dword ptr [MSCOMCTL+0x1174 (27581174)]
275a2533 8bc6            mov     eax,esi

MSCOMCTL!DllGetClassObject+0xb24e:
275a2535 5f              pop     edi
275a2536 5e              pop     esi
275a2537 5b              pop     ebx
275a2538 c9              leave
275a2539 c3              ret

MSCOMCTL!DllGetClassObject+0x3c715:
275d39fc b8ffff0080      mov     eax,8000FFFFh
275d3a01 e92febfcff      jmp     MSCOMCTL!DllGetClassObject+0xb24e (275a2535)

MSCOMCTL!DllGetClassObject+0x3c71f:
275d3a06 b80e000780      mov     eax,8007000Eh
275d3a0b e925ebfcff      jmp     MSCOMCTL!DllGetClassObject+0xb24e (275a2535)

我们将该函数MSCOMCTL!DllGetClassObject+0xb1b9命名为vul。
将调用vul的函数命名为vul_parent:
查看一下调用函数:
0:000> ub 275a273d l20
MSCOMCTL!DllGetClassObject+0xb407:
275a26ee 59              pop     ecx
275a26ef 7c02            jl      MSCOMCTL!DllGetClassObject+0xb40c (275a26f3)
275a26f1 33c0            xor     eax,eax
275a26f3 5f              pop     edi
275a26f4 5e              pop     esi
275a26f5 5b              pop     ebx
275a26f6 c9              leave
275a26f7 c20800          ret     8
275a26fa 55              push    ebp
275a26fb 8bec            mov     ebp,esp
275a26fd 83ec14          sub     esp,14h
275a2700 53              push    ebx
275a2701 8b5d0c          mov     ebx,dword ptr [ebp+0Ch]
275a2704 56              push    esi
275a2705 57              push    edi
275a2706 6a0c            push    0Ch
275a2708 8d45ec          lea     eax,[ebp-14h]
275a270b 53              push    ebx
275a270c 50              push    eax
275a270d e88efdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)
275a2712 83c40c          add     esp,0Ch
275a2715 85c0            test    eax,eax
275a2717 7c6c            jl      MSCOMCTL!DllGetClassObject+0xb49e (275a2785)
275a2719 817dec436f626a  cmp     dword ptr [ebp-14h],6A626F43h
275a2720 0f8539030300    jne     MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)
275a2726 837df408        cmp     dword ptr [ebp-0Ch],8
275a272a 0f822f030300    jb      MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)
275a2730 ff75f4          push    dword ptr [ebp-0Ch]
275a2733 8d45f8          lea     eax,[ebp-8]
275a2736 53              push    ebx
275a2737 50              push    eax
275a2738 e863fdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)

函数0x275a26fa就是函数vul_parent,查看一下完整汇编代码。

0:000> uf 275a26fa
MSCOMCTL!DllGetClassObject+0xb413:
275a26fa 55              push    ebp
275a26fb 8bec            mov     ebp,esp
275a26fd 83ec14          sub     esp,14h
275a2700 53              push    ebx
275a2701 8b5d0c          mov     ebx,dword ptr [ebp+0Ch]
275a2704 56              push    esi
275a2705 57              push    edi
275a2706 6a0c            push    0Ch
275a2708 8d45ec          lea     eax,[ebp-14h]
275a270b 53              push    ebx
275a270c 50              push    eax
275a270d e88efdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)
275a2712 83c40c          add     esp,0Ch
275a2715 85c0            test    eax,eax
275a2717 7c6c            jl      MSCOMCTL!DllGetClassObject+0xb49e (275a2785)

MSCOMCTL!DllGetClassObject+0xb432:
275a2719 817dec436f626a  cmp     dword ptr [ebp-14h],6A626F43h
275a2720 0f8539030300    jne     MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)

MSCOMCTL!DllGetClassObject+0xb43f:
275a2726 837df408        cmp     dword ptr [ebp-0Ch],8
275a272a 0f822f030300    jb      MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)

MSCOMCTL!DllGetClassObject+0xb449:
275a2730 ff75f4          push    dword ptr [ebp-0Ch]
275a2733 8d45f8          lea     eax,[ebp-8]
275a2736 53              push    ebx
275a2737 50              push    eax
275a2738 e863fdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)
275a273d 8bf0            mov     esi,eax
275a273f 83c40c          add     esp,0Ch
275a2742 85f6            test    esi,esi
275a2744 7c3d            jl      MSCOMCTL!DllGetClassObject+0xb49c (275a2783)

MSCOMCTL!DllGetClassObject+0xb45f:
275a2746 837df800        cmp     dword ptr [ebp-8],0
275a274a 8b7d08          mov     edi,dword ptr [ebp+8]
275a274d 742a            je      MSCOMCTL!DllGetClassObject+0xb492 (275a2779)

MSCOMCTL!DllGetClassObject+0xb468:
275a274f 83650c00        and     dword ptr [ebp+0Ch],0
275a2753 8d450c          lea     eax,[ebp+0Ch]
275a2756 53              push    ebx
275a2757 50              push    eax
275a2758 e82f000000      call    MSCOMCTL!DllGetClassObject+0xb4a5 (275a278c)
275a275d 8bf0            mov     esi,eax
275a275f 59              pop     ecx
275a2760 85f6            test    esi,esi
275a2762 59              pop     ecx
275a2763 7c1e            jl      MSCOMCTL!DllGetClassObject+0xb49c (275a2783)

MSCOMCTL!DllGetClassObject+0xb47e:
275a2765 ff750c          push    dword ptr [ebp+0Ch]
275a2768 8d4fdc          lea     ecx,[edi-24h]
275a276b e81a52feff      call    MSCOMCTL+0x798a (2758798a)
275a2770 ff750c          push    dword ptr [ebp+0Ch]
275a2773 ff1540155827    call    dword ptr [MSCOMCTL+0x1540 (27581540)]

MSCOMCTL!DllGetClassObject+0xb492:
275a2779 837dfc00        cmp     dword ptr [ebp-4],0
275a277d 0f85e6020300    jne     MSCOMCTL!DllGetClassObject+0x3b782 (275d2a69)

MSCOMCTL!DllGetClassObject+0xb49c:
275a2783 8bc6            mov     eax,esi

MSCOMCTL!DllGetClassObject+0xb49e:
275a2785 5f              pop     edi
275a2786 5e              pop     esi
275a2787 5b              pop     ebx
275a2788 c9              leave
275a2789 c20800          ret     8

MSCOMCTL!DllGetClassObject+0x3b778:
275d2a5f b8ffff0080      mov     eax,8000FFFFh
275d2a64 e91cfdfcff      jmp     MSCOMCTL!DllGetClassObject+0xb49e (275a2785)

MSCOMCTL!DllGetClassObject+0x3b782:
275d2a69 83c714          add     edi,14h
275d2a6c 53              push    ebx
275d2a6d 57              push    edi
275d2a6e e8ebfdfcff      call    MSCOMCTL!DllGetClassObject+0xb577 (275a285e)
275d2a73 59              pop     ecx
275d2a74 8bf0            mov     esi,eax
275d2a76 59              pop     ecx
275d2a77 e907fdfcff      jmp     MSCOMCTL!DllGetClassObject+0xb49c (275a2783)

重新加载poc.doc,因为mscomctl.ocx是word在加载poc.doc的时候才加载的,需要在加载mscomctl.ocx的时候断下来,然后才可以在函数vul_parent上下断点。
操作如下:
打开windbg、word软件,windbg附加word软件进程,sxe ld mscomctl.ocx,g,word打开poc.doc文件,windbg成功在加载MSCOMCTL.OCX时断下:

(900.e64): Break instruction exception - code 80000003 (first chance)
eax=7ffd4000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=039fffcc ebp=039ffff4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc              int     3
0:004> sxe ld mscomctl.ocx
0:004> g
ModLoad: 27580000 27686000   C:\WINDOWS\system32\MSCOMCTL.OCX
eax=00000000 ebx=00000000 ecx=07d50000 edx=7c92e514 esi=00000000 edi=00000000
eip=7c92e514 esp=00120194 ebp=00120288 iopl=0         nv up ei ng nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000296
ntdll!KiFastSystemCallRet:
7c92e514 c3              ret


在函数vul_parent下断并运行,成功在函数vul_parent 断下:

(7f0.8bc): Break instruction exception - code 80000003 (first chance)
eax=7ffd3000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=0396ffcc ebp=0396fff4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc              int     3
0:004> sxe ld mscomctl.ocx
0:004> g
ModLoad: 27580000 27686000   C:\WINDOWS\system32\MSCOMCTL.OCX
eax=00000000 ebx=00000000 ecx=07e10000 edx=7c92e514 esi=00000000 edi=00000000
eip=7c92e514 esp=00120194 ebp=00120288 iopl=0         nv up ei ng nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000296
ntdll!KiFastSystemCallRet:
7c92e514 c3              ret
0:000> bp 0x275a26fa
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\MSCOMCTL.OCX - 
0:000> bl
 0 e 275a26fa     0001 (0001)  0:**** MSCOMCTL!DllGetClassObject+0xb413
0:000> g
Breakpoint 0 hit
eax=034336ec ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a26fa esp=00121700 ebp=00121724 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
MSCOMCTL!DllGetClassObject+0xb413:
275a26fa 55              push    ebp


首先记录一些重要数据,
Breakpoint 0 hit
eax=034336ec ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a26fa esp=00121700 ebp=00121724 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
MSCOMCTL!DllGetClassObject+0xb413:
275a26fa 55              push    ebp
0:000> dd esp
00121700  275e727b 034336ec 023a57b8 00000000
00121710  034336c8 0023f2d8 275a688f 00000001
00121720  00121744 00121744 275e75c2 034336ec
00121730  023a57b8 023a57b8 736d7449 00000064
00121740  275b0000 001217c4 275ca175 0023f4d0
00121750  023a57b8 0023f328 0023f2d8 06a9569c
00121760  abcdef01 00050000 01655d98 00000007
00121770  80000008 80000005 00000000 2758310b
0:000> p
eax=034336ec ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a26fb esp=001216fc ebp=00121724 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
MSCOMCTL!DllGetClassObject+0xb414:
275a26fb 8bec            mov     ebp,esp
0:000> p
eax=034336ec ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a26fd esp=001216fc ebp=001216fc iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
MSCOMCTL!DllGetClassObject+0xb416:
275a26fd 83ec14          sub     esp,14h
0:000> p
eax=034336ec ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a2700 esp=001216e8 ebp=001216fc iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
MSCOMCTL!DllGetClassObject+0xb419:
275a2700 53              push    ebx

可以看到在vul_parent函数内部,ebp=0x001216fc,在栈上分配了0x14大小的空间
在vul函数下断点并运行:
275a2700 53              push    ebx
0:000> bp 275a24a0
0:000> bl
 0 e 275a26fa     0001 (0001)  0:**** MSCOMCTL!DllGetClassObject+0xb413
 1 e 275a24a0     0001 (0001)  0:**** MSCOMCTL!DllGetClassObject+0xb1b9
0:000> g
Breakpoint 1 hit
eax=001216e8 ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a24a0 esp=001216cc ebp=001216fc iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
MSCOMCTL!DllGetClassObject+0xb1b9:
275a24a0 55              push    ebp
0:000> p
eax=001216e8 ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a24a1 esp=001216c8 ebp=001216fc iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
MSCOMCTL!DllGetClassObject+0xb1ba:
275a24a1 8bec            mov     ebp,esp
0:000> p
eax=001216e8 ebx=023a57b8 ecx=275b0b08 edx=00000001 esi=034336ec edi=00000000
eip=275a24a3 esp=001216c8 ebp=001216c8 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
MSCOMCTL!DllGetClassObject+0xb1bc:
275a24a3 51              push    ecx

此时可以看到ebp=0x001216c8

在0x275a24fe下断点,并且运行:
0:000> g
Breakpoint 2 hit
eax=00008282 ebx=023a57b8 ecx=000020a0 edx=00000000 esi=03446008 edi=001216f4
eip=275a24fe esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000207
MSCOMCTL!DllGetClassObject+0xb217:
275a24fe f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
0:000> dd esi
03446008  00000000 00000000 00000000 41414141
03446018  00000000 00000000 00000000 00000000
03446028  00000000 00000000 00000000 00000000
03446038  00000000 00000000 00000000 00000000
03446048  00000000 00000000 00000000 00000000
03446058  00000000 00000000 00000000 00000000
03446068  00000000 00000000 00000000 00000000
03446078  00000000 00000000 00000000 00000000

可以看到此时edi=0x001216f4,ecx=0x000020a0,刚才分析过在vul_parent函数中,ebp=0x001216fc,说明此时如果ecx=4时,esi+0xc正好覆盖了函数返回地址,而此时ecx远远大于4,说明覆盖了返回地址,导致了溢出,此时如果直接运行可以看到eip=0x41414141,已经被我们控制了 

现在的问题就是ecx,edi,esi是有什么控制的,我们在地址0x275a24fe往上查找(即内存低址)
SHR ECX,2即逻辑右移四位,相当于除以四,说明在这条指令前是要移动的字节数,这条指令后是要移动的dword数,在0x275a24e8    call    dword ptr [ecx+0Ch]之后,可以看到ecx=edi,edi=dword ptr [ebp+8]即函数vul的第一个参数,esi=dword ptr [ebp+c],即函数vul的第二个参数,我们重新运行程序,在0x275a2738和0x275a24e8上分别下断(需要在0x275a2738上下断,不然可能会多次断下):
0:000> bp 0x275a2738
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\MSCOMCTL.OCX - 
0:000> bl
 0 e 275a2738     0001 (0001)  0:**** MSCOMCTL!DllGetClassObject+0xb451
0:000> g
Breakpoint 0 hit
eax=001216f4 ebx=023a57b8 ecx=7c93005d edx=00140608 esi=0679cd5c edi=00000000
eip=275a2738 esp=001216d0 ebp=001216fc iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
MSCOMCTL!DllGetClassObject+0xb451:
275a2738 e863fdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)
0:000> dd esp
001216d0  001216f4 023a57b8 00008282 00000000
001216e0  0679cd5c 023a57b8 6a626f43 00000064
001216f0  00008282 00121744 275876c7 00121724
00121700  275e727b 0679cd5c 023a57b8 00000000
00121710  0679cd38 036520d8 275a688f 00000001
00121720  00121744 00121744 275e75c2 0679cd5c
00121730  023a57b8 023a57b8 736d7449 00000064
00121740  275b0000 001217c4 275ca175 036522d0

可以看到函数vul的参数信息:
可以看到第三个参数 poi(esp+0x8)=00008282=0x000020a0*4
第一个参数poi(esp)就是后来275a24fe   rep movs dword ptr es:[edi],dword ptr [esi]中edi的值
单步跟进
0:000> p
eax=7699dd78 ebx=023a57b8 ecx=001216c4 edx=00140608 esi=00000000 edi=00000000
eip=275a24b4 esp=001216b0 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1cd:
275a24b4 51              push    ecx
0:000> p
eax=7699dd78 ebx=023a57b8 ecx=001216c4 edx=00140608 esi=00000000 edi=00000000
eip=275a24b5 esp=001216ac ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1ce:
275a24b5 53              push    ebx
0:000> p
eax=7699dd78 ebx=023a57b8 ecx=001216c4 edx=00140608 esi=00000000 edi=00000000
eip=275a24b6 esp=001216a8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1cf:
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll - 
275a24b6 ff500c          call    dword ptr [eax+0Ch]  ds:0023:7699dd84=30ed7be6
0:000> ln 30ed7be6
(30ed7b91)   mso!Ordinal1077+0x55   |  (30ed7d09)   mso!Ordinal6286
0:000> dd esp l10
001216a8  023a57b8 001216c4 00000004 00000000
001216b8  00000000 0679cd5c 023a57b8 7c93005d
001216c8  001216fc 275a273d 001216f4 023a57b8
001216d8  00008282 00000000 0679cd5c 023a57b8

查看执行0x275a24b6 call    dword ptr [eax+0Ch] 前后各寄存器的值及栈中的数据:
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00000000
eip=275a24b9 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1d2:
275a24b9 3bc6            cmp     eax,esi
0:000> dd esp l10
001216b8  00000000 0679cd5c 023a57b8 00008282
001216c8  001216fc 275a273d 001216f4 023a57b8
001216d8  00008282 00000000 0679cd5c 023a57b8
001216e8  6a626f43 00000064 00008282 00121744

可以看到函数执行前后vul函数的三个参数没有发生变化(ebp+8 ebp+c ebp+0x10)
注意这几个值: edi=esi=0 
继续单步跟进:
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00000000
eip=275a24bb esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1d4:
275a24bb 7c78            jl      MSCOMCTL!DllGetClassObject+0xb24e (275a2535) [br=0]
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00000000
eip=275a24bd esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1d6:
275a24bd 8b7d10          mov     edi,dword ptr [ebp+10h] ss:0023:001216d8=00008282
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24c0 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1d9:
275a24c0 397dfc          cmp     dword ptr [ebp-4],edi ss:0023:001216c4=00008282
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24c3 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1dc:
275a24c3 0f8533150300    jne     MSCOMCTL!DllGetClassObject+0x3c715 (275d39fc) [br=0]
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24c9 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1e2:
275a24c9 57              push    edi
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24ca esp=001216b4 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1e3:
275a24ca 56              push    esi
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24cb esp=001216b0 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1e4:
275a24cb ff3520e06227    push    dword ptr [MSCOMCTL!DllUnregisterServer+0x2dfe8 (2762e020)] ds:0023:2762e020=00140000
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24d1 esp=001216ac ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb1ea:
275a24d1 ff1568115827    call    dword ptr [MSCOMCTL+0x1168 (27581168)] ds:0023:27581168={ntdll!RtlAllocateHeap (7c9300c4)}
0:000> dd esp
001216ac  00140000 00000000 00008282 00000000
001216bc  0679cd5c 023a57b8 00008282 001216fc
001216cc  275a273d 001216f4 023a57b8 00008282
001216dc  00000000 0679cd5c 023a57b8 6a626f43
001216ec  00000064 00008282 00121744 275876c7
001216fc  00121724 275e727b 0679cd5c 023a57b8
0012170c  00000000 0679cd38 036520d8 275a688f
0012171c  00000001 00121744 00121744 275e75c2

此时调用的是在堆上分配内存的函数RtlAllocateHeap,函数定义:
PVOID RtlAllocateHeap( _In_     PVOID  HeapHandle,_In_opt_ ULONG  Flags, _In_     SIZE_T Size);

可以看到在堆上分配大小为0x8282的内存,此处的0x8282即来自edi也就是vul函数的第三个参数。
继续单步: 
0:000> p
eax=03646008 ebx=023a57b8 ecx=7c9301db edx=00140608 esi=00000000 edi=00008282
eip=275a24d7 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1f0:
275a24d7 3bc6            cmp     eax,esi
0:000> r eax
eax=03646008
0:000> dd eax
03646008  baadf00d baadf00d baadf00d baadf00d
03646018  baadf00d baadf00d baadf00d baadf00d
03646028  baadf00d baadf00d baadf00d baadf00d
03646038  baadf00d baadf00d baadf00d baadf00d
03646048  baadf00d baadf00d baadf00d baadf00d
03646058  baadf00d baadf00d baadf00d baadf00d
03646068  baadf00d baadf00d baadf00d baadf00d
03646078  baadf00d baadf00d baadf00d baadf00d

此处eax就是分配内存的首地址
继续单步走:
0:000> p
eax=03646008 ebx=023a57b8 ecx=7c9301db edx=00140608 esi=00000000 edi=00008282
eip=275a24d9 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1f2:
275a24d9 89450c          mov     dword ptr [ebp+0Ch],eax ss:0023:001216d4=023a57b8
0:000> p
eax=03646008 ebx=023a57b8 ecx=7c9301db edx=00140608 esi=00000000 edi=00008282
eip=275a24dc esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1f5:
275a24dc 0f8424150300    je      MSCOMCTL!DllGetClassObject+0x3c71f (275d3a06) [br=0]
0:000> p
eax=03646008 ebx=023a57b8 ecx=7c9301db edx=00140608 esi=00000000 edi=00008282
eip=275a24e2 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1fb:
275a24e2 8b0b            mov     ecx,dword ptr [ebx]  ds:0023:023a57b8={ole32!CExposedStream::`vftable' (7699dd78)}
0:000> p
eax=03646008 ebx=023a57b8 ecx=7699dd78 edx=00140608 esi=00000000 edi=00008282
eip=275a24e4 esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1fd:
275a24e4 56              push    esi
0:000> p
eax=03646008 ebx=023a57b8 ecx=7699dd78 edx=00140608 esi=00000000 edi=00008282
eip=275a24e5 esp=001216b4 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1fe:
275a24e5 57              push    edi
0:000> p
eax=03646008 ebx=023a57b8 ecx=7699dd78 edx=00140608 esi=00000000 edi=00008282
eip=275a24e6 esp=001216b0 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb1ff:
275a24e6 50              push    eax
0:000> p
eax=03646008 ebx=023a57b8 ecx=7699dd78 edx=00140608 esi=00000000 edi=00008282
eip=275a24e7 esp=001216ac ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb200:
275a24e7 53              push    ebx
0:000> p
eax=03646008 ebx=023a57b8 ecx=7699dd78 edx=00140608 esi=00000000 edi=00008282
eip=275a24e8 esp=001216a8 ebp=001216c8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSCOMCTL!DllGetClassObject+0xb201:
275a24e8 ff510c          call    dword ptr [ecx+0Ch]  ds:0023:7699dd84=30ed7be6
0:000> ln 0ed7be6
0:000> ln 30ed7be6
(30ed7b91)   mso!Ordinal1077+0x55   |  (30ed7d09)   mso!Ordinal6286
0:000> dd esp
001216a8  023a57b8 03646008 00008282 00000000
001216b8  00000000 0679cd5c 023a57b8 00008282
001216c8  001216fc 275a273d 001216f4 03646008
001216d8  00008282 00000000 0679cd5c 023a57b8
001216e8  6a626f43 00000064 00008282 00121744
001216f8  275876c7 00121724 275e727b 0679cd5c
00121708  023a57b8 00000000 0679cd38 036520d8
00121718  275a688f 00000001 00121744 00121744

分析一下这个函数使mso组件中的,第一个参数是对象地址,第二个参数是刚才在堆上分配的内存首地址,第三个参数分配内存的大小,第四个参数是0x0,可以看到这个函数可能就是往刚才分配的内存上写数据(数据来源是从poc.doc上读取的数据),注意此时edi=0x8282,poi(ebp+8)=001216f4 poi(ebp+c)=03646008,此处的poi(ebp+c)的值是0x275a24d9 mov     dword ptr [ebp+0Ch],eax传入的,  即堆上分配的内存。
单步走一下:
0:000> p
eax=00000000 ebx=023a57b8 ecx=0012181c edx=00000000 esi=00000000 edi=00008282
eip=275a24eb esp=001216b8 ebp=001216c8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSCOMCTL!DllGetClassObject+0xb204:
275a24eb 8bf0            mov     esi,eax
0:000> dd 03646008
03646008  00000000 00000000 00000000 41414141
03646018  00000000 00000000 00000000 00000000
03646028  00000000 00000000 00000000 00000000
03646038  00000000 00000000 00000000 00000000

函数执行成功返回0,堆分配内存中新写入了数据,这些数据来自poc.doc文件

经过上边分析,我们总结一下,在函数vul中,275a24fe rep movs dword ptr es:[edi],dword ptr [esi]  ,此处ecx来自->275a24fb shr     ecx,2 ->0x275a24f4  mov     ecx,edi->0x275a24bd mov     edi,dword ptr [ebp+10h] ->vul的第三个参数,说明vul函数的第三个参数除以四就是ecx
esi来自->275a24f1 mov     esi,dword ptr [ebp+0Ch]->275a24d9 mov     dword ptr [ebp+0Ch],eax ->275a24d1 call    dword ptr [MSCOMCTL+0x1168 (27581168)]  说明esi来自堆分配的一块大小为0x8282的内存,内存被函数275a24e8 call    dword ptr [ecx+0Ch] 写入poc.doc中的数据
edi来自275a24f6 mov     edi,dword ptr [ebp+8]  即函数vul的第一个参数

上边已经分析完了函数vul,我们继续分析vul_parent函数,从0x275a2738往上分析(即内存低址):

         
 275a270d e88efdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)  
  1. 275a2712 83c40c          add     esp,0Ch  
  2. 275a2715 85c0            test    eax,eax  
  3. 275a2717 7c6c            jl      MSCOMCTL!DllGetClassObject+0xb49e (275a2785)  
  4.   
  5. MSCOMCTL!DllGetClassObject+0xb432:  
  6. 275a2719 817dec436f626a  cmp     dword ptr [ebp-14h],6A626F43h  
  7. 275a2720 0f8539030300    jne     MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)  
  8.   
  9. MSCOMCTL!DllGetClassObject+0xb43f:  
  10. 275a2726 837df408        cmp     dword ptr [ebp-0Ch],8  
  11. 275a272a 0f822f030300    jb      MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f)  
  12.   
  13. MSCOMCTL!DllGetClassObject+0xb449:  
  14. 275a2730 ff75f4          push    dword ptr [ebp-0Ch]  
  15. 275a2733 8d45f8          lea     eax,[ebp-8]  
  16. 275a2736 53              push    ebx  
  17. 275a2737 50              push    eax  
  18. 275a2738 e863fdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)  


函数vul的第一个参数来自0x275a2737 push    eax ->275a2733       lea     eax,[ebp-8] 即函数vul_parent的第一个参数,此时是在ebp低0x8的地址处,如果此时复制的长度超过0x8,就会覆盖ebp,如果超过0xc,就会覆盖到vul_parent的返回地址,就可以造成栈溢出

看一下275a2726 837df408        cmp     dword ptr [ebp-0Ch],8 有个条件判断语句,如果函数vul_parent的第二个参数小于8的话,就跳转,大于等于8的话就继续执行,此处的vul_parent的第二个参数正好是vul函数中275a24fe rep movs dword ptr es:[edi],dword ptr [esi] 复制时ecx*4的值,由于这个错误的判断 ,正好造成了栈溢出。

vul函数的第三个参数来自0x275a2730 push    dword ptr [ebp-0Ch]  我们来重点分析一下这个参数是来自哪里 
 
 1. 275a26fa 55              push    ebp  
  2. 275a26fb 8bec            mov     ebp,esp  
  3. 275a26fd 83ec14          sub     esp,14h  
  4. 275a2700 53              push    ebx  
  5. 275a2701 8b5d0c          mov     ebx,dword ptr [ebp+0Ch]  
  6. 275a2704 56              push    esi  
  7. 275a2705 57              push    edi  
  8. 275a2706 6a0c            push    0Ch  
  9. 275a2708 8d45ec          lea     eax,[ebp-14h]  
  10. 275a270b 53              push    ebx  
  11. 275a270c 50              push    eax  
  12. 275a270d e88efdffff      call    MSCOMCTL!DllGetClassObject+0xb1b9 (275a24a0)  
  13. 275a2712 83c40c          add     esp,0Ch  


在0x275a270d处调用vul函数,第一个参数来自ebp-14h,即写入的地址,第三个参数是0xc,即写入的字节数,从ebp-14h到ebp-8h,此时正好覆盖了275a2730   push    dword ptr [ebp-0Ch]  的内存,说明0x275a270d调用的vul函数写入的数据覆盖了0x275a2738处调用vul函数的第三个参数的数据,也就是poc.doc(0x275a270d调用的vul函数调用了poc.doc中的数据)中的数据最终改写了275a24fe rep movs dword ptr es:[edi],dword ptr [esi] 中ecx的值。

 最后总结一下:

在vul_parent第一次调用函数vul,写入0xc的数据,写入的数据内存正好覆盖了第二次调用函数vul的第三个参数的值,这个值决定了vul复制数据的字节数,本来vul_parent只分配了0x14的栈空间,第一次已经用去了0xc的大小,还有0x8的空间,如果此时第二次调用vul的第三个参数大于8就可以覆盖ebp,甚至函数vul_parent的返回地址

所有问题的症结就在于
275a2726 837df408        cmp     dword ptr [ebp-0Ch],8  
  1. 275a272a 0f822f030300    jb      MSCOMCTL!DllGetClassObject+0x3b778 (275d2a5f) 
有个条件判断语句写错了,应该是判断当 dword ptr [ebp-0Ch]大于8的时候应该跳转结束,这里正好写反了。

其实用IDA分析一下更简单

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (2)
雪    币: 38
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cjkillyes 2016-11-10 17:55
2
0
分析的挺详细,支持一下!
雪    币: 524
活跃值: (87)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
hualuore 3 2016-11-10 19:27
3
0
多谢多谢
游客
登录 | 注册 方可回帖
返回