由 FoxMail 漏洞演示,如何确定溢出的返回点位置。
在这里我们主要利用 FoxMail 漏洞来练习一下缓冲区溢出的第一步精髓,如
何确定溢出返回点的位置。
详细请参考:http://www.xfocus.net/articles/200403/683.html
首先简单的介绍一下 FoxMail 漏洞,问题出在 PunyLib.dll 里面的 UrlToLocal 函
数,当一封邮件被判定为垃圾邮件之后,就会调用 UrlToLocal 来处理邮件体的
“From:”字段,处理过程中发生堆栈溢出,可以导致执行任意代码。
这里由于发送的字节数不能超过 0x200,所以我们测试的时候先发送一个
0x150 个 A ,发送代码如下:
Memset (buffer, 0x41,0x150);
Sprint(temp,”Form: %s \r\n”,buffer);
Send(sock,temp,strlen(temp),0);
查看返回结果为:“ Access violation at address 02FA1BAB in module
‘punylib.dll’,Write of address 41414141”
这里需要解释一下,通常我们要利用一个溢出点返回我们的 ShellCode 是需
要我们的程序去(read)读 EIP 的数据。而这里是(write)写,
我们刚才提交
的数据可能过长,不仅覆盖过了 EIP 的数据,而且还覆盖了其他一些程序要用的
参数,如果在程序返回前,要对那些参数进行改写,但参数的地址为改成
了”41414141”,是根本不能写的,所以就造成了上面的(write)写错误。
那么接下来我们需要做的就是把字段覆盖短一点,要覆盖到返回地址,但是
不要覆盖到那些参数地址,可以采用二分法来类推。最终确定的地址为 0x104。
memset (buffer, 0x41, 0x104);
sprintf (temp, "From: %s\r\n", buffer);
send (sock, temp, strlen (temp), 0);
返回信息为:“Access violation at address 41414141.Read of address 41414141”
如上,我们填充’From:’ 字段时不能超过 0x104 的长度。
定位返回点的位置我们可以通过根据报错信息把数字直接数出来的方式,但
是由于这里的缓冲区比较长,那么采用下面两次提交数据根据数据的不同报错信
息来计算出返回点的位置。
FoxMail1.c
第一步:
For ( i=0;i<=0x104;i++ )
Buffer[i] = ‘A’ + i%10;
Sprint( temp,”From:%s\r\n”,buffer);
Send( sock,temp,strlen(temp),0);
返回信息“Access violation at address 4A494847.Read of address 4A494847”
这里用取余数的
,在 From 字段不段的加上 A-J 的循环(就是十六进制
0x41-0x4A 这十个数的循环)。
报错的最小值为 0x47,那么可以大胆的推算尾数为 0x47-0x41=6。
第二步:
For ( i=0;i<=0x104;i++ )
Buffer[i] = ‘A’ + i/10;
Sprint( temp,”From:%s\r\n”,buffer);
Send( sock,temp,strlen(temp),0);
返回信息“Access violation at address 5A5A5A5A.Read of address 5A5A5A5A”
这里用除 10 的方法,是以 10 为一段长度,每段分别为 0x41,0x42„„来填
充’From:’。
报错信息全部为 5A,此时是从 0x41 开始,每 10 个数为一段。所以
0x5A-0x41=0x19, 十进制为 25,就是在字符串的第 25 个段。
第三步:
由以上推断,我们可大胆计算出程序的返回点位置是: (0x5A-0x41)×
10+(0x47-0x41)=25×10+6=256
Lion 共享的中文通用地址――0x7ffa4512,通杀中文版 Win2000、XP、Win2003
如上,那么我们可能在想在”Form:”填充如下字段就可以返回 Shellcode ,但
是这里还有一个问题,当代码执行到 256 个 A 之后跳转到 ShellCode 的时候就覆
盖掉了 EIP 之后的内容,那么肯定会出现出错信息,变成写数据。
在这里,我们采用如下方式来写入 Shellcode:
在这样的格式下,返回时程序就会先执行 JMP –0x80 这个指令,往前跳到
一堆空指令中,然后顺着空指令往下执行,最后进入到 ShellCode 中,就可执行
我们的 ShellCode 了。