Developers at fault? SQL Injection attacks lead to wide-spread compromise of IIS servers

There's been a lot of noise and violent thrashing over the last couple days regarding a flaw that was originally believed to be a flaw in Microsoft's IIS (Internet Information Server), but has since been pointed out as simply a well thought out SQL Injection attack. For those of you who aren't familiar with SQL Injection attacks, it's a pretty well known web application attack vector that exists in high volume on dynamic applications, say for instance, on your banking site.

There's been a lot of noise and violent thrashing over the last couple days regarding a flaw that was originally believed to be a flaw in Microsoft's IIS (Internet Information Server), but has since been pointed out as simply a well thought out SQL Injection attack. 

For those of you who aren't familiar with SQL Injection attacks, it's a pretty well known web application attack vector that exists in high volume on dynamic applications, say for instance, on your banking site.  SQL Injection allows an attacker to subvert the logic of the currently running SQL query in order to interact with data more interesting to the attacker, bypass authentication/authorization, or run arbitrary commands on the operating system of the database server.  Here's an example of the attack:

1.) Imagine a web application, such as a banking application, that has a login page.  When logging in, the application will take the username and password that you supply and query a database table of users that it knows about.  Basically, if your username and password match entries within the database, then you'll be authenticated.  

2.) When a query is created dynamically, and uses user-supplied input (the username and password), without sanitizing them or running them through a parameterized query class, then SQL Injection is possible. 

3.) The code might look something like the follows (this will be roughly Java like, but you can extend it to your language):

String query = new String("select * from USERS_TBL where username='" + request.getParameter("username") + "' and password = '" + request.getParameter("password") + "';");

// create the connection and statement, details left out as they are unimportant

Connection con = new Connection(...);  Statement stmt = new Statement(...);


4.) Now, if you look in that code, you'll notice that the query is constructed with dynamic parameters (username and password) that are pulled in from the request object (basically pulling them out of the query string from a request) and put between a set of single quotes.

5.) If I inject something the application doesn't expect, for instance ' or 1=1--, the application will execute the SQL code as is:

select * from USERS_TBL where username = '' or 1=1-- and password = '';

Basically, I've forced the query into a conditional statement that will always be true.  The username will be blank, or 1=1 (which is true of course), and since this is an or statement with an always true value, this statement will always be true... well guess what?  Now I've logged into the application as an authenticated user.

6.) SQL Injection is much more dangerous than this in fact, as I can typically pull out all information from all tables (including social security numbers, account numbers, etc.), and in some cases, like in Microsoft SQL server, I may be able to execute arbitrary commands (xp_cmdshell). This might also be used to insert data into relevant tables (like it appears to have been used here), where an attacker might insert data that would later get rendered in the context of the victims browser. Imagine deploying a browser based attack vector in conjunction with SQL Injection. Infect 100s of thousands of sites, infect millions of users.

Obviously this is really bad.  Would you be suprised if I told you it was pretty common place to discover these types of flaws in a web application assessment?  In any case, back to the matter at hand which is this wide-scale compromise (estimated at over a half-million sites) of Microsoft IIS servers.  Sunnet Beskerming, a blogger that I read often, commented on this story as follows:

Although there has been a new IIS vulnerability disclosed in recent weeks, the attacks are only making use of poor site and database maintenance practices - using SQL injection to exploit sites.

For site visitors who visit an affected site, JavaScript is used to try and download / run malware that then targets a number of commonly used technologies in order to gain full control over the system.

It goes to show that input validation is a critical component of the security picture for a site and it is a problem that is still not being properly addressed by many sites, including a lot that should know better.

In one simple set of attacks, previously trustworthy sites can now no longer be considered trustworthy and it is another blow to services that tout their ability to mark a site as being 'Hacker Safe' or otherwise safe for visiting (like SiteAdvisor).

Bill Sisk of Microsoft has also commented on the issue:

There have been conflicting public reports describing a recent rash of web server attacks. I want to bring some clarification about the reports and point you to the IIS blog for additional information.

To begin with, our investigation has shown that there are no new or unknown vulnerabilities being exploited. This wave is not a result of a vulnerability in Internet Information Services or Microsoft SQL Server. We have also determined that these attacks are in no way related to Microsoft Security Advisory (951306). 

The attacks are facilitated by SQL injection exploits and are not issues related to IIS 6.0, ASP, ASP.Net or Microsoft SQL technologies. SQL injection attacks enable malicious users to execute commands in an application's database.  To protect against SQL injection attacks the developer of the Web site or application must use industry best practices outlined here.  Our counterparts over on the IIS blog have written a post with a wealth of information for web developers and IT Professionals can take to minimize their exposure to these types of attacks by minimizing the attack surface area in their code and server configurations. Additional information can be found here:

It sounds like, at least from reading several sources such as Dancho Danchev and Ronald van den Heetkamp's blogs, that this is a SQL Injection attack that actually inserts a malicious JavaScript payload that will then be rendered into victim's browsers.  Victim's who then view the subsequent pages will be hit with Cross-site scripting like attacks that try to force them to download malware, etc.  It could just as easily (probably should've been) incorporated with something like the latest QuickTime flaw(s) or some of the URI abuse research that I've been involved with. Now you can hit millions of users with attack vectors.

What is scarriest about this attack is that it appears that the group doing the attacking has found a few very reliable attack vectors for SQL Injection... honestly, it's likely even more damage could've been done, such as scouring the information out of all of these databases, deleting the databases all together, etc.

Interesting stuff... really shows how serious web application flaws are these days.  Good thing we have that strong PCI certification process recommending we have all of our applications go through at a minimum a black box security review... oh wait, that's right, they suggested web application firewalls.  Well, at least web application firewalls are decent at preventing SQL Injections, right?  Umm... well, don't you think that some of the following sites use a WAF and all that's available to them:

  • The UK government web pages
  • United Nations web pages
  • The Department of Homeland Security
  • etc.

Maybe it's because the attackers encode the attack funky-like (from Ronald van den Heetkamp's blog):

DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x4400450043004C0041005200450020004000540020007 600610072006300680061007200280032003500350029002 C00400043002000760061007200630068006100720028003 20035003500290020004400450043004C004100520045002 0005400610062006C0065005F0043007500720073006F007 200200043005500520053004F005200200046004F0052002 000730065006C00650063007400200061002E006E0061006 D0065002C0062002E006E0061006D0065002000660072006 F006D0020007300790073006F0062006A006500630074007 300200061002C0073007900730063006F006C0075006D006 E00730020006200200077006800650072006500200061002 E00690064003D0062002E0069006400200061006E0064002 00061002E00780074007900700065003D002700750027002 00061006E0064002000280062002E0078007400790070006 5003D003900390020006F007200200062002E00780074007 900700065003D003300350020006...

Decoded: DECLARE @T varchar(255)'@C varchar(255) DECLARE Table_Cursor CURSOR FOR select' from sysobjects a'syscolumns b where and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b...

So end result is, looks like another case of bad programming for now, on the side of developers of the vulnerable applications, not Microsoft.  More to come when I hear more.