Users of Google Reader, gulker.com followers were complaining that my RSS feed had become a torrent of spam. Somehow, a hacker (or more likely, his ‘bot) was able to penetrate both my WordPress MySQL database and the plugins directory on my host server. I was curious why the spam only showed up in Google Reader, and why I never saw it: it turns out the hack, which runs on the fly whenever the RSS feed is called, blocks itself from running whenever the request comes from the host’s IP or a reader other than Google’s. So my readers see the crud, and I just see my feed, thinking problem must lie elsewhere. Someone has way too much time on their hands.
I’m christening this the Google Reader Backward Hack’, because the code is written into the wp_options table backwards where it just looks like garbage – not executable code. There is a small amount of forward-reading PHP distributed throughout the ‘garbage’ code, where it’s not obvious to the unaided eye. My guess is that a call to the options table (not sure exactly how this works yet) runs the forward-facing code which, in turn, reads the long stream of backward code. The backward code runs and writes a hidden file (name starts with a period, rendering it invisible on UNIX-based and some other OSes) to the WordPress plug-ins folder where it then runs as a WordPress plugin (which probably won’t show up on your WP Plugins activation page). Whenever Google Reader calls the RSS feed on an IP address other than the host’s, the code returns a torrent of spam from somewhere in the hacker botnet.
My recipe for cleaning out the backward hack (with thanks to Chris Merlo, Jim Goldstein, Scott Loftesness and some anonymous posters over at Google Reader discussion):
- Back up your WordPress db, plugins folder and anything else you value.
- Search all of the folders and subfolders in your WordPress Plugins folder for files that begin with a period (e.g. .akismet.cache.php, .licence.cache.php) – make a copy of these to your local machine, then delete them. Most WP plugins apparently do not require hidden files.
- Using phpMyAdmin (your host may offer it on their server) log in to your MySQL database and search in the wp_options table for entries named like this – rss_f541b3abd05e7962fcab37737f40fad8 – there will probably be several files named rss_ with a long random string. Most of these files look like regular PHP code. One table entry will contain a very large chunck of ‘garbage’. One end of the garbage may be marked with this string: edoced_46esab (lave’;s:150 On my system the garbage was at the beginning of the file and ended at ‘edoced_46esab(lave’;s:150.’
- Delete the garbage code and save the table.
- You should probably disable user registration if it’s on, delete any suspicious users, and change your WordPress db username and passwords and update your wordpress.config.php file. You should also follow all the WordPress security recommedations (e.g. changing AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, and ‘NONCE_KEYfrom their defaults)
That did the trick on my system. Best of luck to all…