|
Fending off the Rumplestiltskin Mail Attack
I have noticed lately that I have been getting a ton of this nonsense in my sendmail logs:
Apr 9 00:13:36 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:36 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:36 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:36 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:36 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: ... User unknown
Apr 9 00:13:37 server sendmail[19112]: f394DZt19112: from=, size=0, class=0, nrcpts=0, proto= SMTP, daemon=MTA, relay=cable28-105.someisp.net [99.99.99.105]
This is the infamous Rumplestiltskin Attack. Like the fairytale character, this bit of
virtual nastiness tries to guess the named of valid recipients on your servers. Why? So they
can either later send spam, or sell the names to somebody else.
I haven't run across anything that elegant as of this writing (April 2001), so I hacked together
the following script.
The idea is to call it every minute from cron (must be run as root) to check the maillog for
anything that resembles the attack. If it is detected, it routes the offending host to a
dead IP address on your local network. This allows you to play dead before they can drag
your server to its knees. ;-)
Again, this thing is a real hack! It does seem to work quite nicely and should run as-is
on a Redhat box, provided you edit the following lines:
- $myip= whatever your system's main IP address is.
- $blackhole= an unused IP address on your local network.
- $blockedfile= a file to store IP addresses that have been blocked.
- $tolerate= a number indicating how many user unknown messages
you will tolerate from a host before blackholing them.
Then, just make the little edits suggested under the script to implement.
It is easily adapted to other Un*x OS's by simply modifying the paths of things
such as route, tail, grep- as well as the actual route syntax.
#--------SCRIPT-STARTS-ON-LINE-BELOW----------------#
#!/usr/bin/perl
#rumplekiller.pl: something to attempt fending off
#Rumplestiltskin spam attacks. by bignosebird.com 2001
use Socket;
$myip="12.12.12.12";
$blackhole="12.12.12.254";
$blockedfile="/var/log/blockedips";
$tolerate=15;
open(IX,"/usr/bin/tail -1000 /var/log/maillog |");
while ($line=<IX>){
chop $line;
$line=~s/\://g;
$line=~s/\<//g;
$line=~s/\>//g;
@parts=split(/\s+/,$line);
if ($line=~/User unknown/i){
$id=$parts[5];
if ($results{$id} eq ""){
push(@final,$parts[5]);
$results{$id}=1;
}
else{
$results{$id}=$results{$id} + 1;
}
}
}
close(IX);
foreach $item (@final){
if ($results{$item} > $tolerate){
$killer=`/bin/grep '$item' /var/log/maillog | grep -i 'from=' `;
chop $killer;
$killer=~s/\]//g;
@parts=split(/\[/,$killer);
if ( defined(inet_aton($parts[2])) ){
&kill_ip($parts[2]);
}
}
}
sub kill_ip{
my ($ip) = @_;
@subparts=split(/\s+/,$ip);
$ip=$subparts[0];
open (LX,"<$blockedfile");
while ($bl=<LX>){
chop $bl;
if ($bl eq $ip){
return;
}
}
@subparts=split(/\s+/,$ip);
$newip=$subparts[0];
open(OX,">>$blockedfile");
print OX "$ip\n";
close(OX);
if ($ip ne "127.0.0.1" && $ip ne $myip){
system("/sbin/route -n add -host $ip gw $blackhole");
}
}
#------------END-OF-SCRIPT---------------------------#
#----------------- put this line in /etc/crontab
0,10,20,30,40,50 * * * * root /path_to/rumplekill.pl
#---------------- put this line in /etc/rc.d/rc.local
/bin/cat /dev/null >/var/log/blockedips
(or whatever your blocked file happens to be named)
|