Tales of a WordPress Trojan

A couple of nights ago, as I was browsing the web, I got a pop-up message from Zone Alarm Anti-virus telling me that it had found and quarantined the Trojan-Clicker.JS.Agent.h trojan in my Firefox cache.

Now the problem with the Firefox cache is that the files in there aren't indexed by URL name so I had no idea which site I'd gotten that trojan from. The only two sites that were open in my browser at that time were Google Reader and this here blog of mine. This blog, by the way, is installed on my own website which, in turn, is hosted on a shared web hosting server in the US. A server that is expertly managed by my web host's very competent systems administrators. My website, therefore, is very secure. My blog is also secure since my version of WordPress is almost always up-to-date. This, then, was strange since neither of those sites should really have had a trojan or virus or anything else malicious on them.

Since Google Reader was the less likely trojan-hosting candidate, I thought I'd check my blogs's HTML page source to see if I could figure out what was going on. However, when I tried to check it through Firefox, the page came up "missing". That was not a good sign. This meant that it was indeed my blog that contained the trojan since it was this page's local copy (in the cache) that Zone Alarm had quarantined. To double check, I navigated away from and then came back my blog's home page. Immediately, Zone Alarm popped-up another quarantine notice. Yep, the trojan was in my blog [1].


Time For Some Research

I then went to the web to learn all I could about the trojan which, strangely enough, wasn't much at all. This trojan was (and still is) rather new to the 'net and, therefore, has been minimally catalogued in all the online virus databases. It was, however, mentioned on a few message boards. Unfortunately, the relevant posting on Zone Alarm's message board was incredibly useless while the message boards that really seemed to be discussing it actively were all in Russian. Google Translate helped a bit with that but, ultimately, I couldn't learn anything from those pages either.

All I ended up learning from the web was that this is a JavaScript trojan (hence the JS in the middle of its name) that either opens up a pop-up ad, places a cookie in your browser's cache, creates a connection to a couple of sites on the 'net, and/or re-directs your browser to a particular page. I wasn't sure which of these this trojan did because it never got the chance to run on my computer. I also learnt that this trojan was, for all intents and purposes, pretty harmless. The virus databases listed its threat level as low and, really, if no one had even bothered to document it in any detail on the 'net, how bad could it be?

Still, a trojan is a trojan. So I set about trying to fix the problem myself.


The first thing I then did was some more research. I started by checking the WordPress site for security documentation. I learnt quite a bit from there. I then went and did all the things they suggested you do to 'harden' your WordPress installation. These were things I hadn't done earlier and that was probably how the trojan had gotten into my blog in the first place.

Next, I went and downloaded (through FTP) all the files from my blog installation to my local hard drive. All the files (mostly PHP files) got downloaded just fine but one of them immediately got quarantined by Zone Alarm. "A-ha", I thought, "that must be the file that contains the trojan. I must look at this file." Unfortunately, Zone Alarm wouldn't let me (duh!).

Fortunately, this was a file that I could look at from inside WordPress' administrator's interface. Unfortunately, again, most of what was in that file was gibberish. It contained a few JavaScript functions that were weirdly named (a seemingly-random string of numbers instead of a descriptive name) and some code within those. Now, since I didn't want to mess with WordPress' code, I though I'd compare this file's code with the corresponding code from Nadia's blog installation (which, according to Zone Alarm, was trojan free). Nadia's version of this file was, indeed different from mine. As I tried to tweak the code in my version of the file, however (i.e. change my file's code to make it look like Nadia's), I must have mistyped something because the next time I tried to view the blogs they had both crashed. That is, every time I tried to load them, I got a 500 Internal Server Error error.


It All Falls In To Place

Fortunately, our blogs eventually came back online (did I mention that my web host's SysAdmins were really good?) and, this time, I wasn't getting any trojan pop-up messages from Zone Alarm when I visited them. However, the next day, the trojan quarantine messages were back. Oh, and now they were coming from both blogs. It was then that it occurred to me: "Dammit! The reason my code editing didn't work the first time was because I was trying to make my trojan-ridden code look like another kind of trojan-ridden code!" That is, I wasn't actually removing the trojan from my blog, I was merely changing it to look like the trojan on Nadia's blog. What I should have done was compare my version of the file to a perfectly clean version of the same file.

To get a clean version of that file, I went back to the WordPress site but couldn't find it there. I figured I'd have to go into the actual PHP source code (maintained by WordPress' developers) to do that...but that wasn't something I really wanted to get into. Then I realized that I did have easy access to a clean version of that file: I could simply install another copy of WordPress on my own website. Since this would be a new install, all of its files would be perfectly clean and trojan-free. I could then compare my file to that installation's version of that file. So I went ahead and did just that. And guess what? All of the JavaScript code in my file was trojan code. That is, the original version of the file didn't contain any JavaScript code at all [2].

Removing that was easy and now, finally, our blogs are completely trojan-free. If all now goes well, and with the help of a much more secure WordPress installation, our blogs will stay trojan-free from now on as well. Here's hoping.


[1] While my web host's SysAdmins are responsible for maintaining the web server itself, they aren't responsible for the stuff you install on your site. That is, the fact that my blog had a trojan in it, wasn't their fault. It wasn't entirely my fault, either. Nor was it really the fault of the people who made WordPress. It was basically the fault of the hackers who had found a way to exploit a vulnerability in WordPress that let them attach this trojan to it. That's usually how it happens anyway.

[2] Which, in retrospect, is obvious since it was a PHP file that really shouldn't have had any JavaScript in it anyway.