0x01 漏洞描述

CVE-2010-3333 分析学习
 
0x02 分析环境

 
 
环境
备注
操作系统
winxp sp3
网上下的镜像
虚拟机
VMware
版本号 15.0.2
调试器
ollydebug
windbg
 
反汇编器
IDA Pro
版本号:6.8
漏洞软件
Microsoft office word
版本号:2003 sp3
 
0x03 背景知识

 
RTF文件格式:
 
 
0x04 漏洞分析

一、 查看CVE-2010-3333样本数据
用pdfstreamdumper打开一个样本doc文件,查看该样本部分数据如下图:
CVE-2010-3333 分析学习
 
  二、 基于栈回溯的漏洞分析方法
 
  1. 首先,通过metasploit生成可触发漏洞的poc样本
ps:
  • 漏洞分析:多喜欢用metasploit生成的漏洞样本。
  • exploit技术或shellcode技术:多分析实际的病毒样本。
CVE-2010-3333 分析学习
由于我们分析漏洞,故target选择6
CVE-2010-3333 分析学习
 
 
    2.打开winword.exe,并用windbg附加进程,然后打开生成的样本文件msf.rtf
先用windbg附加进程
CVE-2010-3333 分析学习
 
打开样本文件msf.rtf:
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习
!address edi 报错:
CVE-2010-3333 分析学习
解决:由于要联网下,此处未解决。
书上图片:
CVE-2010-3333 分析学习
 
CVE-2010-3333 分析学习
用lmm命令查看mso模块的详细信息
CVE-2010-3333 分析学习
 
从上面分析,触发异常的指令地址为30e9eb88,原因是在mso.dll上有一处栈溢出漏洞,由于在循环复制内存数据到栈空间时,未检测复制的内存大小,导致覆盖到edi(书里的edi是0x00130000,我的由于symbol并没有出来。但从最开始的输出的edi值也可以看出来。)这个只读内存地址,最后造成访问违例。CVE-2010-3333 分析学习
 
关闭调试,重新启动,在30e9eb88 处下断点,再打开样本文件。
CVE-2010-3333 分析学习
 
断下后,查看栈回溯,以定位是哪个函数调用到崩溃函数。
CVE-2010-3333 分析学习
由于出异常的位置位于:mso!Ordinal6426+0x64d,那么查看是谁调的它,由上图可以看出是mso!Ordinal753+0x306eCVE-2010-3333 分析学习
 
查看mso!Ordinal753+0x306e
CVE-2010-3333 分析学习
可知函数出错地址为:30f4CC5d
 
在30f4cc5d处下断点,重新用windbg加载进程。
0:004> bp 30f4cc5d
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll -
0:004> g
ModLoad: 76060000 761b6000   C:\WINDOWS\system32\SETUPAPI.dll
ModLoad: 72f70000 72f96000   C:\WINDOWS\system32\winspool.drv
ModLoad: 095e0000 095ec000   C:\WINDOWS\System32\spool\DRIVERS\W32X86\3\mdiui.dll
ModLoad: 0a190000 0a25b000   C:\WINDOWS\System32\spool\DRIVERS\W32X86\3\mdigraph.dll
ModLoad: 75ff0000 76055000   C:\WINDOWS\system32\MSVCP60.dll
ModLoad: 76d70000 76d92000   C:\WINDOWS\system32\appHelp.dll
ModLoad: 0d870000 0d8ce000   C:\Program Files\360Safe\safemon\360UDiskGuard.dll
ModLoad: 0d8d0000 0d93d000   C:\Program Files\360sd\ShellIco.dll
ModLoad: 76c00000 76c2e000   C:\WINDOWS\system32\WINTRUST.dll
ModLoad: 765e0000 76675000   C:\WINDOWS\system32\CRYPT32.dll
ModLoad: 76db0000 76dc2000   C:\WINDOWS\system32\MSASN1.dll
ModLoad: 76c60000 76c89000   C:\WINDOWS\system32\IMAGEHLP.dll
ModLoad: 76590000 765de000   C:\WINDOWS\System32\cscui.dll
ModLoad: 76570000 7658c000   C:\WINDOWS\System32\CSCDLL.dll
ModLoad: 76960000 76984000   C:\WINDOWS\system32\ntshrui.dll
ModLoad: 76af0000 76b01000   C:\WINDOWS\system32\ATL.DLL
ModLoad: 759d0000 75a7f000   C:\WINDOWS\system32\USERENV.dll
ModLoad: 75ef0000 75fed000   C:\WINDOWS\system32\browseui.dll
ModLoad: 7e550000 7e6c1000   C:\WINDOWS\system32\shdocvw.dll
ModLoad: 765e0000 76675000   C:\WINDOWS\system32\CRYPT32.dll
ModLoad: 76db0000 76dc2000   C:\WINDOWS\system32\MSASN1.dll
ModLoad: 75430000 754a1000   C:\WINDOWS\system32\CRYPTUI.dll
ModLoad: 3e410000 3e4f7000   C:\WINDOWS\system32\WININET.dll
ModLoad: 0dbf0000 0dbf9000   C:\WINDOWS\system32\Normaliz.dll
ModLoad: 43ce0000 43e14000   C:\WINDOWS\system32\urlmon.dll
ModLoad: 3eab0000 3ec9c000   C:\WINDOWS\system32\iertutil.dll
ModLoad: 76c00000 76c2e000   C:\WINDOWS\system32\WINTRUST.dll
ModLoad: 76c60000 76c89000   C:\WINDOWS\system32\IMAGEHLP.dll
ModLoad: 76f30000 76f5c000   C:\WINDOWS\system32\WLDAP32.dll
ModLoad: 76950000 76958000   C:\WINDOWS\system32\LINKINFO.dll
ModLoad: 7de40000 7dfd9000   C:\WINDOWS\system32\NETSHELL.dll
ModLoad: 76bd0000 76bfd000   C:\WINDOWS\system32\credui.dll
ModLoad: 42e00000 42e0a000   C:\WINDOWS\system32\dot3api.dll
ModLoad: 76e50000 76e5e000   C:\WINDOWS\system32\rtutils.dll
ModLoad: 4a5c0000 4a5c6000   C:\WINDOWS\system32\dot3dlg.dll
ModLoad: 5a990000 5a9b8000   C:\WINDOWS\system32\OneX.DLL
ModLoad: 76f20000 76f28000   C:\WINDOWS\system32\WTSAPI32.dll
ModLoad: 762d0000 762e0000   C:\WINDOWS\system32\WINSTA.dll
ModLoad: 4a820000 4a842000   C:\WINDOWS\system32\eappcfg.dll
ModLoad: 582e0000 582ee000   C:\WINDOWS\system32\eappprxy.dll
ModLoad: 76d30000 76d48000   C:\WINDOWS\system32\iphlpapi.dll
ModLoad: 3eca0000 3f73d000   C:\WINDOWS\system32\ieframe.dll
ModLoad: 36c30000 36c39000   C:\Program Files\Microsoft Office\OFFICE11\msostyle.dll
ModLoad: 39800000 399b3000   C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLL
Breakpoint 0 hit
eax=00124060 ebx=00000000 ecx=00123ed4 edx=00000000 esi=00000000 edi=00000000
eip=30f4cc5d esp=00123eac ebp=00123ed8 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!Ordinal753+0x2f0e:
30f4cc5d 55              push    ebp
 
