土豆 发表于 2013-12-12 11:24:13

WPS 2012/2013 RTF fchars 堆溢出漏洞分析

本帖最后由 土豆 于 2013-12-12 12:39 编辑

by phperl ,zzf,nine9 of code audit labs of vulnhunt.com

在2013年9月3日,翰海源捕获到一个针对中国政府部门的钓鱼邮件定向攻击事件(参考我们之前的文章) 。我们发现该攻击利用了一个WPS 2012/2013的0day漏洞,之后我们在第一时间通知被攻击客户,以及联系金山WPS相关部门处理该问题。金山WPS对于我们反映的问题,做出迅速响应,与昨天(2013年12月10日)修补该漏洞,并发布新的版本WPS。请大家及时更新WPS的最新版本,下面是我们针对本次0day攻击事件的技术分析一些摘要。

      问题描述

在WPS处理rtf时,遇到\*\fchars元素时处理不当,导致堆溢出,成功利用,攻击者可以执行任意代码。

   漏洞分析

在处理rtf时,遇到\*\fchars元素时会将其后形如\u16705格式的字符串转换成字符后使用wcscat追加到缓冲区末尾,直到遇到‘}’字符为止,由于没有检测字符串的长度,导致heap缓冲区溢出。缓冲区位于C++对象的内部,紧跟在缓冲区后面的是虚表指针,覆盖了虚表指针后,可以跳转到用户控制的地址,构造ROP绕过DEP可以执行任意代码。


asm code in rtfreader.dll 9.1.0.4249
.text:10033296               mov   , eax
.text:10033299               call    ds:isalpha
.text:1003329F               pop   ecx
.text:100332A0               test    eax, eax
.text:100332A2               jz      short loc_1003326B
.text:100332A4               lea   eax,
.text:100332A7               push    eax
.text:100332A8               push    ebx
.text:100332A9               call    read_num//ebp-1c为转换前的字符串长度
.text:100332AE               cmp   , 496h
.text:100332B5               jnz   short loc_100332C8
.text:100332B7               push    //ebp-18为转换后的字符
.text:100332BA               push   
.text:100332BD               push    ebx
.text:100332BE               call    sub_10032A2C
.text:100332C3               jmp   loc_1003304E

.text:10011D2C ; int __stdcall sub_10011D2C(int, void *Src, int)
.text:10011D2C sub_10011D2C    proc near               ; DATA XREF: .rdata:10038644o
.text:10011D2C                                       ; .rdata:100386F8o
.text:10011D2C
.text:10011D2C Dst             = dword ptr -20h
.text:10011D2C var_C         = dword ptr -0Ch
.text:10011D2C var_4         = dword ptr -4
.text:10011D2C arg_0         = dword ptr8
.text:10011D2C Src             = dword ptr0Ch
.text:10011D2C arg_8         = dword ptr10h
.text:10011D2C
.text:10011D2C               push    ebp
.text:10011D2D               mov   ebp, esp
.text:10011D2F               sub   esp, 20h
.text:10011D32               mov   eax, ___security_cookie
.text:10011D37               xor   eax, ebp
.text:10011D39               mov   , eax
.text:10011D3C               mov   eax,
.text:10011D3F               push    esi
.text:10011D40               push       ; Dst
.text:10011D43               mov   esi,
.text:10011D46               push    eax             ; Src
.text:10011D47               lea   ecx,
.text:10011D4A               call    sub_1000FF9B
.text:10011D4F               cmp   , 8
.text:10011D53               mov   eax,
.text:10011D56               jnb   short loc_10011D5B
.text:10011D58               lea   eax,
.text:10011D5B
.text:10011D5B loc_10011D5B:                           ; CODE XREF: sub_10011D2C+2Aj
.text:10011D5B               push    eax             ; Source
.text:10011D5C               mov   eax,
.text:10011D5F               add   eax, 18D8h
.text:10011D64               push    eax             ; Dest
.text:10011D65               call    ds:wcscat    //追加到缓冲区末尾,此处会导致缓冲区溢出
.text:10011D6B               pop   ecx
.text:10011D6C               pop   ecx
.text:10011D6D               push    0               ; int
.text:10011D6F               push    1               ; char


漏洞利用分析

利用上面的方式在堆上填充大量0×030a4a2c,该地址为指向dbghelp.dll中切换堆栈的指令,将堆栈切换到发生溢出的缓冲区中,从而利用dbghelp.dll中的指令构造ROP绕过DEP。


0:000> u 030a4a2c
dbghelp!dia::CDiaLoadCallback::InitExeRead+0x43:
030a4a2c 95            xchg    eax,ebp
030a4a2d c0eb02          shr   bl,2
030a4a30 b001            mov   al,1
030a4a32 5e            pop   esi
030a4a33 c9            leave
030a4a34 c3            ret


溢出的缓冲区的内容为:

    ROP链

    Shellcode

    NOP指令0×41414141

    0×030a4a2c在堆中的地址

重现方法如下:


ba e1 030a4a2c
eax=035fbc48 ebx=03648008 ecx=00200404 edx=035d65e7 esi=0012cda0 edi=00000071
eip=030a4a2c esp=0012ccdc ebp=0012ccf8 iopl=0         nv up ei pl zr na pe nc
cs=001bss=0023ds=0023es=0023fs=003bgs=0000             efl=00200246
dbghelp!MiniDumpReadDumpStream+0x4eb7c:
030a4a2c 95            xchg    eax,ebp
0:000> db eax-20
035fbc2841 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
035fbc3841 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
035fbc4804 04 20 00 8e c5 0b 03-f0 f4 ff ff 84 0f 0c 03.. .............
035fbc5800 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00................
035fbc6800 00 00 00 58 9c f1 01-00 00 00 00 00 00 00 00....X...........
0:000> dd 200404
00200404030a4a2c 030a4a2c 030a4a2c 030a4a2c
00200414030a4a2c 030a4a2c 030a4a2c 030a4a2c
00200424030a4a2c 030a4a2c 030a4a2c 030a4a2c


ROP链分析

将堆栈指针切换到溢出缓冲区

执行VirtualProtect,将栈变为可执行

返回到jmp esp指令,开始执行shellcode

    shellcode分析

先是shellcode解码头


035fb254 0fb6c0          movzx   eax,al
035fb257 01c7            add   edi,eax
035fb259 3017            xor   byte ptr ,dl          ds:0023:035fb260=f5
035fb25b 47            inc   edi
035fb25c 49            dec   ecx
035fb25d 75fa            jne   035fb259


循环遍历句柄,调用GetFileSize,成功则调用CreateFileMapping、MapViewOfFile,搜索11222211和33444433,找到则开始解密,将解密后的内容写入临时文件的IE7.exe文件,并使用WinExec执行该文件,执行后会释放到临时目录win32_453B.dll。

shellcode使用LoadLibrary加载释放的dll,并调用dll导出函数mail。

本文转载自:FreebuF.COM

启帆 发表于 2013-12-12 11:31:02

:funk:看不懂呢....

契约 发表于 2013-12-12 19:09:45

小弟 看不懂 逆向不咋滴楼主的OD是白色的也看不习惯 = =

彼岸花开 发表于 2013-12-14 09:21:54

csadsl 发表于 2013-12-14 10:53:19

逆向好家伙啊
页: [1]
查看完整版本: WPS 2012/2013 RTF fchars 堆溢出漏洞分析