En construction (Web) - 404CTF 2022

En construction (Web) - 404CTF 2022

Fichiers du challenge Principe:
Identifier que le HTTP status code 2xx sert à passer un message encodé en ASCII par blocs de 9 bits (et non 8 bits)

Le challenge

Un site web est utilisé pour diffuser un message secret: retrouvez-le!

Le site

Le site semble assez vide, mais on a deux pages en plus de l'accueil
Un coup d'oeil au robots.txt ne donne rien

Page d'admin

Dans les sources de la page d'accueil, on trouve la mention d'une page d'admin
Mais celle-ci semble être là juste pour nous troller

Faire défiler les pages

Au vu des URLs /page/1 et /page/2 on peut requêter les N premières pages

Toutes les pages semblent répondre pareil, mais regardez bien: la page 48 manque! Il se passe un truc pour cette page…

Jamais 2 cent 4

En allant voir la page 48, on s'aperçoit que le serveur répond une HTTP 204 (No Content), d'où l'absence de body dans la réponse
Je relance le même genre de requêtes sur toutes 300 premières pages, et j'observe plusieurs pages sans réponse mais aucun pattern ne se détache
En allant voir la page /page/404 (car je me dis: peut-être que le numéro de page et le HTTP response code ont un lien), je reçois une HTTP 240 UNKNOWN

HTTP 204 n'est pas définit par la spécification HTTP. C'est un code custom du site, et un bon indice pour dire "il y a un truc avec les response code HTTP"

Les HTTP response codes

Je relance alors le même scan, mais je récupère cette fois les headers (curl -I): les response code HTTP varient d'une requête à l'autre

Décoder

Collectant les HTTP response codes, j'essaie alors de trouver la clef de leur déchiffrement: est-ce un code ASCII (à 200 près)? non

Le -200 est là car les codes HTTP "success" sont de la forme 2xx, donc, seul le xx peut être arbitrairement choisi pour passer un message

Via un shell script, je dump alors un bon millier de pages, et je trouve une répétition: les mêmes codes reviennent en boucle
J'observe alors qu'aucun 8 ni 9 n'apparait dans les codes: on dirait que le xx dans 2xx est peut-être une valeur octale

Décodage

J'ai cherché des dizaines de variantes de codes possibles… la première fut une analyse de fréquence, pour voir si 1 code = 1 lettre, mais la répartition est mauvaise
Substituer certains codes par un espace donnait des mots bien trop longs quelque soit le code remplacé, donc la substitution monoalphabétique ne semblait pas être la bonne solution
Dans le doute, j'ai cherché à faire apparaitre des mots par endroits et à faire les remplacements correspondants, mais cela ne mena nulle part
J'ai aussi tenté un base64 -d mais là encore, rien
Ne sachant pas si le premier caractère de mon base64 était le bon, j'ai aussi essayé des variantes en partant du 2e, 3e, etc code: rien
Pour des pages d'index négatives, on récupère aussi les mêmes codes, donc, il n'y a probablement pas de lien entre l'index de page et le code HTTP

Il y aurait pu avoir un lien, du type XOR

Je vérifie au passage que même avec d'immenses valeurs d'entiers, le cycle reste présent (il y aurait pu y avoir des écarts à partir d'une valeur donnée, ou un overflow, mais rien)
J'ai continué ainsi de chercher des variantes à coups de base64 en décalant chaque code de 1, 2 3 etc, générant des dizaines de fichiers pour tenter de trouver un format convenable, partant sur un peu n'importe quoi…

Et je n'ai pas flaggué…

Binaire

En fait, après la fin du flag, il s'avère que je n'étais pas passé loin. Parmi mes tests, j'avais tenté de passer de la base 8 à la base 2 histoire de voir si je trouvais un pattern en binaire, mais j'ai cherché trop loin (j'ai même pensé que le binaire pouvait être un QR code, mais impossible d'en faire un carré potable!).
Il suffisait de regrouper les valeurs binaires par 9, et d'en prendre la correspondance ASCII

J'aime faire du PHP!
					php -r '$c=explode(" ",file_get_contents("codes-list.txt"));\
					$c=array_map(function ($x){ return str_pad(base_convert(((int)$x) - 200,8,2),6,"0",STR_PAD_LEFT);},$c);\
					$c=implode("",$c);\
					$c=str_split($c,9);\
					$c=array_map(function($x){ return chr(base_convert($x,2,10));},$c);\
					var_dump(implode("",$c));'
				
Le message secret:
réunion Hallebarde le 26 juin à 13h. Venez nombreux. N'oubliez pas le mot de passe qui vous permettra d'entrer dans la salle secrète : 404CTF{Dr0l3_D3_m0Y3N_d3_f41r3_P4sS3r_d3S_d0nN33s_n0N?}. Longue vie à Hallebarde

Fichiers du challenge

↩ Retour à la liste des challenges

⇇ Retour à l'accueil