Event | Challenge | Category | Points | Solves |
---|---|---|---|---|
AperiCtf | TMNT | web | 300 | 6 |
TL;DR
In this challenge we need to trigger an XSS, first we need to bypass the template engine of the browser to insert custom tags in the page. We can then trigger the XSS with some specific tag and use a DOM-based JavaScript injection vulnerability.
Step 1
This is my first web write-up, I usually prefer popping shell, but this time we will pop some alert boxes ! We are faced with a search bar which display information about some ninja turtles.
In the source code of the page we can see the script main.js.
1 |
|
tmnt
is an array containing the name and descriptions of the turtles. So first a template is created, then it search for -->
in the input of the user to delete it and finally create some html to add to the page. Indeed, it’s reflected on the page:
My naïve approach was to add --!>
to the beginning of the input since it’s a valid closing comment tag and add <--
to the end of my input to close the last part of the comment:
1 |
|
Some weird things start to happen ! First my closing chevron >
has been encoded in >
but the other chevrons hasn’t. Because of that, my opening comment <!--
is useless. And a new closing comment appears out of nowhere.
In the script a comment is left from the author of the challenge:
1 |
|
Here is the description of the template tag from mozilla:
[...] Think of a template as a content fragment that is being stored for subsequent use in the document. While the parser does process the contents of the template element while loading the page, it does so only to ensure that those contents are valid; the element's contents are not rendered, however.
So the template element checks that those contents are valid html. This is the first step, we need to make the template engine fail this verification. After a lot of trying and error I came up with this payload:
1 |
|
It seems really simple but took me some time to figure it out. Here is the result:
Due to the Content Security Policy (CSP) we can’t directly inject <script>alert('XSS')</script>
because it will block inline javascript, this also means that we can’t use events like onload, onerror, onclick… CSP can be found in the source of the page:
1 |
|
This website allow you to test your CSP:
The yellow warning tells us that unsafe-eval could allow execution of code injected into the DOM API, seems promising.
Step 2
A second javascript file is loaded in the page, pizza.js.
1 |
|
At the end of the file there is an interesting line:
1 |
|
If we control the parameter user.name
we could potentially execute some javascript code, for example:
1 |
|
But to get there we need to set up some pizzas tags with custom parameters to pass into the last if
:
1 |
|
So the final payload is:
1 |
|
And boom the XSS: