# Writeup CTF - DRSD 9 Mars 2022 ## Introduction Ce CTF a été réalisé dans le cadre d'une semaine de visite par les différents bureaux de la DRSD. Dernier de la semaine, celui-ci est le plus complet que j'ai pu voir. Alliant plusieurs catégories accessibles à tous, j'ai pu y trouver mon bonheur en tant qu'habitué. Mon nom d'utilisateur était **user27** ### Résultats ![](https://i.imgur.com/RkaOlGB.png =600x) ## Challenges #### Introduction - 0 points ![](https://i.imgur.com/dBPxWIK.png =200x) Rien de bien compliqué ici, 'suffit de lire la consigne et je me lance ! Flag : **Go** #### Web - Administre moi ça ! ![](https://i.imgur.com/rFWWdyw.png =300x) Je me retrouve sur une page de connexion, indiquant être réservée aux administrateurs. J'ai tenté le classique `admin@localhost` mais pas cette fois le créateur du chall est allé plus loin. Je suis alors immédiatement allé dans les cookies : | Nom | Valeur | | -------- | -------- | | Auth | user | Ça sent bon. Rien de bien sorcier ici, j'ai logiquement changé en admin puis refait la requête et bim ! Flag : **DRSD{SuPer_Cook1e}** #### Web - Administre moi ça ! (suite) ![](https://i.imgur.com/NFmNdQ1.png) Une fois sur l'interface d'administration, on a une **navbar** et un message qui nous dit que *le service de surveillance est en maintenance* (et alors? ). J'inspecte le bouton désactivé (coucou [Rootme](https://www.root-me.org/fr/Challenges/Web-Client/HTML-boutons-desactives)): ```htmlembedded= <a class="nav-link disabled" href="commande.html">Surveillance</a> ``` Je peut observer une super interface admin, qui doit être sécurisée parce je ne peut pas mettre les commandes que je veut : `ping`,`free`,`top`. J'ouvre immédiatement [burpsuite](https://portswigger.net/burp), je fais une requete pour effectuer la commande `ping` puis j'envoie ma requête dans le répéteur. J'essaie de remplacer `commande=ping` avec `commande=ls` mais : erreur ! Je laisse alors le ping dans ma requête, et je met un ';'. ```ping;ls``` m'affiche le resultat du ping, et les fichiers du repertoire courant, dont commande.php. Je décide de l'afficher `ping;cat commande.php` Après avoir scruté de nombreuses minutes, je remarque une ligne qui m'a échappée : ```php= <?php //DRSD{1nj3ction_Code} ``` Flag : **DRSD{1nj3ction_Code}** #### Reverse - Zoo Le fichier Zoo.exe ne s'xecute que sur windows. Je dois donc utiliser wine pour l'utiliser. On m'invite à indiquer quel est mon animal préféré, avec un dessin en ascii art. J'essaie quelques tests, notemment d'overflow la réponse mais il y a un contrôle. J'ouvre donc mon fichier dans Cutter. Je découvre dans le main un appel à la fonction `_processAnswer()` avant de me dire si j'ai le flag ou non. ```c _printf ("- Les %s ?\n"); eax = &s; eax = _processAnswer (eax); var_2ch = eax; ``` Cette fonction définit plusieurs variables, et fais des tests avec de nombreuses opérations d'ajout et de suppression de valeur. ```c #include <stdint.h> int32_t processAnswer (char * user_entry) { var_eh = 0x70; var_dh = 0x64; var_ch = 0x71; var_bh = 0x6a; var_ah = 0x72; var_9h = 0x78; correct = 1; eax = user_entry; eax += 9; eax = *(eax); if (al != 0x73) { correct = 0; } eax = user_entry; eax += 8; eax = *(eax); if (al != 0x65) { correct = 0; } eax = user_entry; eax += 7; eax = *(eax); al >>= 1; if (al != 0x3a) { correct = 0; } eax = user_entry; eax += 6; eax = *(eax); eax = (int32_t) al; eax <<= 2; if (eax != 0x1cc) { correct = 0; } user_entry = 0; while (user_entry <= 5) { edx = user_entry; eax = user_entry; eax += edx; eax = *(eax); eax = (int32_t) al; ecx = eax + 3; edx = &var_eh; eax = user_entry; eax += edx; eax = *(eax); eax = (int32_t) al; if (ecx != eax) { correct = 0; } user_entry++; } eax = correct; return eax; } ``` La fonction **processAnswer** prend un pointeur de caractère (user_entry) en entrée et renvoie une valeur int32_t. La première partie du code initialise certaines variables (var_eh, var_dh, var_ch, var_bh, var_ah, var_9h et correct). On vérifie par la suite s l'index 9 de la chaîne d'entrée est '**s**'. Ensuite, la fonction vérifie si l'index 8 de la chaîne d'entrée est '**e**'. La fonction vérifie alors si le résultat du décalage vers la droite sur l'indice 7 est égal à 0x3a 0x3A << 1 = 0x74 ('**t**'). La vérification suivante consiste à voir un décalage à gauche de l'index 6 est égal à 0x1cc << 2 = 0x73 ('**s**'). Notre flag commence à sortir le bout de son nez !! La dernière partie de la fonction est une boucle qui répète les 6 premiers caractères de la chaîne donnée.. Pour chaque caractère, vérifiez si la somme de la valeur ASCII + 3 est égale à la valeur de la variable à l'offset correspondant. On applique : '**m**' (0x6d) + 3 = 0x70 (var_eh) '**a**' (0x61) + 3 = 0x64 (var_dh) '**n**' (0x6e) + 3 = 0x71 (var_ch) '**g**' (0x67) + 3 = 0x6a (var_bh) '**o**' (0x6f) + 3 = 0x72 (var_ah) '**u**' (0x75) + 3 = 0x78 (var_9h) Flag : **DRSD{mangoustes}** #### Reverse - India Pale Ale J'ai avec moi une application déstinée à être utilisée sur MACOS (extension [.ipa](https://fr.wikipedia.org/wiki/.ipa)) J'extrait les différentes parties du fichier dans le but d'extraire la Main avec la commande `binwalk --dd=".*" breakmedaddy` ```shell user@LAPTOP-MrRobot:~$ binwalk breakmedaddy DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 2140 0x85C Unix path: /usr/lib/dyld 78813 0x133DD XML document, version: "1.0" 79405 0x1362D Certificate in DER format (x509 v3), header length: 4, sequence length: 1105 80514 0x13A82 Certificate in DER format (x509 v3), header length: 4, sequence length: 1211 81189 0x13D25 Certificate in DER format (x509 v3), header length: 4, sequence length: 260 81729 0x13F41 Certificate in DER format (x509 v3), header length: 4, sequence length: 1478 82545 0x14271 Certificate in DER format (x509 v3), header length: 4, sequence length: 273 83571 0x14673 XML document, version: "1.0" ``` L'addresse 0x85C à l'air intéressante ! J'ouvre mon fichier `85C` sur cutter, me rend dans la partie 'strings' et je pars à la recherche d'informations croustillantes. Un peu plus bas, à l'addresse `0x00006b4d`, on trouve ceci : ![](https://i.imgur.com/LPp3b85.png) J'essaie `babiesareevil` comme flag, et bim ! Flag = **babiesareevil** #### Reverse - Android Secure ![](https://i.imgur.com/ZnkCiOh.png =300x) Dans l'archive donnée, 2 fichiers sont à notre disposition ```shell= $ ls app.apk Secret_file ``` J'upload l'apk sur [javadecompilers.com](https://javadecompilers.com ) et je trouve dans les sources le package com.ctf avec le fichier `uncrypt.java` Je me retrouve avec une fonction interessante : uncrypt, qui contient la clé de chiffrement AES Je vais la modifier un peu pour la faire fonctionner : ```java=9 String flag_path = "/home/63teft/Desktop/flag"; public uncrypt(File file) { byte[] data = readfile(file); SecretKeySpec key = new SecretKeySpec("T'esmauvaisJack!".getBytes(), "AES"); writefile(decrypt(data, key).trim()); } ``` J'ai du retirer la notification Toast et le Context qui n'ont tous deux plus lieu d'être puisque nous sommes sur ordinateur. Je crée la fonction main qui n'existe pas : ```java=56 public static void main(String[] args) { File encryptedFile = new File("Secret_file"); uncrypt decryptor = new uncrypt(encryptedFile); } ``` ```java uncrypt.java``` Et je me retrouve avec une jolie recette de blanquette ! Flag : **DRSD{AnDr0iD_S3cuR3}** #### Forensique : Dumping Téléphone - Android (série) ![](https://i.imgur.com/WklvgId.png) Je suis sur les traces d'un certain **Sergei**. Comme je suis un enorme flemmard quand il s'agit de chercher a la main, je vais faire une commande qui va chercher a ma place. Les fichiers du dump possèdent pour la plupart du texte en clair, je vais donc chercher tous les fichiers avec le nom de ce chenapant : ``` find . -type f -exec grep -l "Sergei" {} +``` Je trouve un joli fichier XML : `./data/system_ce/0/shortcut_service/packages/com.whatsapp.xml` J'extrait les strings et cherche une occurence pour `Sergei`. Alternative : J'aurait pu utiliser `contactsv2.db`. FLAG : **0758976294** ##### Suite ![](https://i.imgur.com/hQKqWSK.png) J'imagine ici que je dois accéder à des conversations. Je vais donc chercher à lire les messages échangés. Je sais que le fichier `./data/data/com.android.providers.telephony/databases/mmssms.db` possède les sms/mms echangés. Je l'ouvre donc avec DB browser for sqlite, et je découvre, stupéfait, ce message : `Bonjour camarade, effectivement je suis très intéressé. Pour plus de sécurité je te demande de me contacter sur WhatsApp, appelle moi par mon pseudonyme grizzly.` Flag : **grizzly** ##### Suite ![](https://i.imgur.com/6lUxtJu.png) Je dois ici récupérer les pièces jointes (images, messages vocaux...) J'accède alors à la base de données média de Whatsapp `data/data/com.whatsapp/databases/media.db` Je regarde la table `shared_medias_ids` et on découvre un message vocal nommé `PTT-20230124-WA0001.opus`. J'y accède et le flag est énoncé à l'oral. Flag : **chipolata** ##### Suite ![](https://i.imgur.com/WwgRkrN.png) Je cherche un un zip envoyé par telegram. J'accède alors au stockage local du telephone : `/data/media/0/Android/data/org.telegram.messenger.web/files/Telegram/Telegram Documents/4_5945261333631995949.zip` ``` >unzip 4_5945261333631995949.zip Archive: 4_5945261333631995949.zip [4_5945261333631995949.zip] tarif.txt password: chipolata ``` Fichier : ``` 2000€ fichier secret 4000€ fichier tres secret ``` Le tarif voulu est ici 2000€ pour un fichier secret. Flag : **2000** #### Forensique : Dumping Téléphone - IOS (série) ![](https://i.imgur.com/FDSkKjo.png) Ce premier challenge ressemble au premier de la série android. Je sais que sur IOS, l'organisation des fichiers est différente, mais le contenu doit être semblable. Je peut donc utiliser la même stratégie. ``` find . -type f -exec grep -l "Sergei" {} +``` Ce résultat m'interesse `./private/var/mobile/Containers/Shared/AppGroup/6D6C6D97-0B6E-4D79-ACE9-631148A96712/ContactsV2.sqlite` La ligne du contact voulu apparait alors | ZSEARCHTOKENLIST | ZWHATSAPPID | | -------- | -------- | | kremlevka sergei | 33758976294@s.whatsapp.net | Flag : **0758976294** ##### Suite ![](https://i.imgur.com/6OgPGsh.png =300x) Retournons sur les résultats de la commande. Une nouvelle ligne m'intrigue : `./private/var/mobile/Library/SMS/sms` Il doit y avoir quelque chose d'interessant ici... par exemple *sms.db* Et en effet, on y trouve un message explicite : ``` Bonjour camarade, En effet, mais pour plus de sécurité, contact moi sur WhatsApp et appel moi par mon pseudonyme "Ursus" ``` Flag : **Ursus** ##### Suite ![](https://i.imgur.com/mjqJ8bZ.png =300x) Cela ressemble VRAIMENT au challenge précédent ! Je me rend manuellement dans le repertoire whatsapp afin de regarder si un fichier audio ne serait pas présent. ET BIGO ! Dans le répertoire précédemment visité, on trouve des repertoires : `Message/Media/<identifiant>/f/8/f892c5f9-fbe9-40de-b823-72788da68b87.opus` Cette fois ci on reste dans le piquant, le flag est... Flag : **chorizo** ##### Suite ![](https://i.imgur.com/2NZJ9YO.png =300x) Je découvre dans le repertoire `./private/var/mobile/Containers/Shared/AppGroup/0150B24B-6B10-4436-85D1-2A1336F5490C/telegram-data/account-929481405905042963/postbox/media/` plus d'une centaine d'archives telegram. En fin de liste, je trouve deux images, envoyées par **Sergei** qui me font penser que mon archive doit se trouver ici. Je fais un coup de binwalk au hasard sur l'archive voisine qui annonce avoir des données compréssées ! Je la dézippe, entre le mot de passe précédement trouvé et découvre le tarif : Flag : **1950€** ##### Suite ![](https://i.imgur.com/hIaC6rF.png) Après avoir lu la documentation donnée et récupéré le fichier keychain, je cherche la clé correspondant au v_data de `R1JEQkRhdGFiYXNlQ2lwaGVyS2V5U3BlYw==` Il s'agit de `l/o1TlWNbzxhWDS2fXmCBFezcRuqApIkuufbG/9/Nr9ysLPE+314uExBaiifQ62e` J'effectue les commandes nécéssaires pour traduire la clé : ```shell= echo -n l/o1TlWNbzxhWDS2fXmCBFezcRuqApIkuufbG/9/Nr9ysLPE+314uExBaiifQ62e|base64 -d | xxd -p -c 48 > 97fa354e558d6f3c615834b67d79820457b3711baa029224bae7db1bff7f36bf72b0b3c4fb7d78b84c416a289f43ad9e ``` Je lance ensuite sqlcipher ``` > sqlcipher signal.sqlite` > PRAGMA key="x'97fa354e558d6f3c615834b67d79820457b3711baa029224bae7db1bff7f36bf72b0b3c4fb7d78b84c416a289f43ad9e'" > PRAGMA cipher_plaintext_header_size = 32; .tables (Mon sqlcipher est cassé ca n'a pas marché) ``` #### Bonus - We need to go deeper ![](https://i.imgur.com/dBC9mOy.png =350x) Page d'accueil, `CTRL` + `U`, `CTRL` + `F`, `DRSD`. Flag = **DRSD{HTML_C0mm3nt}** ![](https://i.imgur.com/A7bL6j9.png) ####