~ overflow ~

Archive for June 5th, 2010

Botnet ddos and mail server hammering

by z3n on Jun.05, 2010, under Coding, Linux Happyness

Problem:
So i noticed a real slow down on my server recently, nothing new was installed, no new sites launched. Investigating it a little further i saw like +100 sendmail processes running in background, WTF!

Solution:

Looking at huge maillogs, i found that there’s a botnet hammering my mail server, trying to authenticate with random strings and send unauthenticated emails, as if my server were configured as a promiscuous email server.

So, i had to put in practice my never used before iptables config skills.

First i added a rule to avoid global hammering:

-N SMTP-BLOCK
-A SMTP-BLOCK -s 127.0.0.1 -j ACCEPT
-A SMTP-BLOCK -s ##YOUR_SERVER_IPS## -j ACCEPT
-A SMTP-BLOCK -m limit --limit 1/m --limit-burst 3 -j LOG --log-level notice --log-prefix "iptables SMTP-BLOCK "
-A SMTP-BLOCK -m recent --name SMTPBLOCK --set -j DROP
-A INPUT -p tcp --dport 25 -m state --state NEW -m recent --name SMTPBLOCK --rcheck --seconds 360 -j SMTP-BLOCK
-A INPUT -p tcp --dport 25 -m state --state NEW -m recent --name SMTP --set
-A INPUT -p tcp --dport 25 -m state --state NEW -m recent --name SMTP --rcheck --seconds 60 --hitcount 10 -j SMTP-BLOCK
-A INPUT -p tcp --dport 25 -m state --state NEW -j ACCEPT

This will avoid hammering on port 25, SMTP, make sure you add your server’s ip here, otherwise it might slowdown your own server from sending emails out. This will ban users for 60 seconds if they send more than 3 packets a minute on port 25, pretty much enough what you need to do.

Now the bot net will still hammering, since they have MANY different ips , 800 so far, they can still hammering and eating up your server resources and bandwidth, since they will not stop i wrote a script to analyze maillogs and ban by ip:

// (c) z3n - R1V1@100605 - www.overflow.biz - rodrigo.orph@gmail.com

if (!isset($argv[2])) die("Usage: ".$_SERVER['PHP_SELF']." <input file> <ip tables>");

function _gii($s,$s_1,$s_2,$st=1) { // what, start string, end string, strip tags bool
	if ((stripos($s,$s_1) !== false) && (stripos($s,$s_2) !== false)) {
		$p=strlen($s_1)+stripos($s,$s_1);
		return ($st == 0) ? substr($s,$p,stripos($s,$s_2,$p)-$p) : strip_tags(substr($s,$p,stripos($s,$s_2,$p)-$p));
	} else {
		return "";
	}
}
function _r($x) { echo $x."\n"; }

$ips=array();
$handle=fopen($argv[1],"r");
while (!feof($handle)) {
	$buf=fgets($handle,4096);
	$x=explode("\n",$buf);
	foreach ($x as $v) {
		if (strpos($v,"Relaying denied") !== false) {
			$ip=_gii($v," [","]",0);
			if (!in_array($ip,$ips))
				$ips[]=$ip;
		}
	}
}

for ($r="",$i=0,$j=count($ips),_r("Found: ".$j." entries, building ban list..."),$ip_tables=file_get_contents($argv[2]);$i < $j;$i++)
	if (strpos($ips[$i],$ip_tables) === false)
		$r.="-A INPUT -s ".$ips[$i]." -j REJECT\n";

if (!empty($r)) {
	file_put_contents("maillog.ban",$r);
	_r("Wrote maillog.ban");
} else {
	_r("No new entries found");
}

..not so good on preg, but it works :P
once you generated the maillog.ban file just paste it on the iptables.

Besides that you may want to tune up your MTA child limit in order to avoid server overloading.

You may also want to keep this:

-A INPUT -p tcp -m tcp --syn -m limit -m state --limit 1/second --limit-burst 5 --state NEW -j ACCEPT
-A INPUT -p tcp -m tcp --syn -m state --state NEW -j REJECT

on for a while, it will ban ips based on their sync packet usage, let’s say that our unhappy script kiddie who owns the botnet starts to ping the server instead, this will avoid server from having resources wasted, but may also cause issues with legit clients.

I also found this article that shows how to disable ping echoing straight on kernel just by adding net.ipv4.icmp_echo_ignore_all = 1 at /etc/sysctl.conf.

Leave a Comment :, , , , , , , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!