按F10单步跟踪,当运行到 (sub_30d2810c),此处调用了出异常的函数
0:000> p
eax=00124060 ebx=00000000 ecx=00124164 edx=00000000 esi=00000000 edi=00124060
eip=30f4cc75 esp=00123e88 ebp=00123ea8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
mso!Ordinal753+0x2f26:
30f4cc75 e892b4ddff      call    mso!Ordinal6594+0x596 (30d2810c)
 
跟进函数sub_30d2810c,继续单步,可以发现req movs指令复制内存时,ecx的值为0x0000c8ac,即复制数据大小,由于是操作dword字节,因此需要再除以4(逻辑右移2位)
0:000> p
eax=0000c8ac ebx=05000000 ecx=0000c8ac edx=00000000 esi=1104000c edi=00123e98
eip=30e9eb85 esp=00123e70 ebp=00123ea8 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!Ordinal6426+0x64a:
30e9eb85 c1e902          shr     ecx,2
0:000> p
eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1104000c edi=00123e98
eip=30e9eb88 esp=00123e70 ebp=00123ea8 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!Ordinal6426+0x64d:
30e9eb88 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
 
回头看下msf.rtf样本数据,可以发现上面的0xc8ac其实源自于样本数据,它位于pFragements属性值的第三个字段,偏移8个字符后的四个字符即为复制的数据大小。
CVE-2010-3333 分析学习
 
而0xc8ac后的数据正是实际内存复制的数据,复制内存源esi刚好指向这里。
CVE-2010-3333 分析学习
复制内存的目标地址edi刚好偏移栈底宫0x10字节,加上ebp本身占的4个字节,刚好0x14个字节,再覆盖下去就是函数的返回地址了。CVE-2010-3333 分析学习
由于msf.rtf中复制的内存数据较大,导致复制过程中覆盖到不可写的内存地址而触发异常,因此没有去执行覆盖到的返回地址或SEH异常处理函数。
CVE-2010-3333 分析学习
 
三、漏洞利用
CVE-2010-3333 分析学习
采用实际病毒样本(exploit_clac.rtf)进行分析:
打开ollydebug attach到word进程上,在以下指令处下断点。
30e9eb88 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
 
用word打开exploit_clac.rtf,此时进程停在了我们下断点的地方,观察堆栈
CVE-2010-3333 分析学习
可以查出此时进程准备将esi指向的内容复制到edi(00123E98)所指向的栈区,而从00123E98往下偏移20个字节即是进程正常返回地址。
 
