Recovering from a WordPress Spam Injection

I should have been relaxing and working on an inspirational side project, but instead spent much of Thanksgiving weekend trying to eliminate a senseless spam injection on a WordPress (wp) site.

I was frustrated, to say the least, by how difficult it was to find a solution. There were many months-old unanswered pleas on the wp forums.

I cannot figure out the hackers’ revenue model. Repeatedly over the course of two weeks, my husband’s site became unreliable to access. The symptoms were varied, including:

  1. The site never loads
  2. Loading stalls and then redirects to a virus scanner software
  3. The site is redirected to a Harry Potter related website
  4. The site takes a long time to load and the source code shows approximately 30 links to enhancement-related drugs or movies. Each time the links are to a new single site, where the drug or movie is a variable at the end of the URL. The inserted code has a style of display:none; so it’s not visible to the naked eye. Nevertheless, it is available to search bots.

For the first few days, the injection would take place in the form of #4 (invisible links) at the same time of day. Replacing the theme’s header.php erased the problematic code, returning the site to normal for the day. (I read of other situations where the injection is in the footer.) The ftp logs showed that /wp-content/themes/mytheme/header.php file was changed.

After the first few days, replacing header.php no longer solved the problem, and the injection switched over to being an evil redirect, taking our visitors elsewhere.

Location of the Bad Code

Eventually I found bad code in two files in /wp-content/uploads/2009/01/: topper.php and wp-pass.php. At least I think I did. It hasn’t come back in five days. The actual code was a base64-encoded 44,300+ character string starting with: <?php $o=”QAE…(44,300 characters)…”  ==”));return;?> This is apparently a variation on the ‘Goro’ hack, which Roberto Galoppini explains calls an external javascript code when decoded with base64_decode. My impression is that this bad code gets uploaded in any number of directories.

Steps to Harden Off the WP install and Look for the Problem

It took a while to eliminate the pernicious code. First steps included:

  1. Update WordPress. (I keep mine up-to-date, so this wasn’t the issue, but it’s a good first step if you’re facing this situation.)
  2. Change the ftp password, the wp-admin password (strong passwords, different from each other)
  3. Delete the wp-admin user ‘admin.’ (Create a new admin account and assign all of the posts, if needed, to this account.)
  4. Disable any plugins that ping updates to sites like Google, Technorati, etc. until the problem is solved. (You don’t want to call their attention to the new spam.)
  5. Remove any spammy looking registered users on the site. (They shouldn’t be able to do anything, but it seems like a good precaution.)
  6. Move wp-config.php to the directory directly above WordPress install. (It will only work if it is a single directory above its original home.) This file stores the database username and password. [I assume this was the file that made the breach possible, but I don’t know for sure.]
  7. Install the plugin SEO Egghead’s WordPress-firewall
  8. Make sure there is a blank index.html file in the wp-content/plugins/ directory
  9. Per Chris London’s spam injection advice: Protect the wp-config.php file further by adding the following to your .htaccess file:
    1. # protect wpconfig.php
    2. <files wp-config.php>
    3. order allow,deny
    4. deny from all
    5. </files>
  10. Hide your wordpress version number (instructions via WpRecipes)
    In your theme’s functions.php file, add the following line:
    remove_action(‘wp_head’, ‘wp_generator’);
  11. I used the WordPress Admin upgrade tool to reinstall the current wp version. This removed the spam in the code, indicating that the script calling the code was showing up in a new location: a WordPress file and not a theme file.
  12. I followed the steps at http://www.teohuiming.name/blog/wordpress-exploit (reviewing db tables for potentially problematic entries in the options table, as well as *_(old|new).(php|giff|pngg) files in the directory structure). I could have had success in this step if I scoured through the wp-content/uploads/ folders for not just the file names and extensions listed but also for files that did looked suspect (topper.php and wp-pass.php, the culprits, definitely would have gotten my attention).
  13. Finally, I did a fresh install of WordPress, and all plugins. A new database was created, as part of the process. I imported the old data. This potentially could bring the spam back in, but was worth at least a try to me. The site has a lot of photos managed through the wp plugin NextGEN Gallery. Reloading all of the photos would have been very time-consuming. The theme files and uploads were ftp’ed to the server. It was at this point that I scoured through the uploads folders and found the suspect files.

It’s been almost two weeks now, with no sign of the injection. If you’re dealing with this: best wishes. If your site’s Google search ranking is suffering because of the spam links, see instructions for requesting reconsideration.

Submit a Comment

You must be logged in to post a comment.