Wednesday, 18 July 2012

WebKit XSSAuditor : The XSS catalyst

---Google:"Chrome 18 anti XSS bypass" and feel lucky ;)
 
A while ago I released a bypass for the webkit XSSAuditor in Chrome, I thought I'd honor it with a blog post and discuss another danger the XSSAuditor presents to web application security. This 'danger' of XSS filters has been published in a very popular paper---http://www.collinjackson.com/research/xssauditor.pdf--- about some XSS filters. What I'm doing here is demonstrating whats described.
XSSAuditor is part of WebKit's HTML parser and exists to try and mitigate reflected XSS attacks. Unfortunately because of how the auditor operates it can often have quite the opposite effect!
In this post I'll explain the situations where XSSAuditor can actually have the adverse effect on a web application's protection against XSS attacks.

How does it work?

Before getting down to business we need to cover a little admin, I should first make it clear exactly how the XSSAuditor goes about its job.
   The XSSAuditor is a small part of WebCore the collection of things in WebKit that handle parsing HTML,XML and Javascript---among other things.
   Its been designed to inspect requests and responses for anything that resembles runnable Javascript. Should a response and request contain exactly the same runnable Javascript, the XSSAuditor will remove said Javascript from the response. Please take note of the way that last sentence was phrased. The XSSauditor will only
  • inspect:
    • Responses
    • Requests---GET and POST
  • Audit
    • Responses
IF and ONLY if the same runnable javascript is detected in both---the request and corresponding response. Whether they are the same is down to whether the cpp string method `find' will match the data in both requests and responses---to be as clinical as possible.

I'm sure some of you will immediately start thinking of ways you can inject one thing while being returned another. Sit tight I'll get to instances where that's possible!

So lets take a look at the XSSAuditor in action, what it does and when.
Once again I'll be using DVWA to do the demo.
I'm gonna use a straight forward payload, something like:
www.vulnerable.com/script.php?arg=<script>alert("Woops!");</script>
XSS attack Blocked by XSSAuditor
 So in the above screen shot you can see the effect XSSAuditor has on the injection payload. Its managed to match the payload in BOTH the request and response and is stripped out the contents of the script tag. You may wonder why it doesn't just completely kill the entire payload, why would it keep the script tags?

Oh as a side note, just to put the whole operation into perspective, XSSAuditor kicks in before the bulk of the HTML parser does, its actually called from with in the HTML Parser in Webkit. What it does is work with the HTML Parsers COPY of the response. Anyway cracking on...

Oh yes, why keep the script tags? This is done so that the Auditor affects as little of your browsing experience as possible, it will only remove what it deems dangerous, but keep the rest of the returned HTML tokens in attribute values in case the Web Page needs them for some reason. Personally I don't agree with this stance, browsing safety trumps browsing experience anyday!

So yeah that's what does. You may want to see that I'm serious when I say "RUNNABLE" javascript---this means any javascript that could be executed, including any javascript that will cause errors or has syntax errors---will be audited. To prove my point, ill inject some non-runnable javascript---meaning code thats commented out.

Here's the Payload:
<script>/*alert("Woops");*/</script>
And the screen shot :)

 The payload remains untouched! If you inject commented and non-commented javascript the entire contents of the script tags will be removed.

So now you guys know a lil about what the auditor does, I can move onto explaining what it doesn't do!

We know that the XSSAuditor STRIPS out the javascript, if it sees the same javascript in the response and the request. This obviously implies that if it cannot match the javascript in the request, it will not strip it out---because frankly, its impossible to determine whether the javascript in the response is genuine or not.

So this means if something happens to the injected javascript
before it reaches the browser the XSSAuditor would touch it. I'm talking about cases when the web application you're attacking mangles or changes the payload before returning it. This particularly dangerous when the application returns the payload in a form thats different from it is in the request but still runnable. Now I know that this doesn't likely occur in modern applications, I've stated it this way because it provides a good stepping stone to move onto the next topic.

Reverse Engineering Server side XSS filters

 

I must make myself clear when I say "Server Side XSS filters", I'm referring to server side filters that strip out dangerous payloads from requests before returning them.

Because of the way the XSSAuditor operates, its possible to  use these server side filters to propagate XSS attacks! If you think about it a lil it because pretty obvious.
  • An attacker injects some payload A with malicious content q
  • This payload is audited by the server and returned as A - q
  • XSSAuditor tries to match  A with A - q, this fails and the returned payload is left untouched!
 It may not be apparent why this is dangerous, you're probably arguing that
if you inject a payload and the server removes all the good bits, why would it still be dangerous in the request?

To prove that we can create attacks using these properties, I'll pose a not so hypothetical situation.

DVWA has an example of XSS attacks against scripts that behave the same way, I'm going to attack it with a non-malicious payload, and have it return a malicious one all while bamboozling the XSSAuditor into allowing the payload to take effect, here's the for the script I'll will be attacking:

The critical part here is str_replace('<script>','',$_GET['name']);
This will remove the string <script> from the payload. So what I'll do with this is inject something like:
<scr<script>ipt>ale<script>rt(1);</script>
The first bolded <script> string is to make sure that the server side filter will not remove our opening <script> tag, but infact strip away the "bold" <script> leaving a valid opening script tag behind. The second one is there so that the XSS auditor will see:
  • ale<script>rt(1); in the request
  • and alert(1) ; in the response
This means it will not find a match between the two, and leave the response to be parsed by the WebCore.
This example is quite simplistic though I'm confident that code like this does occur in the some of the web applications out there---I know you haz em! Another thing to take into account is the average blacklist or regex that is to perform a similar action---remove dangerous string tokens from input---will most probably try to match a list of tags, not just <script>, unless the developer knows absolutely nothing about XSS attacks.
Lets check out how the payload behaves:
XSSAuditor says what!?
As expected! Also keep in mind that we are not just talking about Server Side filters only here, we could be talking about IDS's or WAFs I'm sure some of you will be able to think up tons of examples where applications behave the same way.

Oh for those of you who are wondering I used Chrome Version 19.0.1084.52 
to do the demo.


The most shocking part about all this is the XSSAuditor is supposed to protect users but what It's doing here is actually helping propagate attacks! Solution?
FireFox + NoScript ;)

That's it for now! Hope you enjoyed it, feel free to flame me with some comments if the post has some spelling/logic or grammatical errors lols.