BreizhCTF 2019 – Write-Up

15 Avr 2019
Romain Koszyk
308
0

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 :

Script Back2Rootz

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 :

Script de résolution Back2Rootz

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:

Indice sur l'utilisation du MD5

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 :

Collision de condensats MD5

Il ne reste alors plus qu’à soumettre ces deux valeurs à l’application :

Script de résolution WhyMD5IsStillUsed

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.

Page d'accueil du challenge Hecoucou

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 :

Code source du challenge Hecoucou

Il est possible de réaliser une injection de commande sur le système en utilisant le saut de ligne %0a.

Injection de commande 'ls'

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 Hecoucou

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 !

Lucky Luke

 

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 :

Code hexadécimal dans les métadonnées

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 Ducky Duke

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.