Earlier this week the WP GDPR Compliance plugin was briefly removed from the WordPress.org repository after the discovery of critical security issues impacting its users. In yesterday’s post, we provided some details regarding these issues and illustrated their severity. In the hours since that post was published, our team has continued tracking the adversaries seeking to exploit this new attack vector. Today, we’re sharing the findings of this extended research. This post is technical in nature and will be helpful for network defenders, developers and security researchers.
For details regarding the vulnerability and its scope be sure to read yesterday’s post, Privilege Escalation Flaw In WP GDPR Compliance Plugin Exploited In The Wild, before proceeding.
If you run a WordPress site and use this plugin, you should update to the newest version which fixes the vulnerability, or remove the old version of the plugin. The newest version of WP GDPR Compliance is version 1.4.3.
The data gathered by our malware scans, firewall activity, and site cleaning reports has revealed two primary types of exploit taking place. The first case, identified early in our research and mentioned in yesterday’s post, involves modifying user registration settings. The second case, caught and logged by the new firewall rule for this vulnerability, injects malicious scheduled actions to be executed by WP-Cron. Examples we have seen of both attack types have made use of backdoor scripts named
wp-cache.php, though the contents of these backdoor files differ between the two methods.
Administrator Access via Modified Settings
The most common attempted attacks against this flaw at the time of this writing directly exploit the ability to modify arbitrary settings on affected sites. By enabling new user registration and changing the default role of new users to Administrator, attackers are able to simply create a new privileged user, then log in and take any actions on the newly compromised site.
Interestingly, automated attempts to perform this activity are also reversing the settings modifications being made. The following screenshot contains relevant access log entries for one such attack.
In this log, we first see a GET request to the site’s homepage. This first request is necessary to produce the “ajaxSecurity” nonce required by the plugin to perform AJAX actions. Next, two POST requests are made to
/wp-admin/admin-ajax.php. Data stored in POST bodies is not seen in access logs, however in the course of our research we have been able to acquire samples of this data. The first two AJAX requests contain the following data:
In the first action, we see the attacker enabling the
users_can_register option, which adds functionality to a site’s
wp-login.php page allowing users to create new accounts. Next, the
default_role option is set to ‘administrator’, meaning any new user registered to the site is automatically given full administrative access.
The next items in the access log show the attacker making a POST request to
/wp-login.php?action=register, and the subsequent redirect to the “Registration complete. Please check your email” dialog.
Lastly, two more AJAX requests are made, containing the following instructions:
Here we can see the attacker actually reversing the configuration changes that allowed them to create an administrator account, first by disabling user registration then setting the default user role to “subscriber”. This serves to help prevent other attackers from creating their own administrator accounts, as well as reducing the likelihood that a site’s administrator will notice a problem. It closes the door behind the attacker.
Several hours after the new user is created, the attacker logs in to their new administrator account and can begin installing further backdoors. In our sample cases, we’ve seen attackers uploading a robust PHP webshell in a file named
wp-cache.php. The image below is a screenshot of the shell user interface.
With a file manager, terminal emulator, and PHP eval features, a script like this on a site can allow an attacker to deploy further payloads at will.
Backdoor Installation via Injected Cron
The second type of exploit we’re seeing is less straightforward, and more difficult to identify at a glance. By injecting malicious actions into a site’s WP-Cron schedule, these attackers are able to install a persistent backdoor that can replace itself if removed. While a variety of malicious actions can be stored and executed via WP-Cron, the cases we have seen so far rely on the presence of another popular WordPress plugin, WooCommerce.
The following line contains a portion of an AJAX request body blocked by the Wordfence firewall for attempting to insert a malicious WP-Cron task:
This cron task attempts to use WooCommerce’s built-in
woocommerce_plugin_background_installer action to install the 2MB Autocode plugin, which allows the injection of arbitrary PHP code into all posts on a site. The code to be injected is stored by 2MB Autocode as an option in the database, so the next step is to modify that setting using the same vulnerability:
[malicious_php] placeholder in the above example contains a PHP backdoor script which performs the following actions in sequence:
- Receive encoded input stored in the attacker’s request as an “HTTP_X_AUTH” header, which declares the locations used in the following steps.
- Make a request to http://pornmam[.]com/wp.php
- Decode the response and save the resulting PHP backdoor as
- Include the core file
- Deactivate and delete the 2MB Autocode plugin
- Clear the WP-Cron event associated with the attack
- Delete the
2mb_autocode_topstringoption containing this code.
While the backdoor script seen in these cases shares the name
wp-cache.php with other methods, the contents are much different. Instead of a self-contained web shell, this script contains some decoding functions and some execution syntax, but none of the executed payload is stored in the file. Instead, the payload to be decoded and executed is stored as a POST variable or in a cookie.
Without any captured requests to this script, we can’t know exactly what the intended behavior is. However, given the nature of the script and its eventual call to
eval(), it’s to be expected that any arbitrary code can be executed by way of this backdoor.
In most infections, there will be one or more active methods in place to bring value of some form to the attacker. Whether an infected site is serving spam emails, hosting a phishing scam, or any other direct or indirect monetization, there’s often a clear goal identified as part of the triage process. However, despite the rapid occurrence of these identified cases, so far our research has only turned up backdoor scripts on sites impacted by this issue. No “end-stage” payloads intended to directly benefit an attacker have yet been associated with these attacks.
This behavior can mean a number of different things. It’s possible that these attackers are stockpiling infected hosts to be packaged and sold wholesale to another actor who has their own intentions. There’s also the chance that these attackers do have their own goals in mind, but haven’t launched that phase of the attack yet. In either case, sites impacted by these attacks should immediately work to identify and remove any backdoors present.
The following section contains a series of IOCs (Indicators of Compromise) that can be used to assist in identifying and triaging cases similar to the ones in this report. Be advised that any common methods may be changed by the malicious actor at any time, especially as more attackers begin exploiting this vulnerability.
Most Prevalent Attacking IP Addresses
- Admin Creation Method:
- Cron Injection Method
Outbound Domains Accessed
- Admin Creation Method Backdoor
- MD5: b6eba59622630b18235ba2d0ce4fcb65
- SHA1: 577293e035cce3083f2fc68f684e014bf100faf3
- Cron Injection Method Backdoor
- MD5: c62180f0d626d92e29e83778605dd8be
- SHA1: 83d9688605a948943b05df5c548bea6e1a7fe8da
- The presence of unauthorized accounts in your site’s users table, including but not limited to the following examples:
- An entry in your site’s options table with an option_name starting with
2mb_autocode(If not used intentionally)
- The option
default_roleset to anything other than “subscriber” unless directly intentional.
- The option
- 2MB Autocode (If not used intentionally)
It is our hope that the details revealed by this research can be used to assist others in the security sphere to track and prevent these exploits. However, the attacks first seen following an impactful security disclosure can be considerably different than those seen in the weeks and months after. Given the scope of the vulnerability in question, it’s likely that more unique and sophisticated attack methods will be seen in the wild before long.
As always, we stress the importance of performing regular plugin updates to prevent these attacks from succeeding in the first place. The Wordfence plugin notifies administrators of outdated plugins automatically in order to help facilitate a quick response to potential vulnerabilities. In addition, the Wordfence Threat Intelligence team has released firewall rules and malware signatures to our premium customers in real-time to protect against this exploit and detect the indicators of compromise associated with the attack.
Written by Mikey Veenstra with contributions from Stephen Rees-Carter and Marco Wotschka. Edited by Mark Maunder.