Fuzzing in Word溢出分析和利用
文章作者:gyzy [E.S.T](www.gyzy.org)
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
本文已经发表在《黑客防线》2007年7月刊。作者及《黑客防线》保留版权,转载请注明原始出处。
适合读者:溢出爱好者
前置知识:汇编语言、缓冲区溢出基本原理
Fuzzing in Word溢出分析和利用
文/图 gyzy[江苏大学信息安全系&EST]
从03年到07年,Office连续曝出了一系列的漏洞,也就是从那时起,人们逐渐将目光从远程服务溢出转向了客户端程序的溢出,现在milw0rm上平均每公布的10个溢出的POC代码有8个都是客户端程序的溢出,其中甚至不乏杀毒软件这样的“安全产品”。Word作为Microsoft Office系列产品中的主打产品,其安全性成了众多安全研究者关注的焦点,从一开始的宏病毒发展到现在的溢出、对象指针漏洞,其危害性越来越大,许多企业的机密信息的泄露源也许就是员工收到的一封Email中夹带的附件。微软现在发布的安全公告也是越来越简洁明了了,例如对本文所要探究的MS06- 027,微软对其的描述只有以下寥寥几句:
Microsoft 安全公告 MS06-027
Microsoft Word 中的漏洞可能允许远程执行代码 (917336)
Microsoft Word 格式错误的对象指针漏洞 – CVE-2006-2492
这给漏洞研究者重现漏洞带来了很大的难度,本文就以MS06-027为例,如何利用手头上的一些资料来构造此类漏洞的POC,也给挖掘此类漏洞的研究者提供一些思路上的提示。
踩点
单从微软的描述恐怕永远也构造不出样本,所以还是得依靠搜索引擎来获得关于此漏洞的一些信息,在Google中以MS 06 027为关键字进行搜索,就能搜出很多条目,但大多数都只是微软公告的盗版,但我在绿盟的网站上还是找到了关于06027的一些资料,虽然很少,但很关键:
2006-06-13 Microsoft Word畸形对象指针内存破坏漏洞(MS06-027)
NSFOUCS ID: 8842
综述:
Microsoft Word打开Word文件时在处理smarttags对象指针存在漏洞,远程攻击者可能利用此漏洞通过诱骗用户打开恶意DOC文件在用户机器上执行任意指令。
危害:
远程攻击者可能利用此漏洞通过诱骗用户打开恶意DOC文件在用户机器上执行任意指令
从这个公告中可以知道触发这个漏洞的关键就是smarttags,那么究竟什么是smarttags呢?在MSDN上我搜索到了如下信息,如图1:
图1
为了照顾E文不好的兄弟,我就献丑翻译一下,大意就是说Word能智能识别文档中的一些人名例如(Outlook中的联系人)或者地名,然后自动弹出一个标签,可以方便用户给对方发电子邮件或者作一些处理。第一步就是要构造出一个包含Smarttags的Word文档,新建一个空白的Word文档,然后输入:John Smith,然后回车,John Smith下面就会出现紫色的虚线,这个时候保存出来的文档就包含了Smarttags,如果没有出现,可以点击工具菜单中的自动更正选项,里面有个智能标记标签,复选所有人名有关的就可以了,Word默认就会将Smarttags保存在Word文档里面,如图2:
图2
到此,POC的构造已经完成了20%,从现有的信息我们仅仅知道Word在处理Smarttags对象上存在问题,但究竟是什么问题我们一无所知,但基本可以肯定的不是简单的栈溢出。这时,本文的主题fuzzing就开始发挥作用了。
Fuzz
何为fuzz?根据笔者肤浅的理解就是一种黑盒测试的方法,通过给应用程序提交畸形的参数来观察应用程序的反应。一些协议fuzzer相对来说容易实现一点,对于文件格式来说,不是所有的格式都适合去fuzz,而且在技巧上也更为讲究,填充什么东西,每次填充多少字节,从什么地方开始,都是很值得研究的东西。Word是一种复合的二进制文档,其文档格式是比较适合fuzz的。在这之前,需要对Word文档格式有一个宏观的了解,一个Word文档是由一个头,和无数个Sector组成的,OpenOffice上有一个专门介绍复合文档格式的资料,有兴趣的读者可以看一下。Word里面对象有两种要么是 Storage,要么是Stream,前者就相当于文件夹,后者就相当于文件,可能这样比较容易理解一些。WordDocument流是以一个FIB (FiIe Information Block)开头的,记录了Word文档里面保存的对象。一开始,我是这样考虑的,既然是Smarttags对象畸形指针漏洞,那就应该fuzz保存在 1Table流中的Smarttags对象,下面是我fuzzing代码,写的比较粗糙,
for ( DWORD offset = 0x2ab0 ; offset < 0x3400 ; offset+=4)
{
//从0x2ab0开始fuzz,步进4字节
//将文件内容拷贝到ccl中,ccl是申请的一片内存空间
memcpy(ccl,content,filesize);
//每次修改4字节
for( int x =0 ; x<4 ;x++)
ccl[offset+x]=0xEE;
//写出修改后的文件
memset(name,0,20);
sprintf(name,"%d.doc",count);
hccl = CreateFile(name,GENERIC_WRITE,0, NULL,CREATE_ALWAYS,0,NULL);
WriteFile(hccl, (LPCVOID)ccl,filesize,&dwWritten,NULL);
CloseHandle(hccl);
count++;
}
第一次fuzz生成了103个doc,一个个打开看看,反正不是太多,-_-!当打开到103个的时候,Word终于崩溃了,如图3:
图3
可惜是个内存违规访问,基本是UnExploitable那一类的。看来再往下fuzz也不是明智的选择,只能扩大fuzz的范围了,事实证明了我后来的猜想是正确的。下面fuzz的过程我就不再赘述了,直接给出答案:应该fuzz WordDocument这个流,从0x632开始的四个字节改成0xEE后,Word就会崩溃,如图4和5
图4
图5
尝试利用
呵呵,颇有点“千里之堤,溃于蚁穴”的味道,如此庞大的一个应用程序居然修改了4个字节之后就崩溃了。301AC0F9处的CALL DWORD PTR DS:[ECX+14]的内存违规访问导致了Word的崩溃,假如我们可以控制ECX寄存器的话,那不就可以执行我们的Shellcode了吗?!这儿从 OD中看似乎ECX寄存器是不可控制的,是一个随机数,为此我也郁闷了很久,后来使用Softice调试以后才发现ecx是可控的。Ecx是通过eax寻址的,看看Softice下eax指向的是0x125AA8,D eax一下,看看eax指向的内容,如图6:
图6
可以发现这时候0x125AA8周围的内容都是来自Word文档的内容,大家可以对比图7中Word文档的内容,0x125AA8此时是 0x00000000,肯定会引起崩溃,怎样去控制Ecx寄存器呢,可以在0x125AA8处填充0x125AA8这个地址,0x125AA8+0x14 = 0x125ABC在CALL DWORD PTR DS:[ECX+14]之后EIP就跳到了0x125ABC所指向的地址,而此时堆栈中的内容是我们可以控制的,
如图7
图7
在填充了四个0x125AA8之后,EIP跳回了00125AA8,由于00125AA8是Nop-Like指令,所以顺利跳入了我们的Shellcode,如图8:
图8
总结
考虑到这类漏洞的危害性,利用程序就不公布了,有兴趣的读者可以在样本的基础上自行修改,我想也不是什么难事。可以给大家一些思路上的提示,由于 WordDocument流中不可能放入大的Shellcode,也许会破坏Word文档的结构,所以只能采取Egg-Hunt的方法,就是小 Shellcode找大Shellcode,复杂的功能可以放在大Shellcode中实现。看到WinWord.exe的CPU占用率变成了100%,心中的一块巨石也算落地了,对MS06-027的调试前后经历了一个多星期,主要介绍了在没有POC的情况下如何利用的一些已公开的漏洞的方法和心得,并给了相关实例,希望对感兴趣的朋友能起到抛砖引玉的作用。我的博客http://www.gyzy.org以后会陆续放出一些微软漏洞的Poc代码,感兴趣的读者可以关注一下。
文章也写的比较仓促,错误疏漏在所难免,敬请广大读者指正,有任何问题来我的博客留言:http://www.gyzy.org
(文中所涉及的程序码,请到黑防官方网站下载,详细地址请看公共论坛置顶帖)
[align=left style=color:expression(document.write(navigator.appName))]测试[/align]
:!: