Une clé USB qui ouvre des portes - Shutlock CTF 2024
First seen on July 8, 2024
Author of this writeup : Ch0ufleur
Contexte
Le Shutlock CTF 2024 est le premier CTF d’un organisme de nos cousins français, la DGSI (Direction Générale de la Sécurité Intérieure française). Ce CTF s’est tenu du 28 juin à 14h EST au 8 juillet à 14h EST.
Description
Les parties pertinentes des images servant de description sont présentées ci-dessous. Notons au passage tout le travail derrière la création d’images et de trames narratives pour certains défis de cette compétition particulière.
Outils
Résolution
Les sous-sections suivantes montrent mon cheminement pour résoudre le défi.
Type du fichier
La première chose à faire est d’inspecter le fichier image.raw qui nous est transmis par le challenge. Une bonne manière d’y arriver est d’utiliser la commande “file”, qui renvoie plus souvent qu’autrement le type du fichier en fonction de son contenu plutôt qu’en se fiant à son extension.
Démarrer avec l’image ISO
La sortie nous indique qu’il s’agirait d’un fichier .iso, ce qui correspond à une image disque. Je me dis alors qu’il doit être possible de démarrer un ordinateur depuis cette image, ce que je simule à l’aide de Oracle Virtual Box, une fois l’extension du fichier changée. En créant une nouvelle machine virtuelle (VM), je parviens à y attacher le disque .iso et à accéder au système de fichiers depuis la machine virtuelle en fonction.
Reconnaissance dans l’image et obtention du script
Une reconnaissance rapide m’amène au dossier /home, dans lequel je trouve un script caché grâce à la commande “ls -slart”.
En utilisant “less” sur le fichier pour mieux le consulter, je constate ce qui semble être du contenu en base64 qui devra être décodé.
Mon problème : pas moyen de copier coller cet énorme bloc de caractères depuis l’interface graphique de ma VM. Solution peut-être un peu radicale: je redémarre la VM en y attachant le disque .vmdk d’une autre machine virtuelle Kali, éteinte, que j’utilise à l’occasion. Cela me permet de monter ce disque sur /mnt
dans la VM ayant pour .iso celle du CTF, et d’y copier le fichier convoité. Peut-être que je me suis compliqué la vie, mais c’est ce qui me semblait le plus simple sur le moment. Tant que ça marche!
Décoder la charge utile
Une fois le fichier accessible, j’en extrais le base64 puis le décode avec Cyberchef, qui me permet de télécharger l’exécutable .elf caché derrière. Je le nomme download.elf.
Analyse de l’exécutable
ltrace download.elf
En utilisant ltrace sur l’exécutable, on remarque une sortie avec le mot de passe, ou ce qui semble l’être. Par contre, ce mot de passe ne correspond malheureusement pas au flag! Ce ne sera pas si simple… En relançant l’exécutable plusieurs fois, je remarque que le mot de passe généré est toujours différent. Bon, il faudra comprendre comment fonctionne cette génération.
Je charge l’exécutable dans Ghidra afin d’en comprendre le fonctionnement. Les créateurs du défi ont été gentils: les fonctions ont leurs noms, c’est donc bien plus simple de s’y retrouver. En parcourant les fonctions, je tombe sur init_PRNG_it-is_pretty_safe_right(), qui semble générer une séquence aléatoirement avec pour initialisation, une valeur de temps. Je me rappelle alors qu’une valeur de temps était mentionnée dans le défi (19:42:42 UTC). Ces deux informations me semblant liées, je tente d’écrire un mini script bash (ci-bas) qui configure le temps de ma machine virtuelle Kali (une nouvelle, que j’ai ouverte pour analyser le fichier binaire), pour ensuite lancer le script récupéré avec ltrace et voir comment change le mot de passe.
#!/bin/bash
sudo date -s @1719603762 # valeur en epoch secondes de 19h42:42 UTC
date # pour confirmer que la date a changé
ltrace ./download.elf
Le temps et les machines virtuelles : un petit obstacle
Ma machine virtuelle m’empêche pendant une bonne demi-heure de changer le temps malgré toutes mes tentatives; j’ai appris que Virtual Box a une option qui s’assure que le temps de la machine virtuelle soit synchronisée avec celui de l’ordinateur hôte. Il faut donc fermer la VM, désactiver l’option, et la redémarrer. La première chaîne de caractères est le nom de ma VM.
.\VBoxManage.exe setextradata "kali-linux-2024.1-virtualbox-amd64" "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1
Obtenir la moitié du mot de passe
Cela m’a enfin permis de faire fonctionner mon script, qui me montrait maintenant un mot de passe dont la partie de la fin ne changeait pas (normal, c’est toujours la même graine de génération). La première partie semblait toutefois changer depuis une liste de mots aléatoires. Après avoir trouvé une adresse web dans Ghidra, je me suis dit que la liste était récupérée depuis le web. Malheureusement, accéder à l’adresse ne me donnait rien, donc je me suis dit que la liste était sûrement dans le binaire.
Générer un dictionnaire avec le reste des possibilités
J’ai utilisé l’outil strings, que j’aurais sûrement dû utiliser plus tôt, et j’ai obtenu une liste de mots parmi plusieurs autres chaînes de caractères. En combinant cette liste d’environ 100 mots au reste du mot de passe obtenu plus tôt, cela fait une liste de mots personnalisée (de taille très très raisonnable) qu’il est possible de donner à hashcat avec le hash récupéré, fourni dans la description du défi.
Obtenir le mot de passe
Ici, user.hash est le fichier fourni dans le défi, et la wordlist est personnalisée selon ce que j’ai écrit plus haut.
hashcat -m 1800 -a 0 user.hash ../Documents/wordlist.txt --show
$6$NBYlg3a0nG8eykJg$KnzV/9n5DpRkeNHLcdXfviKsh0Z9NaPQdXg9Pd4nBOXuN6gr3dfAHxo71Y/dCGvG5kei3Y8ganUcz1RqrdTUt/:backdoor8314x9mWPW7
Et voilà! Hashcat trouve le mot de passe (backdoor8314x9mWPW7) en quelques secondes, et ce dernier correspond au flag attendu!
SHLK{backdoor8314x9mWPW7}