WordPress Pharma Hack

A few weeks ago I was walking to my car and was copied on an email from the director of the IT department for the UVa Library:

It appears that website redacted has been commandeered…hacked.. Beware if you use windows as there is a malware service running….

Just the kind of email you love to get! By the time I got home (takes me about an hour and a half), there had been a flurry of emails between the company that had a support contract for the site, and various people who were reacting. By the time I actually had a chance to sit down, the site URL had redirected the site to UVa’s home page as a stop-gap measure to not expose the site’s users to malware.

I started taking a look at what had happened and apparently the hackers had exploited WordPress by posting a comment in such a way that WordPress wrote a file to the filesystem, when then injected code (in base64) everywhere it found the string ‘<?php‘. Ah yes, pharma hack. It would be brilliant if it weren’t so diabolical. Some clarification on what is actually going on here. There are a few levels of compromise that systems administrators worry about; web defacement and server compromise. The latter is really serious, but outward facing defacement is really really the Internet equivalent of someone tagging your fence. What these hacks are designed to do is abscond with your Internet search results. This is quite a different attack vector than say brute-forcing passwords on a WordPress site. If you know a little about what you’re doing, this is actually pretty straight forward. In fact, you can script these things pretty easily; this example was written by a hacker over a weekend:

With hacks like this, attackers usually have much darker intentions (e.g. there’s a high probability you use the same password for Work/Facebook/Twitter/Google as you do for your WordPress).

Let me take a second here to briefly pause say that I’m not trying to scare anyone in to shutting down their WordPress site. I will, however, say that annoyances like these go along with the maintaining a WordPress site; sooner or later, you will have to deal with with the fact that some script kiddy found an attack vector to leverage your WordPress site for their purposes. WordPress a great tool, lots of people use it, but there are a lot of moving parts in the platform, and there are always ‘issues’ that pop up (issues in PHP itself, plugins, themes, etc.). If you are really concerned about this, you may like to take a look at an alternative like Jekyll; it’s much harder to inject content in to static files than it is a dynamic framework based on PHP (or Ruby, Python, etc.).

Getting back to what was going on with our compromised site, I considered what I saw as a “those damn kids” attack, and not actually commandeering the site . I then set about cleaning up the WordPress installation to move it to a server environment that I controlled and could make sure that the server had some elements to make this style of attack just a little harder to do.

As a former systems administrator who used to actually read the daily security bulletins put out by Windows, the various Linux distributions, my approach to these recovery is a little more dramatic than what various blogs suggest to clean up. If we’re using the tagging-the-fence metaphor, these posts show you how to paint over the graffiti. Since hackers can be clever little buggers, and I’ve found on at least one occasion that the hackers left something crazy and ‘simple’ to fix to mask what they were really doing (that time it was setting up a store-and-forward server for pornography), I adopted the equivalent of burning down the fence and building a new one when I see this happen.

Caveat: I spend almost all day in a terminal, so the code I show to back-up and massage the code is going to use the terminal. If this really isn’t your cup-of-tea, there are generally GUI tools that will do the same (e.g. PHPMyAdmin) which, if you are on a hosted environment, most likely this tool is there. I just say this in case you are really not comfortable (or have shell access to the server) that you can use the same techniques, but use the tools available.

The basic workflow I was using was to get all the data out the MySQL server, and the WordPress theme that was ‘infected’ on to my local machine, download a fresh version of WordPress, import the WordPress data, reinstall any needed plugins, and the theme the site was using. For the particular hack in question, I actually had remote access (on a non-default port) to the MySQL server, so I could actually pull the data directly from the machine to my computer (as a gist)

mysqldump -h [mysql server] --port=[port number] -u [username] -p [database name] | gzip -c | cat ~/Desktop/`date +%Y-%m-%d-%T`.sql.gz

If you aren’t comfortable with a Terminal commands, this can be a little scary. Basically this is a set of chained commands (Pipes and Redirects) that dump out the entire database (mysqldump), compress the output (gzip), and write the compressed output to a file on my Desktop with a current timestamp (cat). As an example, my output file with all of the WordPress data was named 2012-02-28:20:40:02.sql.gz.

Now to download the latest version of WordPress and set up a database named hack and inject the data from the remote server in to the newly created database.


gunzip ~/Desktop/2012-02-28:20:40:02.sql.gz

mkdir -p ~/public_html/hack && cd ~/public_html/hack

curl -O http://wordpress.org/latest.tar.gz

tar xvf latest.tar.gz

mysqladmin create hacked

mysql -u [local mysql root] -p hacked < ~/Desktop/2012-02-28:20:40:02.sql

