Tales from a base64 wordpress hack, part 1: detection

posted in: Tech | 7

So as I mentioned in my previous post, this blog was compromised earlier today, with the nefarious base64() hack. I’m still picking up the pieces, and viewing this as being pushed into finally switching to a new theme (I’ve been thinking about it for a while now).

The good news is that it’s not the end of the world, and if you are feeling adventurous, you can recover your blog from this and probably have most of your data intact still.

At this point, I can post about detection and stopping the bleeding. Hoping to have a followup about better prevention, if I can figure out how they compromised a fully-updated WordPress installation in the first place.


First off, are you in the clear? If the hack was done cleanly and not by some amateur like the idiot that hacked mine, your blog will not show obvious signs of infection. I have read reports that this particular hack only manifests for users using Internet Explorer and on Windows, since those users are most susceptible to whatever malware it’s pointing you to.

This is going to require some scary terminal stuff. Bear with me. I’ll try to make it as painless as possible. If you don’t know what “SSH” means, or have never logged into your server via the Terminal, then find someone who has and ask them to teach you. It’s good to know this stuff.

  1. Log on to your server via SSH (FTP will not work for this)
  2. Navigate to your blog directory
  3. Type this command below
$ grep -R "base64" *.php | awk '{ print $1 }'

What this does is search for instances of the string base64 in all your PHP files of your blog, then shrink it down so that it doesn’t fill up your whole screen. If you see nothing come up, you’re probably ok. If you see anything, it might mean you’re infected (if you see a bunch of things show up, you’re most certainly infected).

Let’s assume you found a couple results. We need to see if they’re infected, so pick a couple at random and inspect them with the cat command.

$ cat thefilename.php

screenshot of terminal

