or Why I Keep Harping On Blacklisting
An incident reveals attempts to get around blacklisting by manipulating behavior in ASP, illustrating the weakness of blacklist approaches.
A new version of UrlScan is shipping today with a change specifically to address this.
I was working with a colleague on an incident last week that looked like a garden-variety SQL injection drive-by except for something interesting.
While looking through the IIS logs from the affected server, I saw this:
As I looked at this, "DEC%LARE", "VAR%CHAR", and "BS%ET" immediately stood out to me. Obviously, the percent sign is usually used to escape something in a URL (like the %20's in there, which are spaces); however, this naked percent sign thrown in there didn't seem to have any purpose and should have caused SQL to not execute the code in question.
When I see somebody do something like this, it's usually for a purpose so I took another look at it. I realized that, if ASP silently stripped that percent sign out of there, then this would be an efficient way to bypass a lot of blacklist-based filters.
I wrote a quick test ASP page(1) and found that my guess was right on -- ASP drops a percent sign from the query string if it isn't followed by two valid hex characters(0-9, A-F) when it actually interprets it via Request.QueryString. This means that any filter that inspects raw headers using Request.ServerVariables is going to miss "DEC%LARE" if it is looking for "DECLARE" but, on the other hand, the ASP app that actually consumes that string using Request.QueryString("abc") is going to get it without the percent sign.
As this incident illustrates, a blacklist approach to SQL injection only works for as long as nobody finds a way around your blacklist. As soon as somebody finds a way around it (and experience suggests that attackers are motivated to do so), the value of your blacklist is zero.
The right approach is to fix the actual vulnerability in the code using parameterized queries. See the articles below for more information and examples.
The IIS team is releasing an update to UrlScan today that includes changes to address this in their filtering product. Of course, as I've said over and and over, no filter-based approach is going to be perfect, but UrlScan is still an excellent defense-in-depth tool and a way to mitigate SQL injection vulns in the short term while your developers fix them.
For more information on the UrlScan update, Wade Hilmo has all the details:
QUERY_STRING = <%= Request.ServerVariables("QUERY_STRING") %> <BR>
test =<%= Request.QueryString("test") %> <BR>