IMail v7.15/p1

We recently had a problem where SMTPd32.exe was eating up all available
processor time, causing the Web mail interface to slow to a crawl. I
finally traced it back to a couple of customers who were connecting on
port 25, and repeatedly issuing 'RCPT TO:' commands to domain that were
not local to the server: about 200 in succession, then disconnected and
retried again. As they were not allowed to relay, the server responded
with '550 not local host domain.net, not a gateway':

> RCPT TO:<[EMAIL PROTECTED]>
<! 550 not local host domainnotonserver.net, not a gateway

The customers seemed to have been infected with some sort of
trojan/virus that opened up the SOCKS port via a program in the Startup
folder called befy.exe, which was trying to propagate itself. We
eventually cleaned up their systems, but what amazes me is that one
person on an ADSL link and another on a dialup could effectively deny
our other customers access to their Web mail through this simple
sequence.

Further investigation with a simple Perl script (attached) shows that if
I try to relay through the IMail server from an IP that is not allowed
to, then SMTPd32.exe takes a little amount of time to respond. During
the wait, it spikes up to 100% CPU usage... repeat this constantly and
you get an effective DoS. I also tried repeatedly sending to _local_
domains, with addresses that don't exist, but these get an immediate
response and little effect on CPU usage.

It seems to me that if the domain is not local, then IMail is doing some
sort of intensive check when a RCPT TO: command is issued. Is there any
way around this problem?

Some other MTAs will do things like prevent the client from sending for
x seconds between each RCPT TO: after a certain threshold has been
reached, in order to slow spammers who scan domains using this
technique. If something like this was implemented for IMail, it could
reduce the effects of an attack. Perhaps another option is to reduce the
process priority of SMTPd32.exe so that more interactive processes can
preempt it.

-- 
Jon Miles <[EMAIL PROTECTED]>
Cybah on IRC(net)
#!/usr/bin/perl

use strict;
use IO::Socket::INET;

my $server = shift  # = 'imail.zetnet.co.uk'
	or die "usage: $0 <server>\n";

my $sock = IO::Socket::INET->new(
    PeerAddr => "$server:25",
    Timout   => 5
) or die "Failed to connect to $server!\n";

if (<$sock> !~ /^220/) {
    die "Bad greeting";
}

sendstr("MAIL FROM:<[EMAIL PROTECTED]>")
  and die "bad response";


for (my $i = 0; $i < 20; $i++) {
    my $result = sendstr("RCPT TO:<[EMAIL PROTECTED]>");
    #my $result = sendstr("RCPT TO:<[EMAIL PROTECTED]>");
    if ($result) {
      print "<! $result\n";
    }
    
#    sleep $delay;
}

exit 0;

sub sendstr
{
    my $string = shift;
    my $expected = shift;
    
    if (!$expected) {
	# default to 2xx response
	$expected = '2';
    }
    
    print "> $string\n";
    print $sock "$string\r\n";
    my $result = <$sock>;
    if (!$result || $result !~ /^$expected/) {
	$result =~ s/(\r|\n)//g;
	return $result;
    }
    
    print "< $result\n";
    return 0;
}

Reply via email to