Last night, a hacker successfully penetrated one of the WordPress sites I own. I use a WordPress plugin called Word Fence that notifies me whenever anyone with administrator access logs in to one of my sites, so I responded and kicked the attacker out within eight minutes. Approximately fifteen minutes later, an attacker from the same IP address logged in to another WordPress site I run. I kicked him out of that site a few minutes later.
WordPress attackers often modify core WordPress files to install back doors, so I downloaded the contents of both sites, then did a nuke-and-pave with a new known-good WordPress install and moved the database to a different location.
I am still analyzing the attack, but there are a number of factors that have raised my suspicion that this may be a novel zero-day attack, not the least of which is the attacker gained access to both sites on the first login attempt without brute-forcing an administrator password (and yes, I use very robust passwords). Furthermore, the attacker logged in to an account named "admin," and I do not create WordPress administrator accounts with that name--I always use different names for the admin accounts.
I've done a first pass forensic analysis of the attack. These are the characteristics I observed in both attacks:
- The first thing the attacker does is create several new administrator accounts. These accounts have names such as "administrator;" "admin;" "admin" followed by a random two or three digit number (such as "admin52"); and "root."
- The attacker then creates new directories in the /plugins directory located in /wp-content. These directories are named "research_plugin_" followed by a random string of letters and numbers, such as "research_plugin_2hAs".
- Next, the attacker uploads malicious PHP files into these "research_plugin" directories. The PHP files are named "research_plugin.php". Their content is located under the cut below.
(Note that the comments in the header are merely the stock comments at the beginning of the sample WordPress plugin template; they do not indicate that this code is written by WordPress or is an official WordPress plugin.)
This code looks for an HTTP POST request with a POST variable named "2hAs." The code searches for POST data with a name matching the random string of letters and numbers appended to the folder name (for example, a file uploaded to a folder named "research_plugin_6Ghq" will respond to an HTTP POST variable named "6Ghq").
If it sees it, it will decode the POST data and execute it. Effectively, this gives the attacker the ability to run code of their choosing on the hacked site.
The attacker may also attempt to modify files in the Themes directory, and will create a new, empty folder in the /wp-content/uploads directory. I don't know what changes the attacker attempts to make to the Themes files or whether the attacker attempts to upload to the /uploads directory, because in both cases I kicked the attacker out of the sites before he had finished.
As soon as I'd knocked the attacker offline, nuked the sites, moved the database to a different location, and reloaded the sites with known-good backups, I turned to mitigating the attack.
It's a bit scary that the attacker got in to two sites with two different strong passwords on the first try, on fully updated sites, using an admin account that didn't exist. That rings "zero-day" alarm bells in my head.
The attacks originated from two different IP addresses, one in Russia and one in France, both of which have now been firewalled:
The first thing I did upon rebuilding the affected sites was installed a WordPress plugin that moves the standard Wordpress login URL to a different location. And, sure enough, within minutes, I saw access attempts at the standard WordPress login URL, /wp-login.php.
If you run a Wordpress site, and I know a lot of folks reading this do, I strongly urge you to take the following actions:
- Log on to your site and look for administrator users who should not be there. Check for users named "root;" "administrator;" and "admin" followed by a number. If you did not set up an account named "admin," make sure you don't see one there.
- Make sure you are using extremely robust passwords on all admin accounts.
- Using an FTP program, look in your Plugins directory for anything that shouldn't be there, including any files or folders named "research_plugin" or any variant thereof. Compare what's in your Plugins folder to the plugins listed in the Plugins menu of the WordPress dashboard. If you see anything in the Plugins folder that isn't listed in your plugins menu, delete it.
- Make sure everything is fully up to date and automatic updates are turned on. If you run multiple WordPress sites, I highly recommend the free InfiniteWP software, which will notify you of any needed updates by email and give you a single control panel where you can keep all your WordPress sites up to date with one click.
- Install the free WordPress plugins WordFence and WPS Hide Login. WordFence is a security plugin that will monitor for and block hack attacks and notify you whenever an administrator logs in. WPS Hide Login lets you create a new URL, such as /mysecretaccesspage, where you must go in order to log in. This will block brute-force hack attacks and attacks based on login exploits.
If you discover you've been hacked, I would love to hear from you. Please leave a comment below.