从MS03-049漏洞利用看调试系统进程(图)
适合读者:漏洞分析员、黑迷
前置知识:溢出漏洞基本调试步骤、Softice基本使用方法
WTF:Windows XP
SP2相信是大家都在关注的一个系统,这个版本刚推出的时候,由于其具有溢出保护机制,传统的溢出利用方式已经不行了,它也因此而备受青睐。记得当时同行们也开始嘀咕着是否还有继续研究溢出漏洞利用技术的必要。但是随着时间的推移,XP
SP2也慢慢暴露出与以前的操作系统版本存在的兼容性问题,比如,有的软件在Windows 2000或XP SP0、SP1上能正常使用,在SP2上却不行;XP
SP2对利用原始套接字传送TCP数据包做了很大的限制,导致我们开发某些网络程序的时候出现障碍,等等。于是,出现了大量的用户仍然坚持长期使用其它版本系统的情况。我并不是一个守旧者,我只是想借此来说明一下其实MS是给了我们很大的时间来继续研究传统的溢出漏洞的——针对XP SP2的IE漏洞不就出了好几个了吗?好了,废话到此为止,看文章先:
菜鸟版Exploit编写指南之九——
从MS03-049漏洞利用看调试系统进程
本文我主要是从前段时间利用WorkStation服务溢出漏洞(MS03-049)过程中遇到的一些问题为基础,谈谈我是怎样通过对该系统进程的调试来达到利用该漏洞为自己服务的。我的目的不完全是讲这个漏洞,而是更想通过介绍漏洞的利用过程来探讨一下以后在没有公布利用代码,或则有人公布了利用代码但是在关键的地方有所保留的情况下,如何能一步一步地写出自己的利用代码。当然,现在的方法只是很初步的。
尽可能地利用现有的资料
前段时间闲得无聊,想看看有什么新的溢出漏洞可以利用,但是打开Xfocus和Nsfocus一看,实在找不到新的基于Windows的堆栈溢出漏洞。于是就想起了去年的WorkStation漏洞好象没有爆发蠕虫,也就是说虽然网上已有相关补丁,但该漏洞还是有广泛存在的可能性。于是,我决定拿它来练练手。
EEYE发现的MS03-049溢出是在Wkssvc.dll的某个API中Call
vsprintf函数时发生的。我后来找到了Snake的两个分析文章,了解了漏洞的原理以及适用范围,这里不再多讲。遗憾的是,可能由于舆论的压力,Xfocus或Nsfocus都没有在显要的位置公布利用代码,最后费了好大的力气才从论坛上找到了Sbaa的写的那篇代码。有了利用代码,那当然马上试一试。好家伙!居然很快就进了朋友的一台机器,如图1、2所示:
javascript:if(this.width>500)this.width=500" border=0>
图1
javascript:if(this.width>500)this.width=500" border=0>
图2
居然这么顺利?!既然如此,看看能否将利用代码改写为自动传送文件。好在这方面的ShellCode以前编写过,那就用现成的。现在剩下的就是找到溢出点再往下修改即可,为了方便起见,以下的工作都是针对Windows
2000,并且当前系统分区为Fat32。
溢出点的确定
溢出点当然是从现成的代码中找了。再次打开开DOS窗口的源代码,发现其中有两处值得注意的地方,一个地方如图3所示:
javascript:if(this.width>500)this.width=500" border=0>
图3
另一个是代码中发送数据包的安排如下:
| ShellCode| AAAAAAAA…| 跳转地址|
AAAA…|
奇怪!整个代码中只有这个地址覆盖,但是0x7ffa4a1b是Windows 2000下通用的JMP
EBX的地址。我最初的理解是作者要覆盖SEH的处理函数地址,但是为什么在两处使用0x7ffa4a1b呢?而且没有向前跳转的指令,为何刚好跳到ShellCode开始的地方呢?还有,究竟溢出点在什么地?WorkStation服务究竟分配了多少个字节的空间来存储参数?Snake在分析文章中大概指出在2023附近,那就先试试这个。
我填充好数据后,在第2023字节开始的地方覆盖上通用的JMP
ESP地址0x7ffa4512,后面大约40个字节为\xeb\xfe(为什么要这样做,继续往后看!),然后打开Softice,如果溢出点在这里的话,Softice回弹出来将停在“eb
fe”处。可惜,这次没有出现想要的效果,显然2023不是溢出点。但是不用急,再从2001到2040这段区域内依次填写“ABCD…XYZ0123456789JJJJ”,刚好40个字节。编译,连接,得到可执行文件,然后重启系统(这是比较繁琐的地方,每次试验后都得重启),正好弹出来如下图4所示的信息:
javascript:if(this.width>500)this.width=500" border=0>
图4
现在就清楚了,0x54535251对应的是“QRST”,对应位置是在2017处。也就是说,可以认为WorkStation服务分配了2013个字节的缓冲区来存放参数,而函数返回地址是在第2017(下标)字节处。溢出点找到了,下面的事情也就好做一些了。
检测EIP之后的保留地址
前面我在探测2023是不是包含函数返回地址时,在后面约40个字节填满了\xeb\xfe,目的其实在于检查JMP
ESP后面是否有保留地址。因为有时候,BUF中填写JMP ESP的后面是不能直接跟ShellCode的。例如RPC(MS03-026)漏洞就是在JMP
ESP后面必须留8字节的保留地址,那么在WorkStation服务漏洞中呢?按前面的方法一试,如图5所示:
javascript:if(this.width>500)this.width=500" border=0>
图5
从图5可以看出,0x7ffa4512之后到执行“eb
fe”的地方刚好有12个字节,换句话说这12个字节就是保留地址。一般情况下,那我们就只需要把ShellCode放在这12个字节之后就可以了。
检测服务的接收缓冲区大小
其实我觉得这是一个比较容易忽略的地方,在有的漏洞利用过程中,可能会出现该服务用于接收网络参数的缓冲区大小受限。如果是这种情况,我们就不能把ShellCode放在JMP
ESP地址的后面,而应该考虑放在前面。这个检验方法从Softice里查看内存就知道了,这里不再多讲。当然,经过测试WorkStation服务漏洞不存在这个问题。
使用通用跳转地址
能采用通用的跳转地址最好,即使找不到通用的JMP ESP 的地址,也可以找找其他通用跳转地址,而且有的服务本身就有通用的跳转地址。例如SQL
Resolution服务漏洞中,就有一个通用的JMP
ESP的地址0x42b0c9dc, 而RPC溢出漏洞中有通用的具有JMP ESI功能的跳转地址0x0100139d。
如果要想跳转地址更通用,这里推荐现在比较流行的两个:对Windows 2000、XP、2003都通用的具有JMP
EBX功能的地址是0x7ffa1571,通用的具有JMP ESP功能的地址是0x7ffa4512。在WorkStation服务漏洞中,我用的是0x7ffa4512。
接下来,就可以改写我想要的传送文件并执行的利用代码了,ShellCode是以前编写好了的,这里不在讲述。写好的利用代码和下载Sbaa的利用代码都附在光盘的代码中。
利用JMP ESP
这里在补充一点。前面已经说过,Sbaa的代码中其实有效的覆盖函数返回地址的代码只有一句:memcpy(szBuffer+2017,
“\x1b\x4a\xfa\x7f”,
4),但是他的ShellCode是放在SzBuffer的最前面的。从前面的分析入手,肯定是函数返回时ebx指向了SzBuffer!通过Softice查看如下图6所示:
javascript:if(this.width>500)this.width=500" border=0>
图6
EBX = 0x00109744,而szBuffer的首地址也是0x00109744,果然和想象的一样!
我之所以要说这一点,其实是想说明我们对漏洞利用的原理其实都是差不多的,但是实现的手法却可以有多种。具体怎么实现,那是八仙过海,各显神通。
好了,上面就是我通过利用WorkStation服务漏洞中得出的一些体会,可能有的地方写的不是很清楚,希望能和大家相互交流。此外,本文中对Softice的抓屏我没有其它办法,是用数码相机直接照下来的,所以有点模糊,希望大家见谅。