We got a call this weekend from a desperate site owner that had just found out that his site was hacked and hosting malware. He was fairly technical and checked everywhere for it. He even reverted back to an old backup he knew was clean, but the problem persisted.
When he explained the problem to me, I was 99% sure that it was something inserted in the .htaccess file. Well, I was wrong. I checked the site as well and didn’t find anything hidden in the normal places.
I then remember a report from another user and from stopmalvertising.com about some malware being hidden inside the cgi-bin directory.
*Most people forget to check the cgi-bin directory because it is outside the htdocs and not targeted that often.
When we checked that directory we found a php.ini containing:
auto_append_file = “/home/user/USER/cgi-bin/security.cgi
What it does is that it appends the output of this security.cgi file to any PHP script. When we checked this file, this is how it looked like:
function detectBot(){ global $is_human,$stop_agent_detected,$stop_ip_detected,$detected_str; $stop_ips_masks = array( "66\.249\.[6-9][0-9]\.[0-9]+", // Google NetRange: 66.249.64.0 - 66.249.95.255 "74\.125\.[0-9]+\.[0-9]+", // Google NetRange: 74.125.0.0 - 74.125.255.255 "65\.5[2-5]\.[0-9]+\.[0-9]+", // MSN NetRange: 65.52.0.0 - 65.55.255.255 "74\.6\.[0-9]+\.[0-9]+", // Yahoo NetRange: 74.6.0.0 - 74.6.255.255 "67\.195\.[0-9]+\.[0-9]+", // Yahoo#2 NetRange: 67.195.0.0 - 67.195.255.255 "72\.30\.[0-9]+\.[0-9]+", // Yahoo#3 NetRange: 72.30.0.0 - 72.30.255.255 "38\.[0-9]+\.[0-9]+\.[0-9]+", // Cuill: NetRange: 38.0.0.0 - 38.255.255.255 "93\.172\.94\.227", // MacFinder "212\.100\.250\.218", // Wells Search II "71\.165\.223\.134", // Indy Library "70\.91\.180\.25", "65\.93\.62\.242", "74\.193\.246\.129", "213\.144\.15\.38", "195\.92\.229\.2", "70\.50\.189\.191", "218\.28\.88\.99", "165\.160\.2\.20", "89\.122\.224\.230", "66\.230\.175\.124", "218\.18\.174\.27", "65\.33\.87\.94", "67\.210\.111\.241", "81\.135\.175\.70", "64\.69\.34\.134", "89\.149\.253\.169" ); $stop_agents_masks = array("http", "google", "slurp", "msnbot", "bot", "crawler", "spider", "robot", "HttpClient", "curl", "PHP", "Indy Library", "WordPress");
$_SERVER["HTTP_USER_AGENT"] = preg_replace("|User.Agent\:[\s ]?|i", "", @$_SERVER["HTTP_USER_AGENT"]);
$is_human = true; $stop_ip_detected = false; $stop_agent_detected = false; $detected_str = ""; foreach ($stop_ips_masks as $stop_ip_mask) if(eregi("^{$stop_ip_mask}$", defineIP())) { $is_human = false; $stop_ip_detected = true; $detected_str = "by ip"; break; } if($is_human) foreach($stop_agents_masks as $stop_agents_mask) if(eregi($stop_agents_mask, @$_SERVER["HTTP_USER_AGENT"]) !== false){ $is_human = false; $stop_agent_detected = true; $detected_str = "by agent"; break; } if($is_human and !eregi("^[a-zA-Z]{5,}", @$_SERVER["HTTP_USER_AGENT"])) { $is_human = false; $stop_agent_detected = true; $detected_str = "not human agent"; }}function defineIP(){ if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) return $_SERVER["HTTP_X_FORWARDED_FOR"]; else return $_SERVER['REMOTE_ADDR'];}
detectBot();
if(!isset($_COOKIE["cook"]) && $is_human){}
Exactly the same as the counter.cgi reported by stopmalvertising.com
So if you ever have to clean a hacked web site, don’t forget to check the cgi-bin directory and the php.ini file.
As always, if you need help to recover from this attack or need someone to monitor your web site for these issues, visit http://sucuri.net or just send us an email at contact@sucuri.net.