争对war-ftp 1.65版本的一个漏洞,即向服务器发送超过480字节的用户名可以触发漏洞(即使用命令USER longString\r\n),溢出之后ESP内容包含了longString中的部分内容。
环境:
溢出对象:war-ftp 1.6.5
调试工具:OllyDBG v1.1
使用语言:C
编程环境:Visual.C++ 6.0 .SP6
操作系统:Windows XP Professional
Perl解释器:ActivePerl V5.8.8
设计:
首先向服务器发送一个超长的用户名,确定漏洞是否存在。若存在,用ollydbg将war-ftp调试运行,再向服务器发送一个随机产生的用户名字符串,根据ollydbg的提示,查看溢出时EIP和ESP的内容。根据这两个内容确定他们在用户名字符串中的位置,接下来就要构造我的用户名字符串,EIP的位置填上JMP ESP的地址,ESP的位置起填充我的shellcode,然后将这个精心构造的用户名字符串发送给服务器,并查看是否溢出成功。若成功,会在服务器上创建一个用户和密码都是n00b的管理员账户。
详细过程:
1) 先将war-ftpd.exe用Ollydbg挂起。
2) 然后点击 调试->开始 启动war-ftpd.exe程序。
3) 点击第一个图标,启动ftp服务。然后,自己写一个与服务端建立连接的小程序。建立连接后,程序发送 USER+ A*1000到服务端。发现异常。
4) 可以看到左下角显示 “访问违例 执行[41414141]”,这里的41414141 就是A,也就是说明发生溢出了。此时,我们通过PatternCreate.pl来生成不重复的字符串。
5) 然后将产生的字符串作为用户名发送给服务器端。
6) 上图中,EIP处内容为32714131,ESP的地址为 00F8FD58,根据ESP的地址,我们找到ESP地址中所存放的内容为71413471。然后,我们利用PatternOffset.pl程序计算32714131和71413471在字符串中的位置。
7) 那么这个时候,我们只需要在EIP中填写JMP ESP,在ESP中填上我的ShellCode,然后发送给服务器端就可以了。由于0X7ffa4512为JMP ESP的通用地址,那么,我们只需要在EIP中填写该地址即可。Shellcode我用的是从网上找的一个,该shellcode的作用是在系统中添加一个用户和密码都是n00b的管理员用户。具体代码实现如下。
len = strlen(sc); //shellcode的长度489
//
//EIP地址485,ESP地址493
for (i=0;i<485;i++)
{
buf[i] = 'A';
}
//0x7ffa4512为通用jmp esp的地址
buf[485] = 0x12;
buf[486] = 0x45;
buf[487] = 0xfa;
buf[488] = 0x7f;
for (i=489;i<493;i++)
{
buf[i] = 'B';
}
//ESP指向处,填充我的shellcode。
memcpy(buf+493, sc, len);
buf[493+len] = '\0';
8) 然后运行我们的程序,可以看到war-ftpd.exe自动退出,查看一下系统用户。
至此,实验完成!
结论:
war-ftp 1.65确实存在用户名溢出的漏洞,EIP的位置相对于缓冲区的起始位置是485,ESP的位置相对于缓冲区的起始位置是493,我们只要精心构造一个用户名字符串,然后发送给服务器,就能成功溢出。存在该漏洞的原因是因为war-ftp并不检查发送过来的用户名的长度,只要war-ftp每次对建立连接的用户检查发送过来的用户名长度,如果过长,就截取其中一段,那么该漏洞也就不复存在。