In the past few days, I was faced with a pretty interesting problem. My friend’s wordpress blog, which is running the open source wordpress.org, got hijacked with a nasty exploit, which ended up redirecting all links within the blog to some Russian site. Fortunately, the Russian site was a 404 link, however, it still was frustrating to the users visiting the site. More over, it was especially treating the re-direct seriously, when coming from specific referring sites (i.e: Google, Facebook, Yahoo, etc …)
At first sight, I had initially thought it was a URL redirect problem, which means that the problem probably lies in the modification of the .htaccess file. Well, that was simple enough, and sure enough, I did find very clear URL re-writes which were redirecting the site to a malware site.
First things first, I did what any person would do when their site is compromised. I changed the passwords to the admin accounts of the blog, the webhost, phpMyAdmin, and the password to the wordpress database.
It wasn’t until I noticed another .htaccess file lurking outside of the blog root, and containing the same thing as the one within the blog, that some additional flags got raised. So, I decided to delete the .htaccess in the root of the hosted site, and modify the one within the wordpress blog, so as to maintain the legit permalink re-writes. In addition to the replacement of the .htaccess file, the exploit was actually chmod-ing the file to 444 (r–r–r–).
The problem became a bit more apparent when I noticed that the size of the .htaccess was changing periodically, and getting replaced with the malicious code. This is when I was started to look at other options. Given that I had never dealt with code or SQL injections before, I had no idea what to look for. In researching that, I realized that a code injection can look very much like a normal piece of code in a php file, but does something bad to the site, so I started digging around to find the exploit.
Given that the .htaccess was being changed at the root of the host, as well as in the blog, I figured that the exploit can’t be generated from the blog itself, since it seems to be able to see outside of the blogs’ vhost. Through this process, my friends’ blog was hosted on a webhost with a starter package, that barely has access to FTP. Without SSH, navigating code, and doing searches was hard and extremely inefficient. Since I had started to doubt that the exploit may have been on the outside of our website completely, I decided that the combination of those two, may deserve the move to a better host, with an actual functioning cPanel, and SSH access. Well, we did that, and that went fairly smoothly.
To my surprise, I still saw the code exploit in place, even after moving. The 4 places that I thought would be prone to attack are the following:
- The WordPress source code
- The plugins
- The themes
- The database
So I started by replacing the WordPress core with a new copy that I had just downloaded, then waited a while, only to see the exploit come back.
Then I completely removed the plugins directory, and did the same, only to see the exploit come back.
Then I did the same with the themes, and replaced the blog theme with the out-of-the-box twentyeleven theme.
I had thought that this last one will definitely resolve the issue. Again, that didn’t happen.
So I started poking around in the database, following some blog entries, and couldn’t find anything. There were some weird entries in wp-options–>wp-cron. (Cron the wordpress scheduler), except I wasn’t quite sure how to decipher the nomenclature in this field.
I even went into the posts, and the comments to see if there is any malicious code in there. I was getting desperate.
Finally, it dawned on me to try and search for some sort of scanner that I can run against my directory. Sure enough, I found the perfect WordPress plugin, simply called Exploit Scanner. Running this, I got a dump of quite a few results, which I had to weed through, but essentially, that scanner goes through any functions that can be used to obfuscate any code, (like decoding base64 or preg replace). Sure enough, there was one preg replace that was found, and it pointed to a file, get this, in the wp-content/uploads directory, called _cache.php
The ONE directory that I didn’t check. Let me rephrase, I did check the directory, just not in its root, I looked at all the contents of the subdirs, to make sure there is nothing other than jpg and png files, and there wasn’t, so I ruled it out. And all along I was moving around that upload directory as an innocent component. DOPE!
Of course, at this point, I deleted the _cache.php file, fixed the .htaccess files one last time, and all went back to normal.
- Never assume anything. In the exploit world, treat anything and everything as guilty, until absolutely ruled to be innocent.
- I have spent entirely too much time manually looking for the content of the exploit. Had I looked for that scanner from the beginning, that problem would’ve been resolved much sooner.
The good news, is that during that process, I learned a bunch more about PHP, MySQL, exploits, and some more about the WordPress codex, and database structure.
Hopefully this post will help someone navigate through a similar issue, if (and when) it happens.