Recently, our team uncovered a particularly sneaky piece of malware tucked away in a place many WordPress users don’t even know exists: the mu-plugins folder. In fact, back in March, we saw a similar trend with hidden malware in this very directory, as detailed in our post Hidden Malware Strikes Again: MU-Plugins Under Attack. This current infection was designed to be quiet, persistent, and very hard to spot.
./wp-content/mu-plugins/wp-index.php
For those unfamiliar, mu-plugins stands for “must-use plugins.” These are special WordPress plugins that are automatically activated and cannot be deactivated from the WordPress admin panel.
This script acts as a loader, silently fetching a remote payload from a ROT13-obfuscated URL and storing it in the database. The fetched content is then temporarily written to disk and executed. This backdoor gives the attacker persistent access to the site and the ability to run any PHP code remotely.
What is ROT13 Obfuscation?
ROT13 is a simple obfuscation method that shifts each letter 13 places in the alphabet. Its legitimate use cases consist of things like obscuring spoiler text, jokes, or puzzle answers in online discussions without true encryption. It’s also used to hide text like URLs or code in malware. ROT13 is reversible and provides no real security.
Here’s a simple ROT13 example:
“HelloWorld” becomes “UryybJbeyq”
Each letter is rotated 13 places in the alphabet (A↔N, B↔O, C↔P, etc.).
Indicator of Compromise
The attacker’s loader uses WordPress functions to execute its payload and achieve stealth. Here are some Indicators of Compromise (IoCs):
- Malicious file:
wp-content/mu-plugins/wp-index.php
- ROT13-encoded URL:
str_rot13('uggcf://1870l4ee4l3q1x757673d.klm/peba.cuc')
- Decodes to:
hxxps://1870y4rr4y3d1k757673q[.]xyz/cron.php
- Database option key used:
_hdra_core
- Temporary payload path:
.sess-[hash].php
inside the uploads directory - Hidden admin user:
officialwp
These indicators are critical for identifying if your WordPress site has been infected.
Analysis of the Malware
The Loader in wp-index.php
The malicious file wp-index.php located in the mu-plugins directory acts as the main entry point for this malware. Being in the mu-plugin directory, it is automatically loaded by WordPress and cannot be disabled via the admin dashboard. This is how the attacker achieves persistence.
The code begins by decoding a ROT13-obfuscated URL to access the remote payload:
Once fetched, the payload is base64-encoded. The script checks whether the content is valid base64 before proceeding:
The payload is saved in the WordPress options table under _hdra_core, providing a stealthy storage location that avoids filesystem detection. The script then decodes and executes the payload dynamically:
The payload is included and then deleted immediately, leaving little to no trace behind.
The Remote Payload at cron.php
When we decoded the base64 payload from hxxps://1870y4rr4y3d1k757673q[.]xyz/cron.php, we found a complex malware framework.
We found a hidden file manager injected into the theme directory as pricing-table-3.php. It supports browsing, uploading, and deleting files. The access is gated using a custom HTTP header token:
The user ‘officialwp’ is created and granted administrator rights.
The attacker downloads a remote plugin file from the following rot13-encoded URL (wp-bot-protect.php), stores it locally, and force-activates it. This plugin also helps reinstate the infection if deleted.
This encoded URL decodes to: hxxps://1870y4rr4y3d1k757673q[.]xyz/shp
Alarmingly, this malware also includes a function to change the passwords of several common admin usernames (including admin, root, wpsupport, and even its own officialwp user) to a default password set by the attacker.
This is a way for the attacker to regain access if the legitimate admin changes their password, or to lock out other admins.
Impact of the Malware
The attackers gain full administrator access and a persistent backdoor, allowing them to do anything on the site, from installing more malware to defacing it. Its ability to hide its user, clean up temporary files, embed itself in multiple locations, and hide security plugins makes it incredibly difficult for website owners to detect and remove.
The remote command execution and content injection features mean the attackers can change the malware’s behavior.
With admin access, attackers could potentially steal sensitive user data, install ransomware, or use your site to launch attacks against other websites.
Prevention Tips
- Update WordPress, themes, and plugins regularly. These updates fix security holes attackers love to exploit.
- Only get themes and plugins from trusted places like WordPress.org or well-known developers.
- Use unique, strong passwords for all accounts (WordPress, database, FTP, hosting). Turn on Two-Factor Authentication (2FA) for extra security, especially for admins.
- Audit theme and plugin files.
- Set file permissions correctly and disable file editing in wp-config.php:
define('DISALLOW_FILE_EDIT', true);
Final thoughts
This example of a WordPress backdoor in mu-plugins highlights the constant evolution of online threats. By hiding code in MU-Plugins and storing payloads in the database, the attackers bypass typical security scans and maintain access even after cleanup attempts.
It’s essential to remain vigilant, monitor for unauthorized users, and scan all parts of your site, not just the theme and plugin folders.
For those affected, Sucuri offers professional malware cleanup and ongoing monitoring to ensure threats like these are identified and eradicated quickly.