BreizhCTF 2019 – Write-Up
L’équipe Pentest de Digitemis était présente pour la seconde fois au BreizhCTF. Cette édition était encore une fois organisée et animée par SaxX et Kaluche, à nouveau sur le campus de Beaulieu de l’université de Rennes.
Nous vous proposons de revenir sur l’évènement au travers d’un court write-up de quelques challenges choisis.
Misc – 25 pts – hash_breaker
tl;dr
Des hashes de mots de passe de 1 caractère.
Explications
On récupère une liste de hashes, on les numérote et on les passe à John the Ripper, en spécifiant le format (raw-md5) :
En formatant un peu le résultat ordonné en sortie à coup de cut et de tr, on a notre flag :
Flag =>bzhctf{one_char_password_oh_god}
Misc – 25 pts – Back2Rootz
tl;dr
Ecrire la fonction inverse du XOR pour récupérer le flag.
Explications
On récupère le fichier suivant :
On comprend rapidement qu’une opération XOR a été appliqué sur chaque caractère. Le résultat est alors encodé en base64 et concaténé pour former la chaîne base64 présente dans le fichier.
L’opération XOR est réversible, il suffit d’appliquer l’opération inverse pour obtenir le flag. Ci-dessous, un petit script permet d’obtenir le flag :
Flag => BREIZHCTF{baks_t0_roots_with_some_simple_0n3_l1ner}
Misc – 100 pts – WhyIsMD5StillUsed
tl;dr
Contourner le mécanisme d’authentification via une collision de MD5.
Explications
En arrivant sur l’interface d’authentification du challenge, on aperçoit un indice dans les sources:
On peut écarter la possibilité d’abuser d’un type juggling php sur les deux condensats MD5 puisque la comparaison php est stricte ‘===’. Il est donc nécessaire d’obtenir deux valeurs différentes dont le hash MD5 est identique !
MD5 est un algorithme de signature vulnérable au sens cryptographique, en effet des collisions existent !
Les valeurs brutes des deux chaînes hexadécimales suivantes produisent le même condensat MD5 :
Il ne reste alors plus qu’à soumettre ces deux valeurs à l’application :
Flag => bzhctf{TEUTEUTEU_what_havent_you_yet_understand?!STOP_USING_MD5!!!}
Reverse – 25 pts – Werizchacha
tl;dr
Hacking like it’s 1998 with LD_PRELOAD.
Explications
Le challenge consiste en un binaire ELF 64bit qui attend le flag en argument. Un analyse rapide du code avec objdump permet de constater qu’il y a un appel à strcmp, on voit donc venir la simple comparaison de chaine…
Nous implémentons donc une fonction répondant exactement au prototype de strcmp, mais qui affiche simplement la première chaîne passée en entrée.
On compile ça au sein d’une bibliothèque partagée, on exécute le binaire en surchargeant strcmp grâce à LD_PRELOAD et on obtient le flag :
Flag => BREIZHCTF{k3y_H1d1ng_in_Pl41n_SiGhT}
Pwn – 200 – GuessMe
tl;dr
Un script demande la valeur hexadécimale du contenu d’un fichier qu’il vient de créer.
Explications
L’exécution du script « main » permet d’accéder au challenge.
Le script crée un fichier « /tmp/guessme-98R8wA » au début de son exécution. Celui-ci est accessible en lecture.
En ouvrant un deuxième terminal, nous pouvons afficher le contenu du fichier en hexadécimal.
En formattant l’hexadécimal sur une seule ligne, il est possible de le copier-coller entre les deux accès. Le timeout de session étant court, il faut être rapide…
Flag => BZHCTF{oHe_oHe_au_BaL_uMaSKe}
Web – 50 pts – Hecoucou
tl;dr
Contourner le filtrage en place pour injecter des commandes systèmes.
Explications
L’application nous permet « a priori » de ping un hôte sur le réseau.
Dans les faits, il semble que les règles de filtrage réseau sur la machine l’empêche de réaliser de telles actions.
On peut observer le code source de l’application en se rendant sur l’URL suivante :
Il est possible de réaliser une injection de commande sur le système en utilisant le saut de ligne %0a.
Pour éviter les problèmes d’URL encoding sur le caractère ‘%’ de ‘%0a’, nous avons inséré cette valeur au travers du proxy Burp, mais il est évidemment possible de le faire autrement.
Nous obtenons donc la liste des fichiers présents à la racine de l’application Web.
NB: Pour ne pas heurter la sensibilité du lecteur, une partie de ces fichiers a été floutée.
Enfin, il est possible de récupérer le flag du challenge en lisant le contenu du fichier flag.php :
Flag => BREIZHCTF{Try_Th15_K1nd_0f_Tr1cKs_ABOUT_C0mm4nd_3x3cu7i0n}
Web – 50 – SecureuhAccess
tl;dr
Contourner les filtrages en place pour pouvoir accéder au contenu du serveur web.
Explications
Lors de l’accès à la page web du challenge, le serveur nous renvoie qu’il faut choisir « [RennesB0t] » comme navigateur web.
En modifiant la valeur « User-agent » de notre requête en « RennesB0t », nous accédons au deuxième niveau du challenge. La page n’est alors accessible que depuis l’adresse locale du serveur.
Nous ajoutons alors l’en-tête « X-Forwarded-For: 127.0.0.1 » qui permet d’indiquer au serveur que nous venons de son adresse locale. Nous passons à l’étape 2 du challenge.
La dernière étape du challenge indique que seul le port 41814 n’est autorisé à communiquer. En regardant l’indice, l’organisation précise qu’il ne faut pas avoir peur de bruteforcer l’URL. Où? Quand? Comment? Nous ne savons pas. En tentant un bruteforce improbable de connexions successives et en oubliant le script dans un coin, le flag est apparu deux fois comme par magie.
Flag => bzhctf{th47_w4s_An_EZ_PIZI_0n3}
Web – 100 – Ziziping
tl;dr
Contourner le filtrage en place pour injecter des commandes systèmes.
Explications
L’application permet de ping un hôte sur le réseau en sélectionnant le nombre de requêtes à effectuer.
En regardant l’URL, on constate que les paramètres « host » et « count » sont fournis. La synthaxe de ping est en général comme suit : « ping <host> -c <count> ». Il est alors possible d’injecter une commande système à la suite en passant la symbole « ; » , indiquant une fin d’instruction, puis la commande. Ici, on affiche le contenu du répertoire courant.
Nous pouvons alors afficher le contenu du fichier « flag.txt » en utilisant les redirections (l’espace étant encodé, il n’est pas reconnu par le système).
Flag => bzhctf{backticks_are_3vil_think_about_use_them;)}
Web – 250 pts – Born To Lose
tl;dr
Challenge de sécurité Web consistant à contourner une mire d’authentification.
Explications
Pour ce challenge, nous disposons du code source de la page :
Nous remarquons immédiatement l’ouverture d’une base de données SQLITE stockée dans le même répertoire que le code source de la page principale de l’application WEB.
« new PDO(‘sqlite:’.dirname(__FILE__).’/chall.db’); »
Nous essayons de télécharger la base de données :
Ça commence plutôt bien, inspectons maintenant son contenu.
Enjoy, 250 points.
Un peu trop facile, nous soupçonnons une erreur dans la conception ou un TROLL en rapport avec le titre du chall « BORN TO LOSE ».
Steg – 25 pts – Ducky Duke
tl;dr
Une chaîne ASCII ART encodée est présente dans les métadonnées de l’image.
Explications
Nous débutons ce challenge au travers de l’image de notre cher Cow-Boy !
En observant les métadonnées de l’image, on découvre la présence d’une chaîne hexadécimale dans le champ commentaire :
En décodant la chaîne hexadécimale, on obtient une chaîne en base64. Cette dernière nous permet d’obtenir une chaîne ASCII ART.
Flag => BREIZHCTF{W17HL0V30URDUCMACDUCKD0T!}
Prog – 75 – Cococomparizon
tl;dr
Les temps de réponse du serveur permettent d’obtenir le flag.
Explications
Lors de la connexion au service, le code source de l’application est affiché puis exécuté.
En lisant le code, on remarque que celui-ci compare les lettres une par une avec le flag. Lorsque les deux caractères sont identiques, le script attend 0.25 secondes avant de passer en caractère suivant. Dans le cas contraire, aucun délai n’est observé.
En développant un script permettant de bruteforcer chacun des caractères et incrémentant la valeur du temps attendu, nous nous basons sur le temps pour identifier chacune des lettres.
Nous reconstituons lentement (vraiment très lentement) le flag final.
Flag => bzhctf{tim1ng_l0l}
Prog – 100pts – Tendu comme des strings
tl;dr
Challenge de programmation nécessitant de la reconnaissance de texte dans des images.
Explications
Pour ce challenge de programmation WEB, nous devons nous connecter à une ressource accessible en HTTP et concaténer deux strings en moins d’une seconde.
Pour récupérer le FLAG, nous devons répéter cette opération trois fois. La difficulté repose sur la récupération des deux strings contenues dans deux images.
Pour récupérer le texte contenu dans les images, nous décidons de faire de la reconnaissance d’image avec la librairie tesseract (https://github.com/tesseract-ocr/tesseract).
Le script python suivant nous a permis de passer les trois étapes du challenge :
Nous lançons le script et quelques secondes plus tard nous obtenons le FLAG.
Crypto – 50pts – ASR
tl;dr
Décrypter un message chiffré grâce à l’algorithme RSA en possédant la clé publique.
Explications
Pour ce challenge, deux fichiers sont à notre disposition, une clé publique « pub.key » et un message chiffré « enc ».
Nous devons exploiter une faiblesse dans RSA qui ne doit pas être trop compliqué vu le faible nombre de points accordés au challenge.
L’objectif des CTF est d’aller le plus vite possible, on commence par tester un outil qui parfois fait le café : RsaCtfTool (https://github.com/Ganapati/RsaCtfTool).
Cet outil peut exploiter des vulnérabilités connues à notre place.
Enjoy, l’outil RsaCtfTool arrive à récupérer la clé privée depuis la clé publique.
On déchiffre le message avec la clé privée pour récupérer le Flag.
Derniers articles
Anticipez, réagissez, survivez : élaboration d’un PCA/PRA proactif
Face aux menaces multiples, un PCA bien construit peut être la différence entre la survie et l’effondrement de votre entreprise.
Sécuriser votre environnement cloud : stratégies essentielles et tests d’intrusion
Découvrez les meilleures pratiques pour sécuriser vos données cloud avec des stratégies de protection et des tests d’intrusion efficaces.