There is a lot here, and worth explaining briefly. These commands

  1. Decompress the SQL file from the server that sits on the Desktop;
  2. Create a new directory in the user’s public_html directory named hack (creating public_html/hack if it does not already exist);
  3. Changes the terminal in to the newly created directory (you can chain multiple commands together with the && operator)
  4. Downloads the latest version of WordPress with cURL;
  5. Creates a new database on you local machine named “hacked” using the mysqladmin command;
  6. Connects to the local MySQL server and inserts the contents of the SQL file generated earlier

If you are running some other type of system, you may need to change the location of where you put WordPress, but the rest should be pretty much the same. You can now log on to the WordPress system locally (e.g. http://localhost/~wsg4w/hacked/wordpress/wp-admin/) and reinstall your plugins. The one thing that will take a little bit of effort would be cleaning up the theme you are using if  you have made any significant changes to a theme (and not it in a revision control system), you will need to clean out the hack additions.

find ./ -name "*.php" -type f |  xargs sed -i 's#<?php /\*\*/ eval(base64_decode("aWY.*?>##g' 2>&1
find ./ -name "*.php" -type f |  xargs sed -i '/./,$!d' 2>&1

These lines use the find command to find PHP files and then use sed to remove any of the crazy base64_decode from your files.  If you don’t already have your theme in an SCM, this is a good time. Github is a good option, but if you want a private repository, you can also check out Bitbucket. This will make things easier in the future…

After you have everything cleaned up on your local machine, it’s time to push it back up to the server. There are a few ways to go about doing this. If I’m doing this on a regular basis, I typically use rsync, but if it’s a one time deal, I use scp. If you only have FTP access, I highly recommend the lftp utility.


cd ~/public_html/

scp -R hacked username@servername:~/path/to/wordpress/install

This should put things back on your server to a clean state for your WordPress site. You may want to also make a backup of the file contents occasionally too. This is a script I use to backup servers, modified to look at WordPress:


#! /bin/bash
cd path/to/wordpress
tar cvpzf backup.tgz --exclude=/backup.tgz .

Postmortem

Having a WordPress site compromised can be kind of embarrassing. There are a lot of factors that can go in to the attack vectors that can affect your site. Even if  you regularly update the versions of WordPress, the plugins, etc., you can find yourself in a situation, especially on a shared server, where someone you don’t even know about has left their site open to an attack that compromises your site. There really isn’t a good way to keep this from happening, but what you can do is make it harder for these types of attacks to success. Here are some general guidelines to keeping your WordPress site Cialis free:

  • Keep WordPress updated;
  • Disable plugins you aren’t using; better yet, delete them off the server;
  • Keep your theme in an SCM;
  • Disable comments (this is one of the most common attack vectors); if you really want them, you can also use IntenseDebates or Disqus
  • Set your file permissions properly;

If this is happening to you more than you’d like, I would also suggest taking a look at some of the static web generators. We use jekyll for the Praxis webiste; SecondCrack by Maro Arment if you like PHP, and Growl if you prefer Python.

3 comments on “WordPress Pharma Hack

  1. Hi Evan,

    I think it really comes down to workflow. A lot of scholars are most comfortable writing in Word, then doing other things with the text. I have spent many hours cleaning out all the Word HTML formatting from many-a-CMS to ensure that the text looks correct when rendered. A lot of times, shifting this workflow in to a text-editor is just too disruptive an activity to make this shift in their workflow worth doing on a regular basis.

    That said, other than the funky syntax for anchors, Markdown is really quite straight-forward and easy to read. A full-on jekyll implementation without some hand-holding may be a bit much and would probably need some hand-holding the first few times they add a new post or page (octopress has a lot of really nice helpers for new posts, pages, etc.). I have a set of rake tasks on the Praxis site (see the source on github) for adding useful content (and optimizing its performance), but this does require having Ruby (and a few gems) on the system. The general mind shift that needs to be made from a GUI environment to text-based tools like Markdown can be quite high, and for many, that shift in workflow is outside their interests. There are a few tools to help get over this hump (Marked looks pretty nifty), but as long as you can help design a workflow that makes sense, most people can pick it up (and even enjoy) Markdown.

    Wayne

    • Putting this in term of workflow is a fantastic way of think of it–I will remember that for the future. There seems to be a group of people who gave up doing much for the Web when CSS separated content from style. I wonder if Markdown might be easier for them the incorporate into how they write. Or, perhaps I am just selfish and want to set this up for my own sake… Thanks for the reply and the post! -Evan

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Archives