继续单步执行,观察覆盖后的程序流程:
程序直接就跑完了。。。
换一个样本(Three Big Risks to China's Economy In 2011.doc)继续学习
CVE-2010-3333 分析学习
 
用jmp esp指令地址覆盖返回地址
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习程序确实按流程执行了,可是0x7d1f5fb7处不是jmp esp指令。故出错!
重新构造rtf:将7d1f5fb7修改为指向jmp esp的地址,进行尝试。
以下为用ollydbg的findaddr找到的jmp esp指令:
CVE-2010-3333 分析学习
尝试7e6b1107。
用ollydbg单步跟踪,程序确实按期进行了jmp esp,流程如下:
未覆盖返回地址前的栈情况:
CVE-2010-3333 分析学习
 
覆盖了返回地址的栈情况:
CVE-2010-3333 分析学习
 
最后程序跑崩在:
CVE-2010-3333 分析学习
 
尝试用metasploit生成可用的样本进行实验跟踪:
尝试了自动生成和xp sp3的都不行,估计是因为我机器是中文版的。
 
由于没有ASLR和DEP,故经过分析,将原shellcode替换成我failwest的shellcode,成功弹窗。
CVE-2010-3333 分析学习
 
但是如果只是普通的打开这个文档,却不会弹窗,难道说它有调试检测机制?
CVE-2010-3333 分析学习
其实并不是,在这个文档中我们用jmp esp的指令地址0x7e6b1107来覆盖返回地址,可是这个地址并不是很稳定,此处换成call esp指令的地址0x0026762f
CVE-2010-3333 分析学习
成功弹窗
CVE-2010-3333 分析学习
调试跟踪下流程查看:
CVE-2010-3333 分析学习
解释:
CVE-2010-3333 分析学习
用jmp esp不弹出的原因也有可能选择的指令地址在独自运行文档,即不附加调试器时是不行的,所以只能用office 2003中相当于call esp 的指令地址。
 
以此思路,用msfvenom生成shellcode,尝试下:
查看可用的payload
CVE-2010-3333 分析学习
 
选择 windows/exec 查看其参数
CVE-2010-3333 分析学习
 
生成:
CVE-2010-3333 分析学习
然而打开文档是乱码
用-f 选择输出格式 hex(十六进制)
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习
 
疑问:开始时,用windbg,代码停在30e9eb88处,就是30e9eb88 f3a5            rep movs dword ptr es:[edi],dword ptr [esi],调试时说edi指向的空间是只读,那么构造的恶意代码也应该是写不进去才对啊。
此处需要用我们成功的rtf文档,用windbg从头跟踪下流程。重点注意下几个寄存器的值。
采用payload是msfvnom生成的exec弹出计算器的那个文档,进行windbg单步跟踪,在30e9eb88处跟踪,查看相应寄存器里的值。
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习
其实质就是合理构造payload,让它劫持进程,这就是漏洞利用!
 
四、Office 2003与Office 2007 Exploit通用性研究
CVE-2010-3333 分析学习
 
CVE-2010-3333 分析学习
CVE-2010-3333 分析学习
采用“president obama。。。”样本进行学习。
用ollydebug打开,定位到“rep。。。”那条指令,单步运行,查看栈里复制情况。
复制前,esi中的情况
CVE-2010-3333 分析学习
 
pFragments第三个字段,偏移八个字符就是复制的数据大小
CVE-2010-3333 分析学习
复制前edi:00123E98
复制后edi:00124194
相差2fc,加上Dword的后三个字节即为02ff
程序在77c51025处跑崩,将其换为稳定地址0026762f还是跑崩了。然而0026762f在我之前的两篇里都是指向call esp。
疑问:如何判断指令地址的稳定性。
 
0x05 漏洞修复

    下载官方的补丁文件mso.dll与原来的mso.dll进行比较。
用ida分别加载两个dll,并单击保存,会生成相应的idb文件。
安装bindiff插件用于比对这两个idb文件。
    
    安装bindiff:
jdk:jre1.7
bindiff4.2
ida:6.8
 
    ①用ida打开未打补丁前的mso.dll
    ②打开bindiff
CVE-2010-3333 分析学习
    ③单击diff database按钮,在弹出的对话框里选择我们要比较的补丁
    ④等待分析。。。分析结果如下(补丁函数比对)
CVE-2010-3333 分析学习
“similarity”:代表函数相似度
“change”:大多为G标志(即 图标视图发生变化)
ps:如果补丁前后的两个函数不再“matched Functions”中,此时需要手工定位或是尝试别的补丁比较工具。
 
    ⑤由于漏洞是发生在函数30f4CC5d,故直接来查看。
先打开bindiff主程序
CVE-2010-3333 分析学习
然后回到ida,选择view Flowgraphs
CVE-2010-3333 分析学习
补丁前后代码对比:
CVE-2010-3333 分析学习
 
结合对比图,进行动态跟踪分析
CVE-2010-3333 分析学习修复补丁对PFragment要复制数据内容长度进行了比较,如果大于4字节,那么直接清零返回。
 
 
0x0S 写作后面

思路:
  • 查看异常出错位置。分析出错原因。
  • 回溯上层调用函数,并单步跟踪。单步跟踪时关注寄存器里的值所指代的是什么。同时关注实际文档里对应的数据。
 
 
 
 
 
 
 
 
 
 
 

相关文章: