First of all, at the moment this challenge is ongoing since last year (2013) and you may have already heard about it. Here is the link to this challenge: http://www.modsecurity.org/demo/demo-deny-noescape.html
I was very late to the party as other challengers could have defeated it easier in September 2013: http://blog.spiderlabs.com/2013/09/modsecurity-xss-evasion-challenge-results.html. These bypasses have been fixed now and it should not be possible to use those techniques to win the challenge.
As a result, the challenge is much harder than what it was in September and probably would be tougher in future. Fortunately, I managed to bypass all three different groups of the protections separately. Unfortunately, I could not find a single payload to bypass everything at the same time so I could not claim the prize just like other previous challengers! You can tell me first if you found a way to bypass them all though ;)
Here is what I did to bypass the XSS protections in this challenge for future reference:
XSS Defense #1 – blacklist method
XSS detection based on 5 different restricted blacklists! In my humble opinion, you may not be able to use these blacklists at the same time in a live web application because of the high number of false-positives. For example, it currently detects the following strings as attack vectors: “dude, I am online =))”, “<~form”, or “test this src for me”.
I thought I may be able to bypass the protection by using a flash file and an “object” tag, but “<object data=…” was blocked by different protections…
However, I used the following features to bypass these protections:
-  An “object” tag does not need to be closed for this scenario.
- A null character with an alphanumeric character after the “object” tag would make it undetectable by different protection methods in this challenge (e.g. “<object%00something”).
- “allowScriptAccess” and “data” attributes were allowed!
So the following is a bypass method for the XSS Defense #1:
And as the page writes the payload twice, I could also use the following to bypass the protections:
XSS Defense #2 and #3 – DomPurify and MentalJS
The defense #2 and #3 are about bypassing the white-list protections. You can read more about them in the modsecurity challenge page.
I was thinking to bypass DomPurify by using DOM clobbering attack (http://www.thespanner.co.uk/2013/05/16/dom-clobbering/) but it had some protections against it:
In this code, it checks “elm.attributes.item” to be a function but it does not verify the “elm.attributes” to have the correct type (it has been fixed now). As a result, I managed to bypass its “_sanitizeAttributes()” function by using a “form” tag with two “input” elements with the “name” attributes equal to “attributes”. If I was using just one “input” element, “elm.attributes.item” would not be a function, and therefore it was detectable; however, with more than one element, “elm.attributes.item” would be a function and “attributes.length” would be a numerical value so there would be no error in JavaScript, and this causes confusion for “currentNode.attributes[attr].name” in the following code to point to the “input” elements instead of the real form’s attributes which is what we need. Therefore, I could bypass the protection that DomPurify had in the “_sanitizeAttributes” function without causing any error by using DOM clobbering technique:
The bypass code is as follows:
It turned out that this also bypasses MentalJS sandbox by causing confusion as a result of DOM clobbering in the code below:
XSS Defense #3 – MentalJS
Apart from the previous bypass for MentalJS, I also found out that it is possible to bypass its sandbox by using “innerHTML” to build a script tag instead of using “createTextNode”:
I also found the following interesting tricks in MentalJS but they did not lead me to any new bypasses:
Keeping script “src” to an external js file (normally MentalJS removes them):
Keeping a non-whitelisted tag by clobbering the “removeChild” function (this will cause a JavaScript error but this is not a problem as it is in a try/catch statement):
If you are still interested, the following link is the conversation about bypassing MentalJS in slackers forum and it is really awesome:
MentalJS has been written by Gareth Heyes (@garethheyes‎) who was supporting me to bypass his tool to make it more secure.