Principe:
Exploiter un input() python… Pour ma part, en lisant le flag bit-à-bit
Le challenge
Le challenge demande de "battre" un algorithme à un jeu de
Pierre-Papier-
Ciseaux
Hallebarde
Vous verrez beaucoup parler de "Hallebarde" ici car c'est le nom du "groupe de vilains hackers"
qu'on est censé combattre dans la trame de fond (le Lore) du CTF
L'algorithme
D'après
les sources (dispo ici),
l'algo est purement imbattable et des essais le confirme
En essayant diverses entrées qui ne soient pas celles attendues (1 ou 2 ou 3),
on obtient des erreurs
On note aussi la présence d'une option "-u" dans le shebang du fichier,
mais je n'en ai pas tiré grand chose
Chose intéressante, en entrant des lettres, le script nous répond
que les symboles correspondants sont indéfinies, comme s'ils les interprêtait sous forme de variables
En essayant avec choix, on voit que l'entrée est interprêtée comme du python,
puisqu'ici, la variable choix est un dict (dictionnary, aka, un tableau associatif)
Fichier du flag
Puisqu'input interprête notre entrée comme du Python, essayons de lire le contenu
de "flag.txt": en local, ça marche
Pas avec le challenge en ligne! Probablement car stderr ne nous est pas retourné
bit-à-bit
Plutôt que de gratter une nouvelle piste, j'ai décidé de chercher le contenu du fichier…
bit à bit!
De manière générale, on a ici un "oracle" capable de nous renvoyer 3 valeurs: Pierre, Papier ou Hallebarde
(en fonction de ce qu'on a "choisi" de jouer). On peut donc extraire un "trit" d'information à chaque fois.
Comme c'est peu pratique, j'ai considéré qu'on a ici un oracle renvoyant deux états (Pierre ou Papier),
donc un "bit" d'information pour chaque entrée
Lancement
Ayant généré ma liste de commande, je la lance contre le challenge du serveur, et je stocke
dans un fichier les réponses du type "Vous avez choisi…"
Si la réponse est "Vous avez choisi: Pierre" à la i-eme question, c'est que le i-eme bit vaut 0, sinon, 1.
J'ai répété mon payload 50 fois, considérant que le fichier ferait moins de 50 caractères
Flag
Un premier essai fut un ratage complet: ce que je décodais n'avait aucun sens
Je ne saisis pas pourquoi ce premier essai est raté
Après un second essai, le flag est tombé:
404CTF{cH0iX_nUm3r0_4_v1c701r3}
Vu le faible nombre de points du challenge, je sais qu'il existe plus simple
(on doit pouvoir injecter le flag dans la liste des choix par exemples),
mais j'aime bien cette méthode, et je ne l'ai pas vue chez les autres, donc, je la garde :)