I'm a huge fan of security. I spend many a weekend experimenting with new encryption techniques, hash algorithms, and security protocols.

As a result, I also come across several different server exploits in the wild. PHP hacks, [cci].htaccess[/cci] hacks, JavaScript injection, etc. I once even saw a server hacked through a corrupt PNG image that installed a PHP console when it was loaded.

To a new developer, is is all pretty scary stuff. Here's an example of an exploit I came across last week - and how to both prevent and recover from it.

The Exploit

A friend alerted the world via Twitter to an odd issue posted in the WordPress forums.  A specific site was being redirected to a Russian website, but only if you visited with a mobile device.

I loaded the website both on my desktop and Android phone to see the difference - sure enough, the page loaded fine on the PC and the phone got Russian spam.

Next, I turned to Fiddler to see what else I could diagnose.

With a desktop user agent, everything came across the wire just fine.  Substituting a mobile user agent string - or any string containing the words "Android" or "iPhone" yielded somewhat different results:

There is now a coded block of JavaScript injected above the opening [cci][/cci] tag.  When decoded, this script writes a new script tag to the browser.  This script tag loads a remote URL that forces a redirect from the site you're on to a site of the hacker's choosing.

I followed up with my results in the forums, and mentioned them on Twitter.  That's when Sucuri Security joined the conversation and confirmed this is a known malware bug.


How To Fix It

Most known bugs also have known fixes - in this case, the exploit was a poorly secured [cci].htaccess[/cci] file that loads the extra script based on the user agent passed in the request.  Flushing the file is usually enough to remove it.

But that's never enough for me.

Once an attacker has access to your system, they'll likely install more than one back door.  Yes, [cci].htaccess[/cci] is obviously corrupt.  But there might be code lurking in a random PHP or JavaScript file on the server, just waiting to re-infect your site.

The best way to recover a WordPress site is to:

  1. Change your FTP password (this might be the hacker's original way in)
  2. Change your MySQL password (keep your database secure - also change this in [cci]wp-config.php[/cci])
  3. Check your [cci]wp-config.php[/cci] file line by line to make sure it's clean. Compare it to the [cci]wp-config-sample.php[/cci] file from a fresh download of WordPress to be sure.
  4. Reinstall WordPress. This means deleting everythingexcept for your configuration file, themes, and plugins
    • Ideally, you'll also remove all themes and plugins and reinstall them from clean sources as well. If you can't, make sure you go through each line of every PHP file and make sure there isn't anything hinky going on there.[ref]Yes, I did just use the word hinky in a professional post. Get over it. :-)[/ref]
  5. Go through your entire [cci]/uploads[/cci] directoy and make sure no rogue files or scripts are lying around
  6. Restore your database from the most recent (clean) backup
    • If you don't have a backup, get ready for a long night of going through data tables manually to be sure there isn't anything hiding in the database
    • And really, why don't you have an automated backup? Set one up now while you're at it!
  7. Ask another developer to double check your work to be sure you haven't missed anything.

In a pinch, you can also hire the experts at Sucuri to clean things up for you. They know what they're doing and have likely cleaned up this specific hack already.

Don't Get Hacked in the First Place

There's quite a bit you can do to harden your site before it gets hacked. Here are just a few quick recommendations:

  • Change your WordPress admin password regularly. And don't use the same password anywhere else.
  • Use different passwords and logins for WordPress admin, FTP, and MySQL.
  • If you're running your own VPS, don't do anything as root.
  • If you can, turn off FTP altogether. If you absolutely need it, consider SFTP instead.
  • Check your system access logs for weirdness regularly.
  • Make routine backups of your filesystem and database so you can recover quickly from problems.
  • Consider signing up with a malware monitoring service - Sucuri happens to offer this, too.