Paid Advertising
web application security lab


Jeremiah Grossman and I spent some time looking at the exploit that Kurt Huwig found using malformed ASCII chars to bypass filters. We were able to actually turn this into HTML that will run, without using open and close angle brackets. In IE click here to run the proof of concept XSS (notice that the script tags are not encapsulated by valid ASCII chars).

The trick here is the encoding, we found. Unfortunately the scariness of this exploit is actually not as dramatic as we originally thought it may be, because it requires the US-ASCII char encoding to be set. After just a few minutes we had a working pototype and we even got XSSs working through the script.

So then we ran a scan of ~500 domains and found that only about 1% of the domains had this in them. So as a viable attack vector, sure, it’s possible that some servers (Kurt runs Tomcat, so maybe that one?) may be vulnerable in the way they are set up for any IE users who happen to use their sites.

A more viable possible problem is that content filters, anti-virus and other tools that monitor inbound packets will not see this encoding method. Any virii payloads, or otherwise blocked content like spam could easily follow this encoding method and travel unstopped to the browser, whereby they would be rendered as you would expect. Pretty scary stuff, actually.

Thanks to Jeremiah for his help in this blog post!

9 Responses to “US-ASCII XSS part 2”

  1. Kurt Huwig Says:

    I was able to get your example working on a normal HTTP server by adding this to the er:

    Demo page is here:

  2. RSnake Says:

    Hi, Kurt, thanks for posting, and it’s a very interesting exploit that you’ve come up with. I think the reason that is working on your server and not mine is because you are not passing a header. Here is a dump of your server headers:

    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    ETag: W/”428-1150936271000″
    Last-Modified: Thu, 22 Jun 2006 00:31:11 GMT
    Content-Type: text/html
    Content-Length: 428
    Date: Thu, 22 Jun 2006 02:38:44 GMT
    Connection: close

    And here is ours:

    HTTP/1.1 200 OK
    Date: Thu, 22 Jun 2006 02:44:21 GMT
    Server: Apache
    Last-Modified: Thu, 22 Jun 2006 02:43:08 GMT
    ETag: “19f3b4-1ad-137b6700″
    Accept-Ranges: bytes
    Content-Length: 429
    Connection: close
    Content-Type: text/html; charset=ISO-8859-1

    We automatically set the charset along with the HTTP header, so overriding it doesn’t appear to work on this server. If no charset was set, like you showed (and how your server happens to work), I think that would work. Anyway, I think there are plenty of applications even if the majority of servers don’t happen to support this. And now that I think about it that is probably why I never found this vulnerability by sheer dumb luck during my fuzzing. The server wouldn’t render it properly to the browser based on the encoding set in the HTTP header. Interesting.

  3. RSnake Says:

    FYI, this has now been picked up by the National Vulnerability Database at NIST:

  4. Jake Reynolds Says:

    So I’ve been trying to add support for my script injection tool for this US-ASCII stuff. In the process of testing it out I found something noteworthy regarding ASP.NET web applications. I have a very simple .NET web app I use to test reflected script injection. All it does is copy all parameters out of the query string supplied in the request into hidden form field elements in the body of the response.

    So I configured the response encoding as “us-ascii” and verified that the charset was coming acrossed correctly. Then I just hardcoded “¼script¾alert(¢XSS¢)¼/script¾” into my ASP.NET test page and tried to retrive it with IE. The response was “?script?alert(?XSS?)?/script?”.

    I had seen this a few minutes before when I was writing my 8-bit ASCII encoding method for my tool. The .NET ASCIIEncoder class (correctly) replaces any characters > 0×7F (127) with ‘?’ since us-ascii only supports 7-bit characters (

  5. RSnake Says:

    Interesting. Jake, I hate to say it, because I _LOVE_ your tool, or the version I’ve seen of it, but I really think a proxy would solve all your problems. Just act as a straight pass through, and that way you are browser/rendering engine agnostic and you don’t have to worry about the conversion issues.

    You could do a simple substitution on the few chars you need to (open and close angle brackets, double and single quotes, semicolon, parens, and the whitespace chars will probably cut it). I’m just trying to think of ways to make your life easier.

  6. RSnake Says:

    And yes, you’re probably right, .NET is probably invulnerable to this. I had to write a custom cgi script to even test this. I’m only aware of one server (Tomcat) that is vulnerable to this out of the box (probably others as well but I haven’t found any in my tests).

  7. Jake Reynolds Says:

    Yeah I plan on going the proxy route. Well both actually. When I’m done you’ll be able to run it in local (IE) or proxy mode. That will solve my multi-browser problem. For the us-ASCII stuff I had planned on encoding EVERYTHING so that even the words script, alert, javascript:, etc will bypass filters. ¼óãòéðô¾áìåòô¨©¼¯óãòéðô¾ rather than ¼script¾alert(¢XSS¢)¼/script¾. That in combination with the hex-encoding, zero-padding etc, gives some pretty powerful obfuscation like:

    ¼âïäù âáãëçòïõî佦£ø°°°°¶Á»¦£ø°°°°¶±»¦£ø°°°°·¶»¦£ø°°°°¶±»¦£ø°°°°·³»¦£ø°°°°¶³»¦£ø°°°°·²»¦£ø°°°°¶¹»¦£ø°°°°·°»¦£ø°°°°·´»¦£ø°°°°³Á»¦£ø°°°°¶±»¦£ø°°°°¶Ã»¦£ø°°°°¶µ»¦£ø°°°°·²»¦£ø°°°°·´»¦£ø°°°°²¸»¦£ø°°°°²¹»¾

    Hard to believe that renders in IE. Good luck finding it through input validation. Good thing, like you said, that this has a pretty small attack surface.

  8. RSnake Says:

    Yup, luckily very few people use that encoding method. That’s just ugly.

  9. web application security lab - Archive » US-ASCII Issues Redux Says:

    […] As I’m nearing completion of my XSS fuzzer for people, I’m finding more and more interesting issues. Just so you know I’m not keeping everything from you all, here’s another interesting problem I uncovered. Sure you remember the original problem with US-ASCII encoding, where a character could be modified and in US-ASCII it would render as a open angle bracket, or any other character, if you encoded it correctly. Wellllll, it just happens that that is only one of many problems with US-ASCII it turns out. Sure you can look for everything higher than 7F (or 127 in decimal) and less than FF (255 in decimal) and kill it but that won’t solve your problem. One of the tests I ran was: […]