So I got hacked: How to recover and prevent.

From the and-now-to-something-completely-different dept. Yes, this article has got nothing to do with RES technology, as this is my account of how what can happen if you don’t take precautions to protect your WordPress blog, how it can ruin your day, what to do and how to prevent it from happening again.

I do recognize that there are varying degrees of attacks from the occasional comment spam, over the spamlink hacking that I’ve been dealing with, to a complete site takeover/takedown. Spending two sleepless nights learning the in’s and out’s of WordPress security, wasn’t my idea of fun, so in order to spare other fellow RES Community bloggers from having to learn from scratch, here’s my experiences, which you hopefully can benefit from before it’s too late:


Now, it all started when one of my blogging mates drew my attention to the fact that Google had blacklisted one of the pages on my blog. If accessing this page through Chrome or Firefox, you would get this lovely number, as shown on the right. It was clear that something indeed was quite rotten in the state of Denmark.


Damage overview

To better understand the warning that Google was throwing, the first thing to do, if you haven’t already, is to sign up for the Google Webmaster tools. If I’d bothered to sign up for this service before, Google would have notified me immediatly as they look for spooky code and malware when their Bots are crawling all over your site anyways. If you haven’t worked with Webmaster tools before, it requires 2 things

  • You need a google account (sign up for one, if you haven’t got one already)
  • Once signed up and signed in to Webmaster tools, you will need to prove that you actually own/administer the site you.

The second item is done relatively easy, as Google offers several methods of proving your ownership. Personally, I find the easiest way is to upload a small file via FTP to the / root of the  website. Once that’s taken care of, the website is linked to your account and now you can see the messages which otherwise would have been sent to you when something happened. What we are really after is figure out what’s going on, why the Googlebot vomited dayglo over the page in question.


Cleaning up the mess

The Webmaster tool page offers a Labs section, where you can ask a GoogleBot to pull down the page as it sees it. This may reveal some particular nastyness which you otherwise might not have discovered: Hidden Spam Links. Besides all the html that generates your usual website, you’ll see a block of links that does not not belong there. These spam links serve the nefarious purpose of ranking up whatever lame sites so hopefully Google will bump them up in search results.

Here is an exerpt of some of the stuff that was injected into the site’s html code. The next thing is to figure out how it got there in the first place. One thing is for sure, it’s not static as searching through the site reveals nothing. Googeling around, it turns out that a popular method of infection is modifying Theme files.

There are several good WordPress plugins available to deal with this problem. The two plugins that really saved my behind was Exploit Scanner and Antivirus for WordPress. Both are written to scan .PHP files to look for infections. While AV4WP only scans theme files it notifies you via email if something spooky happens later. It is my understanding that theme files are prone to exploits especially. Exploit Scanner is more thorough and scans ALL files on your site.

Using Exploit Scanner, I found about 15 .php files which were infected. The telltale sign was was Base64 encrypted content in the top of the files. What this means in plain english is that hackers often obfuscate what they do so it becomes harder for the uninitiated to figure out what’s going on. Fortunatly when it comes to WordPress this is a red alert. Something that shouldn’t normaly be there. An exception to this is for example plugins with embedded graphics such as icons. You will however typically see code references to icon data around it if that’s the case.

What I found was the above block, embedded in the top of the infected files (don’t worry, it’s a JPEG, so it’s totally harmless here). I used the built-in wordpress  plugin editor to open the affected files and toss out the malicious code. Be carefull when you edit the php files that you leave a line with a <?php begin header at the top. If you don’t you can royally screw up your entire wordpresss site, especially if the file you’re editing is wp-config.php


What killed the cat

Of course I later got curious, and wanted to figure out what the above did. The easiest thing is to run it through a Base64 decoder. There are plenty of these on the net. I used this one and found out what the code above contained. I’ve blanked out full the path to the file as I don’t want to invite any additional attempts to exploit that path, even though I’ve locked it down.

