← Retour à la liste des WriteUps

Stéganographie Si tu chutes, c'est la tombe 100

Avatar de indyteo

indyteo

Dans ce challenge, il faut analyser cette image pour trouver le flag.

L'image de base Télécharger l'image

La première analyse (méta-données, pixels) ne montre rien de spécial. Un membre de l'équipe propose de la soumettre sur Aperi'Solve, un outil en ligne d'analyse d'image. L'outil montre des données cachées dans l'image, et il propose de récupérer le fichier :

L'extraction des données de l'image

Le fichier contient un unique lien : https://shareflag.fr/4fa90795faafca26d3d985b63488b4ff. En allant dessus, nous obtenons un fichier image qui montre un parachute semblable à celui de Perseverance.

La seconde partie du challenge Télécharger le parachute

Après quelques rapides recherches sur le fameux parachute de la NASA, je trouve les informations nécessaires pour le déchiffrer. Le concept est assez simple : des données binaires sont encodées dans les couleurs du parachute. Les données sont composées de 3 mots de 8 lettres maximum, et de coordonnées sous la forme a b c N d e f W. La première étape consiste à séparer nos paquets de données, nos presqu'octets, puisqu'il s'agit de groupes de 7 bits, séparés par 3 bits vides. Les paquets constitués uniquement de 1 représentent l'absence de donnée.

Première étape pour décoder le parachute

On saute ensuite les zones vides, qui constituent des séparateurs.

Seconde étape pour décoder le parachute

Il ne reste plus qu'à lire les bits, avec un 0 pour une zone blanche et un 1 pour une zone colorée. La lecture se fait dans le sens des aiguilles d'une montre. On obtient alors les résultats suivant :

Troisième étape pour décoder le parachute

Premier cercle (intérieur), de 1 à 7 : 0001101 0001001 0010011 0010011 0001001 0001110 0000111.
Second cercle (milieu), de 1 à 3 : 0010100 0001000 0000101.
Troisième cercle (extérieur), de 1 à 8 : 0001100 0000101 0000010 0001111 0010101 0010011 0010011 0001111 (il y a ici un doute sur le point de départ pour la lecture, il est possible qu'il faille recaler le mot à la fin).
Dernier cercle (séparé), de 1 à 8 : 0101111 0100111 0011110 0001110 0000010 0101101 0001010 0010111.

La dernière étape est maintenant de décoder ces données, la première idée étant d'utiliser les codes ASCII. Un rapide test permet d'expérimenter ceci :

let input = "0001101 0001001 0010011 0010011 0001001 0001110 0000111"
input.split(" ")
	.map(it => parseInt(it, 2))
	.map(it => String.fromCharCode(it))
	.join("")

Le résultat n'est pas aussi concluant qu'espéré : \f\x05\x02\x0F\x15\x13\x13\x0F. Pour cause, les valeurs entières sont bien trop faibles pour être des caractères dans la table ASCII. On essaye alors de faire une correspondance de type 1 = A, 2 = B, ..., 26 = Z. Pour cela, on ajoute simplement 64 à notre valeur de base, pour l'utiliser dans la table ASCII.

input.split(" ")
	.map(it => parseInt(it, 2))
	.map(it => it + 64)
	.map(it => String.fromCharCode(it))
	.join("")

Et là miracle, le terme MISSING apparaît sous nos yeux. On répète alors le même procédé en changeant l'entrée et on obtient ces résultats : MISSING THE LEBOUSSO. On comprend alors qu'il y a une erreur dans le dernier mot, et qu'il aurait fallu partir 2 presqu'octets plus loin, le terme est probablement BOUSSOLE (le bar à proximité de l'école ENSIBS).

Pour les coordonnées, c'est légèrement différent, puisqu'on s'attend à avoir des chiffres, donc on ne transforme pas en caractère.

input = "0101111 0100111 0011110 0001110 0000010 0101101 0001010 0010111"
input.split(" ")
	.map(it => parseInt(it, 2))
	.join(" ")

Ce qui donne la suite de nombres suivante : 47 39 30 14 2 45 10 23. On sait qu'elle doit contenir un N en 4ième position, et un W en dernière position, ce qui va permettre de trouver le début (on rappelle que le parachute étant un cercle, le début n'était qu'une supposition). Le N est la 14ième lettre de l'alphabet, et le W la 23ième, ce qui correspond, par chance, avec notre chaîne actuelle. En regroupant le tout au format attendu par l'énoncé, ceci donne le flag : CTFIUT{MISSING_THE_BOUSSOLE:47_39_30_N_2_45_10_W}

← Retour à la liste des WriteUps