CVE-2010-3333分析

漏洞描述

  • Microsoft OfficeXP SP3、Office 2003 SP3、Office 2007 SP2、Office2010等多个版本的OFFice软件中的Open XML文件格式转换器存在栈溢出漏洞,主要是在处理RTF中的“pFragments”属性时存在栈溢出,导致远程攻击者可以借助特制的RTF数据执行任意代码,因此该漏洞又名“RTF栈缓冲区溢出漏洞”。

分析环境

使用的环境 备注
操作系统 Windows7 32位 旗舰版
虚拟机 VMware 12.1.1
调试器 windbg、Immunity Debugger 6.3/1.85
反汇编器 Ida 6.8
漏洞软件 Microsoft Office Word 2007
十六进制工具 010Edito 7.0

RTF文件格式

  • RTF格式是Microsoft公司为进行文本和图像信息格式的交换而制定的一种文件格式,适用于不同的设备、操作系统。RTF文件基本元素是正文、控制字、控制符号和群组。
  • 控制字是RTF用来标记打印控制符和管理文档信息的一种特殊格式的命令,RTF用它作为正文格式的控制代码,每个控制字均以一个反斜杠\开头,由a~z小写字母组成,通常应该不包含任何大写字母,而分隔符标志着控制字名称的结束。它的使用格式为:\字母序列<分隔符>。
  • 控制符号由反斜杠后跟一个单独的、非字母的字符,表示一个特定的符号。
  • 群组由包含在大括号中的文本、控制字和控制符组成。左括弧表示组的开始,右括弧表示组的结束。每个组包括文本和文本的不同属性。RTF文件也能同时包括字体、格式、屏幕等属性。一个完整的RTF文件包括文件头和文档区两大部分,可以用下列语法表示。
<File>{<header><document>}
通过微软官方文档的目录,可以了解到文件头和文档区各自所包含的数据如图1所示

图1
* CVE-2010-3333部分数据,如图2所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091225130-1047436263.png)
图2
* RTF部分数据分析如下 ```c \rtf1-RTF版本 \ansi-支持ANSI字符集 \shp-绘图对象 \*\shpinst-图片引用 \sp-绘图对象属性定义 \sn pFragments-定义属性名称,pFragments段是图形的附加部分,属于数组结构。允许图形包含多个路径和分段,该属性列出图形各个碎片 \sv-定义属性值 ``` * RTF分析器正是在解析pFragments属性值时,没有正确计算属性值占用的空间大小,导致栈溢出漏洞的发生。 ####生成样本 * 通过Metasploit生成可触发漏洞的Poc样本,通过直接生成样本以供分析漏洞。 * 通过search搜索cve-2010-3333漏洞相关利用代码,如图3所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091600549-1080295970.png)
图3
* 利用use命令指定exploit,并用info命令生成关于此exploit的信息,包括参数值、漏洞描述等,如图4所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091634551-1899758047.png)
图4
* 主要是为了分析漏洞成因,因此选择可触发崩溃的Poc样本,直接通过set命令即可设置target参数值,如图5所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091702127-2114393332.png)
图5
* 利用exploit命令直接生成测试样本,如图6所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091725432-990218881.png)
图6
####漏洞分析 * 获取样本后,打开WINWORD.exe,并使用WinDbg附加进程。然后打开msf.rtf,触发异常,如图7-11所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091815968-1195803635.png)
图7
![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091817619-1550820529.png)
图8
![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091827000-1068459338.png)
图9
![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091833839-637182748.png)
图10
![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091838670-821960365.png)
图11
* 这是mso.dll上的一处栈溢出漏洞,由于循环复制内存数据到栈空间的时,未检测复制内存的大小。导致覆盖到edi(0x00130000)这个只读内存,造成访问违例。 * 使用Immunity Debugger分析,如图12所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418091955325-276614441.png)
图12
* 栈回溯,找到memcpy,如图13所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092018034-1834485331.png)
图13
![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092038021-918968174.png)
图14
* 回头看下msf.rtf中的样本数据,可以发现上面的0xc8ac是源于样本数据的,位于pFragements属性值的第三个字段,偏移八个字符后四个字符即为复制数据的大小,如图14所示。 * 查看memcpy函数的参数地址,如图15-16所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092126377-829270921.png)
图15
![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092129369-263625100.png)
图16
* 跟踪进去发现覆盖返回地址,如图17所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092211017-1545889239.png)
图17
* 复制内存目标地址edi刚好偏移栈底ebp共0x10字节,加上ebp所占四字节,刚好0x14字节,在覆盖下去就是返回地址了。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092242552-1799723131.png)
图18
* 0xc8ac后面的数据正是实际内存复制的数据,复制内存原地址esi刚好指向这里,如图18所示。 * 由于msf.rtf复制内存数据比较大,导致复制过程中覆盖到不可写的内存地址而触发异常,没有去执行返回地址或者seh异常处理函数。 ####漏洞利用 * 分析完漏洞成因,利用该漏洞还是比较容易的。只需将jmp esp指令地址覆盖返回地址,也就是复制数据大小的值之后在偏移.0x14字节,即可覆盖返回地址。然后将shellcode放在后面,即可执行任意代码,如图19所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092333983-269552880.png)
图19
* 以覆盖返回地址0x77411463(这个地址是随机的,需要手动去调试确认)。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092426782-667889194.png)
图20
* 覆盖完成继续跟踪执行,发现在0x610d7977处有一个判断,[ebp+0x14]是否为0,此时[ebp+0x14]相当于[eip+0x14]这里的eip指的是我们覆盖的返回地址。不为0发生跳转,就会发生异常。如图20所示。 * 由于Office存在内存异常处理,也无法执行我们覆盖的seh,以至无法使eip得到执行,如图21所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092517494-1523499982.png)
图21
* 跟进触发异常的函数 * 为了让eip能够执行,必须不让他它跳转,也就是[eip+0x14]处必须为0x00000000,才能让程序正常执行。 * 更改后的msf.rtf,如图22所示。 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092558719-2124580138.png)
图22
* 注:shellcode要使用小写 ![](https://img2018.cnblogs.com/blog/1554865/201904/1554865-20190418092650055-1911625157.jpg)
图23
  • 打开样本,即可执行代码,如图23所示。
补丁比对
  • 如图24所示
图24
* 漏洞主要是在复制内存的时候未检测内存大小导致的栈溢出。但是里面调用的函数都是通过eax索引的,利用动态调试。 * 主要是通过动态监测pFragments属性值是否大于4字节,若大于则跳走并返回,而不进行内存复制,从而解决栈溢出问题。
posted @ 2019-04-18 09:30  一生热爱  阅读(888)  评论(0)    收藏  举报