You’re looking for eval(base64_decode(.... in the beginning:

screenshot of terminal

If you see that. You’re most certainly infected. This means several things:

  1. Every PHP file in your blog is infected. EVERY ONE. Trust me. I’ve looked. Just so we’re clear (this applies only to .php files, as far as I can tell):
    1. Every core WordPress file is infected
    2. Every plugin you have installed is infected
    3. Every theme file you have is infected
    4. Some of your uploads directory (and pretty much anything under wp-content/) is likely infected as well.
  2. There is more than likely a “backdoor” on your server right now so that the attacker can sneak back in later.
  3. The attacker may have access to your database and/or web server via credentials it found while crawling your WordPress files. (there are ways to check this)

The last one is particularly scary, but from what I’ve seen so far, they tend to just do URL hacking (hacking around your site by using the backdoor) rather than full on SSH shell logins.

Just to be safe, let’s test. In the shell again (you still have that open, right?):

last -i | grep $(whoami)

Let it run for a couple minutes, or until the dates showing up are a week or so old.

Screenshot of terminal

If you don’t know your IP address, go find it first, then compare that number to the numbers showing up. They should be similar but may not be identical. If your current IP looks like 111.222.333.444 and the IP in the output looks like 111.222.333.434, it’s probably fine. If it looks like 111.233.333.444, that’s potentially bad. You will want to submit a support ticket to your hosting provider immediately and either give them a screenshot or just paste the text into the email.

Beginning to Recover

The process of recovery will take a while. But it’s doable. And you can do it!

For starters, we need to start fresh. This means re-installing WordPress clean. Don’t worry, your data is safe in the database, and we’ll have you back up and running in minutes. I promise.

  1. Navigate to the directory just above where your blog is located (eg. if your blog is in ~/blog/, then navigate to ~/)
  2. Move the directory containing the blog to a backup location that is NOT web accessible. (eg. move ~/blog/ to ~/blog.hacked/)
  3. Create a new directory with whatever your blog was originally called. (eg. create ~/blog/)
  4. You should now have the old installation in a safe place (~/blog.hacked/) and your blog URL should now point to an empty folder. (You can test this right now)


$ cd ~/
$ mv blog blog.hacked
$ mkdir blog

Screenshot of terminal

Now we need to download the most current version of WordPress, unzip it, and copy over our configuration, and then it should be ready to go!

  1. Navigate to the directory where your blog should be contained (not the “hacked” old blog data, the so-fresh-and-so-clean-clean location)
  2. Download the latest WP version:
    wget  http://wordpress.org/latest.zip
  3. Unzip the archive (it will automatically unzip into a “wordpress” subdirectory, this is ok)
    unzip latest.zip 
  4. Move the files in that new folder into the correct place
    mv wordpress/* .
  5. Delete that empty directory now
    rmdir wordpress 


$ cd ~/blog
$ wget http://wordpress.org/latest.zip
$ unzip latest.zip
$ mv wordpress/* .
$ rmdir wordpress

Screenshot of terminal

Restoring wp-config and enhancing security

Do not access your blog via the web just yet. It’s still not ready. We need to tell it where your database is first, which is held in the wp-config.php file — but before we can copy that over, we need to sanitize it and update the security settings.

Use your favorite text editor (you can use pico if you’re new, or vi or emacs if you’re strong like bull) to edit wp-config.php in the old (hacked) installation (I’ll use pico here, though I am normally a burly vi user):

$ pico ~/blog.amhill.net.hacked/wp-config.php

The window will probably fill up with a bunch of familiar-looking garbage. This is all on one line, so all we need to do is delete the first line (press ctrl+K in pico, or dd in vi. I don’t know what to use in emacs). The whole line should disappear, and you should see “WordPress’s config file” as the next line. Be sure that the very first line of the file is

First of all, remember that every single gorrammed PHP file is infected here. The file “index.php”, for example, should only contain the following:

But it probably contains a bunch of other crap. You can clean it out like earlier, if you like, but it will be really time consuming. Really, all we want to do here is salvage your uploads. You’re just going to have to bite the bullet and re-install all of your themes (hope they weren’t heavily modified, or you kept backups!) and all of your plugins. So based on what we’ve seen so far, we know that the attacker corrupted all the PHP files. Chances are, you’ve never uploaded a PHP file in your uploads directory (if you have, that’s risky business!). So do this:

  1. Navigate into the /wp-content/uploads/ directory
  2. Locate all PHP files within this directory by typing the command below
  3. You will probably see one or more files show up; take note of these filenames.
$ find . -name *.php

screenshot of terminal

See that file that showed up on mine in the image above? anettaauroora.php? It will probably have a different name on yours, but that file is bad news. Take a peek inside of it with your favorite editor to see what I mean. This file is different than the other ones we saw — it’s obfuscated in a similar way, but it actually contains a backdoor that the attacker can use to further manipulate files on your server; re-infecting you at a later date, if s/he wants to.

Either delete it, or move it to a safe place (and rename it if you do!) — just get it out of there. Once it (and any of its friends) is out, we can copy the uploads back over. Again, substitute the directories you use on your server here for the ones I’m using.

First, make sure the uploads directory exists in your squeaky-clean wordpress:

$ mkdir ~/blog/wp-content/uploads

Now copy the contents of the hacked uploads folder into the clean one:

$ cp -R ~/blog.amhill.net.hacked/wp-content/uploads/* ~/blog/wp-content/uploads/

That’s it!

 Re-activating the Website

At this point, you should be able to navigate to your blog at its URL and it should work! You may see only a blank page if you were using a non-default theme, but it at least should not give you an error.

Navigate your browser to your admin area, and log in as your admin user, just like normal. First, we’re going to refresh the permalinks:

  1. Click on “Settings” then “Permalinks”.
  2. Click “Save Changes”.

screenshot of wordpress

Next we’re going to force it to use a default theme, for now.

  1. Click on “Appearance”
  2. Click on “Themes”
  3. Pick any of the default themes (eg. twentyeleven) and click “Activate” for that theme

Lastly, we’re going to verify that all plugins are disabled:

  1. Click on “Plugins” and choose “Installed Plugins”
  2. Click the checkbox at the top of the plugins list to select all
  3. Under “Bulk Actions” choose “Deactivate”
  4. Click “Apply” — all plugins should be deactivated now.

screenshot of wordpress dialog

Navigate back to the public-facing side of your blog and verify that it is indeed showing your data, albeit in a very boring and lame way. That’s good, at least we’re stable now.

One final thing. We need to verify that there were no additional users created, and also change the passwords of any existing users.

  1. Click on Users, then All Users
  2. Look for any strange users — there should be a single Administrator account, and any other accounts should be Editors or less. Delete any accounts that look strange, and on the remaining accounts change the passwords.

Further Reading for the Ambitious

If you are feeling salty, I highly recommend running through the Hardening WordPress guide over on the official WordPress codex. These will help tighten down the security even more and hopefully prevent future attacks. In particular, definitely do the file and directory permissions in that article.

Also, my fellow higher-ed-web colleague Chris Wiegman has created a plugin called Better WP Security to help further harden your installation. Not for the faint of heart, though.

I’m going to do some logfile analysis and see if I can identify how the attacker got in, since my WordPress was the most current version at the time of the attack.

7 Responses

  1. Adam

    I fell foul of this little infection last week and this post was a big help in the cleanup. Thanks!

    • Aaron

      Glad I could help!

      I’ve got another post coming up that details how to use git to create easy backups to monitor your installations and quickly restore if you get infected again.

  2. Cynthia

    I’ve been getting hacked with this on a regular basis for the last couple of weeks. UGH. I will be reading your posts, as I figure there’s a darn backdoor but I don’t know what it is. I’m on shared hosting. I’ve been wondering if my host has the backdoor, and maybe I need to change. I’ve run my own server, my own VPS, and now I just want to be lazy and install and run my WordPress blogs. Really don’t want to have to fight with hackers, and I thought going to shared hosting would help!

    • Aaron


      Be sure to check all the parts to this series. They detail the full process I went through to extricate the bad stuff from my site. It is *VERY* resilient and has a lot of redundancy. You have to be super careful and detailed about finding all the pieces.

      Just hope that the jerk didn’t put bad code in your DB — that can be a lot harder to detect. :/