UrlScan 3.1

Earlier this year, it came to our attention that our customers were being subjected to a SQL Injection attack.  In response to that, we updated the venerable UrlScan filter and released version 3.0 with new features that provide tools to provide some mitigation and allow users to address issues in their affected applications.

This effort has been largely successful, but it has driven attackers to come up with new techniques.  Very recently, our internal security team brought it to our attention that they'd seen a new variation on the attacks.  This new variation is trying to exploit a behavior in ASP's parsing of the query string for the Request.QueryString function.  Note that ASP.NET's behavior in this area is different and ASP.NET applications are not vulnerable to this specific new technique.

The specific behavior in ASP results when the query string contains a name/value pair where the value contains a '%' sign that has not been escape encoded.  Consider the following examples:

  • If the client sends "page.asp?abc=xyz", calling Request.QueryString("abc") will return "xyz".
  • If the client sends "page.asp?abc=x%79z", ASP will decode the value and Request.QueryString("abc") will also return "xyz".

But if you wanted the value to contain a percent, Request.QueryString requires the '%' sign to be encoded at %25.  If you do not encode the '%' sign, Request.QueryString will drop it from the returned value.  For example:

  • If the client sends "page.asp?abc=x%25yz", Request.QueryString("abc") will return "x%yz".
  • If the client sends "page.asp?abc=x%yz", Request.QueryString("abc") will drop the unescaped '%' and return "xyz".

It is the final example above that is problematic.  If you have a filtering rule that is attempting to prevent "xyz" from reaching an ASP application, an attacker could try to get around the filter by sending it in a name value pair with an unescaped '%' in the value.

It is possible for UrlScan 3.0 to block the problematic request above, but to do so it is necessary to block any instance of a '%' sign in the query string.  This would be effective, but it would also be subject to many false positives because it would also block '%' sign instances that are part of a valid escape sequence.

Enter UrlScan 3.1

It became clear pretty quickly that UrlScan needed a new tool to address this new attack in an efficient way.  To do that, we've added the ability to deny unescaped '%' signs in a request.  This new feature can be applied to unescaped '%' signs in the query string, in specific named headers, or anywhere in any header name or value.

To block any requests attempting to use an unescaped '%' to get around the query string filter, you can add a single rule to the urlscan.ini file.  The following rule says that, for any ASP page, search the query string for an unescaped percent and, if found, block the request.  To activate the rule, be sure to add to the RuleList property in the [Options] section of urlscan.ini:

[UnescapedPercentRule]
AppliesTo=.asp
DenyUnescapedPercent=1
ScanQueryString=1

And while we were adding this new feature, we were able to make a couple other fixes in UrlScan.  The following changes have been made:

  • It was possible for certain escape sequences to get past filtering rules.  This has been fixed.
  • Certain query string rules did not work properly on IIS 5.1.  This has been fixed.
  • The behavior of the [AlwaysAllowedUrls] section has been changed.  In UrlScan 3.0, any URLs listed in that section were not subject to filtering of anything that applied specifically to the URL.  Effective with UrlScan 3.1, any URLs in that section are not subject to any UrlScan rules.  This means that adding a URL to this section will prevent query string or other rules from blocking the URL.

The UrlScan team highly recommends that you update to UrlScan 3.1 today at one of the below links.  If you are using UrlScan 3.0 to apply SQL injection filtering to Classic ASP pages, this is particularly important, along with adding the above rule to block unescaped '%' signs.

Also, any discussion of filtering for SQL injection or other injection attacks, it is important to remember that filtering is only a stopgap mitigation.  It is essential to fix the vulnerabilities in the underlying code.  Information on SQL injection vulnerabilities in applications can be found here and general information on security web applications can be found here.

UrlScan 3.1 can be downloaded from the following locations:

For 32 bit: http://www.iis.net/go/1697
For 64 bit: http://www.iis.net/go/1698

-Wade

3 Comments

  • Wade,
    I just found the additional installation instructions here: http://learn.iis.net/page.aspx/475/urlscan-setup/. So I was able to get URLScan start logging in a new directory after I granted Read & Write access to the IIS_WPG account on the log folder.

    I was debating about moving the urlscan.dll & urlscan.ini to the same area as I moved the logs but I was wondering... If a 3.2 came out would the upgrade/installation of that version just put urlscan files back in %windir%\system32\inetsrv and additionally under %windir%\syswow64\inetsrv and update IIS to those directories? That would be a pain to manage and possibly cause issues. Or would it search my hard drive and update any existing versions I had? I'm hoping the later because we have a policy of installing all "need to be backed up files" on a different volume other than C:\. Another possiblity is to allow the installer to select where they want urlscan to be installed.

    Thanks again, Brian

  • Wade,

    This looks like a great tool. I spent most of the day yesterday implementing it on one of our Win2003 x86 development servers. It does exactly what it needs to do.

    Now, I need to take the next step and put it on our test platform which is Win2003 x64. No matter what I've tried, I cannot get URLScan to do anything. We needed x64 so that additional memory would be available for additional, larger application pools, but the application pools run in 32-bit mode for compatibility with some classic ASP and 32-bit resources it depends on. I think this is at the root of my problem but I have no idea how to work around it. This scenario (32-bit compatibility on x64) needs to be addressed in the documentation.

    Can anyone help me with this?

  • Has it been confirmed if this product works with MCMS?

Comments have been disabled for this content.