Few hours ago intigirit posted their third XSS challenge, the solution of the challenge is a little different than your typical XSS challenges.
In this write up I will try to walk you through both my failed and successful attempts at solving this challenge to give you about how you can approach such challenges.
The following were the instructions for the challenge:
Here's the code snippet that was used.
<body> <img src="/www3/instructions.png"/> <script> document.body.append(document.cookie); var source = new XMLSerializer().serializeToString(document); document.body.innerHTML = decodeURIComponent(source); </script> </body>
As you can see above there doesn't seem like any user input is passed to the code, my first attempt was reading the
XMLSerializer().serialize function documentation to see if somehow it can be influenced by user input, however, this was not possible, I did the same with the
decodeURIComponent function, I knew that most likely those two functions doesn't accept user input but I like to check the documentation to be sure I didn't miss anything.
My second attempt was trying to check the URL and see if I can pass a parameter or fragment identifier (value after #) that can somehow affect the page or change it's behavior, I was unsuccessful, however, I noticed something interesting the page will be served not matter what you append to the URL, the link for the challenge was
https://challenge.intigriti.io/3/, However adding anything to that URL also works for example
https://challenge.intigriti.io/3/blahblahblah is still going to work.
My next attempts was after I saw a hint from integrity that says
Go Local and another hint that gave it away which was
"This page says" instead of "http://challenge.intigriti.io says" this meant that the vulnerability is triggering from a local file not online domain so somehow that user has to download the file.
The next thing I thought about was if I can make a local html file read the data from downloaded challenge file by embedding it in an iframe and then read the file contents, I was pretty sure that this is not going to work given that chrome is preventing this to protect against file stealing using local HTML files but I decided to try may be there's something I didn't know about, again this was a failed attempt.
At that point I was a little lost and I didn't know what else to do, so I decided to download the challenge file locally and play around with it, I looked at the source code and I saw this:
I saved the page locally and opened it but the alert didn't trigger, I inspected the source and this is what I saw:
And this time it worked like a charm:
The payload works in chrome and also in Opera as you can see above.
That was it for now, if you like this write up and want to see more you can poke around in this blog, and you can follow me on twitter for any new ones or if you like you can subscribe for mail notifications below.