cve-2010-3333
漏洞简介
Microsoft Office XP SP3、Office 2003 SP3、Office 2007 SP2、Office 2010等多个版本的Offic软件中的Open XML文件格式转换器存在栈溢出漏洞,主要是再处理RTF中的pFragments属性时存在栈溢出,导致远程攻击者可以借助特制的RTF数据执行任意代码,因此该漏洞又名“RTF栈缓冲区溢出漏洞”
RTF文件格式
RTF的基本元素是正文、控字、控制符号和群组。
-
控制字是RTF用来标记控制符和管理文档信息的一种特殊格式的命令,RTF用它作为正文格式的控制代码,每个控制字均以一个反斜杠开头,由a~z小写字母组成,通常应该不包含任何大写字母,而分隔符标志着控制字名称的结束。它的使用格式为:字母序列<分隔符>。分隔符>
-
控制符号由反斜杠后跟一个单独的、非字母的字符,表示一个特定的符号。
-
群组由包含在大括号中的文本、控制字或控制符组成。左扩符({)表示组的开始,右扩符(})表示组的结束。每个组包括文本和文本的不同属性。RTF文件也能同时包括字体、格式、屏幕颜色、图形、脚注、注释、文件头和文件尾、摘要信息、域和书签的组合,以及文档区段、段落和字符的格式属性。
\rtf1 —— RTF版本
\ansi —— 支持ANSI字符集
\shp —— 绘图对象
*\shpinst —— 图片引用
\sp —— 绘图对象属性定义
\sn pFragments —— 定义属性名称,pFragments段是图形的附加部分,属于数组结构。它允许图形包含多个路径和分段,该属性列出图形各个碎片
\sv —— 定义属性值
分析环境
操作系统 Windows XP SP3
调试器 Windbg
漏洞软件 Microsoft Office Word 2003 SP3
样本分析
我们先用Metasploit生成一个会让程序崩溃的样本
先打开RTF样本文件看一下
打开word和windbg,附加上word,输入g之后打开样本文件,发现断在了这个位置,这里是循环ecx次把[esi]的值给了[edi],我们也可以看到它的错误是发生在mso.dll里面的
我们现在通过栈回溯来查找是什么函数调用了它,注意这里栈回溯应该是回溯没有运行到30e9eb88的位置,因为现在的栈已经被破坏。
重新打开windbg断点断在30e9eb88的位置,查看当前栈环境
mso!Ordinal6426+0x64d就是我们当前所在的函数,所以mso!Ordinal753+0x306e就是调用它的函数。
用ub来查看代码,注意这里要用ub而不是u,u是查看地址后面的代码而ub是查看前面的,我们这里需要看的是前面的。再把断点下在30f4cdb8
慢慢往下走,根据前面的地址,我们可以判定就是这个函数里面发生了崩溃
同时我们可以看到前面调用函数给栈分配的空间只有0x14,所以我们在执行rep的时候只要让ecx比0x14大就可以导致栈溢出。
同时我们可以看到这里的ecx其实是样本文件里面的值
找到了漏洞的位置,接下来的利用就比较容易了,典型的栈溢出,我们只要覆盖函数的返回地址为jmp esp然后把shellcode布置在栈后面或者覆盖SHE调用异常处理也可以实现利用。所以我们只要覆盖0x14个值就可以了,注意这里是双字节所以应该输入的是2*0x14个字符来溢出,接下来的就是覆盖返回地址了,我们先用jmp esp尝试,这里给出一种用windbg来查找jmp esp的方法
先用lm来查找当前加载的块,一般我们找kernel32或者ntdll模块里面的
然后用命令s startaddr lastaddr XX XX,xx为机器码,如jmp esp 则为FF E4
拿到命令。还要注意最后的ret 14h,需要填充2*0x14个字节然后再布置shellcode即可。
书中作者点名了,用jmp esp命令的地址可能会受到软件及系统版本的影响,比较难实现通用性,所以用call esp覆盖返回地址,然后再覆盖SHE结构触发异常来劫持eip。
漏洞修复
用bindiff来进行比较
使用教程:https://www.cnblogs.com/lsdb/p/10543411.html
安装完成后可以在文件目录下用java -jar打开.jar文件,但我的bindiff一直卡着,无法识别,所以就没有成功的比较两着的差异。
从作者书中给出的介绍是,修复漏洞时,主要检测RTF文件中的pFragments属性值的大小是否大于4字节,若大于则跳走并返回,而不再进行内存复制,从而解决栈溢出的问题。