Space Fleet Command =============================== On commence par analyser le code de l'application. On a un serveur nginx et un serveur web en JS. Et on a une page pour report un problème, cela ressemble fort à une XSS avec exfiltration de cookie admin. Cependant il y a un CSP a bypass : .. code-block:: javascript res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'none';") On a une injection dans message : Extrait du fichier app.js .. code-block:: javascript app.post('/report', (req, res) => { const url = req.body.url; if (!url) { return res.status(400).send('Missing URL'); } const path = extractPath(url); if (!path) { return res.render('pages/report', { message: `The URL ${url} is not valid.` }); } visit(path, TOKEN, CHALLENGE_HOST) .then(() => { res.render('pages/report', { message: `The page was visited by our admin. We'll get back to you soon.` }); }) .catch((error) => { console.error('Error visiting URL:', error); res.render('pages/report', { message: `An error occurred while visiting the URL ${url}.` }); }); }); Fichier reports.ejs : .. code-block:: console <%- include('../partials/header', { title: 'Report an Issue' }) %>

🛑 Report Incorrect Information

<% if (message) { %>
<%- message %>
<% } %>
<%- include('../partials/footer') %> Mais cela ne semble pas exploitable directement car le bot ne voit pas le message, a moins que. On sait que url.parse est déprécié : .. code-block:: console const parsedUrl = url.parse(urlString); //who cares about deprecation anyway Et surtout on ne vérifie que "http:" et pas "http://" .. code-block:: console if (!(parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:')) { return null; } - https://fr.claroty.com/team82/research/exploiting-url-parsing-confusion - https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf Après plusieurs essaies on découvre que : - http:a/test ==> http://spacefleetcommand.404ctf.fra/test - http:@test.test/a ==> http://spacefleetcommand.404ctf.frt@test.test/a - http:@ahvce.free.beeceptor.com ==> http://spacefleetcommand.404ctf.frt@ahvce.free.beeceptor.com ==> Connexion sur ahvce.free.beepceptor.com On peut donc rediriger le bot sur un endpoint de notre choix. A partir de la, on peut exploiter une CSRF pour qu'il utilise lui même /report avec une url invalide mais qui contiendra notre "XSS". Notre CSRF : .. code-block:: console
Mais il y a le CSP donc la XSS est impossible, on peut uniquement faire une injection HTML. A partir de la, on peut faire chercher au bot le flag, et tenter d'exfiltrer le contenu. La requête de recherche renvoie 200 si elle trouve un résultat et 404 si elle ne trouve rien. Ce qu'on a trouvé de mieux : https://www.cse.chalmers.se/research/group/security/pdf/data-exfiltration-in-the-face-of-csp.pdf .. code-block:: console ==> KO ==> KO ==> fonctionne dans l'injection html pour redirect ==> KO, redirection dans tous les cas que l'objet se charge ou pas ==> KO, redirection dans tous les cas que l'embed se charge ou pas ==> Ok mais inutile si on petu pas forcer soumission du formulaire, pas très utile On utilise object qui se charge ou ne se charge pas selon le résultat 200 / 404, mais on ne trouve aucun moyen d'obtenir une exfiltration même en dns-prefetch. On a trouvé ceci, peut être une dernière chance : https://github.com/cure53/HTTPLeaks/blob/main/leak.html On envoie tout en CSRF au bot Voici ce qui permet de faire des requêtes vers l'extérieur malgré la CSP : .. code-block:: console Bon maintenant comment forcer son activation ou sa désactivation ? On a remarque qu'iframe fait également une requête DNS, donc on va combiner object et iframe : .. code-block:: console