Obviously the style.css.php file was the culprit, and sure enough when opening it was chokefull of more Base64 code. Along side it in the same folders there were several files which contained all the spam URL’s + much more. I downloaded a copy to my local rig and promptly nuked the files from the webserver. For your amusement I’ve included an archive with the files so you can check them out yourself.  The style.css.php file seems to be the heart of this infection. In fact it was double Base64 encrypted and lo and behold, more encrypted code inside. This was however encoded differently so I started googling the first line ‘function FF97A1D7A5B771B21D423C3A9D78408C’. Following threads in other forums, here, and here it seems likely that this is a rather old exploit.


Validating the cleanup

After removing the Base64 entries from all affected files and the target folder they were all pointing at, it was time to tell Google to check the site again. This is an automated process and if things go well, the Malware warning in Firefox and Chrome go away by themselves. Depending on how busy that the Googlebots are, it can take up to 24 hours before this takes effect. What I did was the following:

  • Logged into Google Webmaster Tools again and went to Labs | Fetch as Googlebot.
  • Request a page which was known to be infected previously.
  • Checked that no spamlinks were injected into the code
  • If all of the above checks out, go to the Diagnostics | Malware section and use the link found there to Request a Review.

After a day or so at most, the safety blocks on your pages should be lifted, and you’re back in business.


Cause and prevention

Now, the important question remains. How the heck did this happen in the first place and how does one prevent it from happening in the future.  I believe the hacker in my case exploited a vunerability in SMF (Simple Machines Forums) which was still sitting dormant on my site. For a long time I’ve redirected to the RESug Forums, but the old SMF engine had just been sitting around forgotten, waiting to be tinkered with. Yup. My bad. SMF uninstalled. Second, I’ve done some preventive hardening to hopefully ensure that this doesn’t happen again. The last section belows covers some of the steps I’ve taken to tighten things up a bit:

Backing up your wordpress database. There are several nice plugins out there to help you create a full backup of the MySQL database that powers your WordPress engine. This is a really good step to take, both as a preventive measure, but also if you like me like to tinker with stuff. You really want to have a backup of your DB before you proceed further. Online Backup for WordPress is one such plugin, which I’ve used since day one. It can mail you a copy of the backup as well as store an encrypted copy at a remote storage facility, where they offer 50 megs for free. Mine’s only 23 megs after 2 years of operation, but it of course depends on what kind of blog and what other plugins you’re using.

Secure your Admin account: Rename the Admin account for your wordpress installation. This is target numero uno to secure. If somebody gets their hands on that one, it’s game over, man. So better deal with it now.

  1. You need to access the MySQL database. To do this you need the equivalent of a SQLadmin tool. You may have an app called phpMyAdmin in your Cpanel from your hosting provider. If not you can just download one as a plugin for WordPress, called Adminer. I find this quite nifty to have around actually, as I discovered I had some old and gone plugins that left orphaned tables behind. But that’s another matter.
  2. Using this tool (rtfm) open the table called wp_users.
  3. Make sure that only Admin and any other users which you recognize are in here. If you discover bogus user names, make sure you kick them out immediatly.
  4. When you change the admin name to something else, be sure you’ve noted it down and type it in correctly, as you will get kicked out of WordPress the moment the record is commited. Your password will remain the  same.
  5. Login again with the new admin name and you’re good.

Find some security plugins that make sense. Again, this depends on what kind of blog you’re running but essentially you should protect yourself from commentspam, have something in place to scan your site for nasties and generally button things down. This is a list of some of the plugins I use to make sure things run more smooth

Note that you can search for the plugin names above from within your Plugin|Add New page. In addition, I’d suggest to read the article found here, where 20 good security plugins are reviewed in detail

Get some more advice: After seaching a bit, I came across several good sites offering recommendations on what to do to lock down your WordPress site. I suggest you read the articles found here and here. There are many more pages like these out there, but make sure you read through the advice and implement what is necessary for you.


AC (Theme Authenticity Checker)

No Comments

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Comments are welcome as always. Just do the math below. * Time limit is exhausted. Please reload the CAPTCHA.