Skip to content

#OVHack : récit d’un « petit » CTF organisé par OVH

Attention ! Ce contenu a été publié il y a 11 ans. Merci de lire cette page en gardant son âge à l'esprit, son contenu étant potentiellement obsolète.

OVH nous à proposé du Lundi 17 juin au Jeudi 20 juin un petit challenge CTF en marge de la Nuit du Hack 2013 : l’#OVHack Contest 2013  !

J’y ai participé et je fais partie des 16 gagnants, à travers ce billet je vous propose de vivre ce challenge de mon point de vue et si vous l’avez tenté sans y arriver, de connaître les solutions aux différents problèmes posés.

Step 1 : « follow the white rabbit »

Sur la page d’accueil de l’#OVHack, on nous indique ceci :

This website has been compromised. Heard that some obfuscated content was hidden somewhere around here… Just follow the white rabbit.
FR : Ce site a été compromis. Il parait que du contenu « brouillées » est caché quelque part par là … Il suffit de suivre le lapin blanc.

Suivre le lapin blanc… Mais encore ?

Pour cette partie, j’ai un peu de chance, en effet j’ai un réflexe assez « étrange » : je ne peux m’empêcher de regarder à quoi ressemble la source d’un site quand je le visite pour la première fois…

BINGO ! Le lapin « blanc » se trouve dans le code source de la page http://www.ovhack.com/contest.html !

STEP 1 - The white rabbit
Comme vous pouvez le voir sur cette capture écran, il englobe une image nommée « ovhacked ».

Step 2: Et si on jouait en hexadécimale ?

Téléchargeons cette image pour voir…

ovhackedRien d’extraordinaire à première vu…

Par curiosité, ouvrons cette image dans un éditeur hexadécimal…

image ouverte dans editeur hexadécimalComme vous le savez peut-être déjà, chaque fichier dispose de sa propre signature, par exemple si vous regardez attentivement la capture d’écran ci-contre, vous remarquerez le « %PNG » qui signifie « ce fichier est une image PNG ».
En plus de sa signature, un fichier à des « marques » de début et de fin de fichier.

Cherchons donc sur Google quelle est la marque de fin d’un fichier PNG…

D’après la page https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header, « IEND » marque la fin d’un fichier au format PNG.

Effectuons donc une recherche dans notre éditeur hexadécimal :

iendOn peut voir que le fichier continu… ce qui n’est pas normal.

En examinant un autre fichier PNG, je m’aperçois que 4 octets suivent le IEND : ®B`‚ nous allons donc les ignorer pour la suite.

Prenons les 4 octets suivants la marque de fin de notre image et effectuons une recherche sur Google.

D’après les résultats de recherche, seuls les 3 premiers octets définisse le format de fichier recherche qui n’est autre qu’un fichier GZ, une archive au format GZIP.

Supprimons maintenant la totalité de l’image dans notre éditeur et ne gardons que ce qui suit « IEND®B`‚ », enregistrons ce fichier au format GZ et tentons de l’ouvrir avec 7-Zip :

7zJe crois que nous sommes sur le bon chemin !

Extrayons maintenant ce fichier et ouvrons le :

hex icag

Alors là, si vous êtes comme moi, vous vous dites « WHAT THE FUCK IS THAT ?! ».

Bon… Tentons de décodé tout ça en base64 pour voir :

decoded
Rien qui semble très utile à première vu… mais copions tout ça dans notepadd++, on sait jamais !

Là par contre, on remarque déjà que tout est sur une seule ligne, mais aussi qu’il n’y a qu’un seul « + » dans tout le fichier… Tentons de placer des retours à la ligne manuellement…

BINGO ! Les lettres OVH commence à se former à l’écran ! Continuons… et là c’est un lien ovh.to complet qui apparaît : http://ovh.to/qPHdnVFC.

Step 3 : follow the white rabbit the hidden link

Rendons nous sur la page http://ovh.to/qPHdnVFC qui n’est autre qu’une news OVH : http://www.ovh.com/fr/all/a1084.impression-3d-test-ovh.

Comme pour la première étape, allons faire un tour du côté de la source de la page…

Bingo, un nouveau lapin et un petit texte l’accompagnant afin de nous féliciter !

src

En scrollant un peu le code de la page, mon regard est immédiatement attiré par ceci

<span ndhid= »2k13#1″>t</span>

On comprend assez rapidement que c’est en rapport avec le #OVHack Contest et surtout, il n’y en a plusieurs, tous numéroté !

Prenons donc l’ensemble des lettres contenues dans toutes les balises span, ce qui nous donne à nouveau un lien : http://ovh.to/gfexdsai

On se rend sur la page, on ouvre directement la source et on se rend compte que là aussi il y a des lettres à remettre dans l’ordre.

A nouveau, un lien ovh.to, en réalité il nous faudra recommencer cette étape 10 fois, chaque lien nous envoyant vers une autre page et ainsi de suite.

http://ovh.to/gfexdsai => http://www.ovh.com/fr/all/a1036.ovh-derniere-innovation-ethylcooling

http://ovh.to/ojasuomn => http://www.ovh.com/fr/all/a1037.ovh-nouveautes-telephonie-voip-ovh

http://ovh.to/gjfrecsd => http://www.ovh.com/fr/all/a1040.bilan-datacentre-ovh-usa-canada

http://ovh.to/nbcerfsq => http://www.ovh.com/fr/all/a1100.eoliennes-ovh-energie-renouvelable

http://ovh.to/pmldrtac => http://www.ovh.com/fr/all/a895.hubic_une_premiere_annee_epique

http://ovh.to/iAdlpmcd => http://www.ovh.com/fr/all/a923.cybersecurite_a_vous_de_placer_le_curseur

http://ovh.to/efroplsa => http://www.ovh.com/fr/all/a955.nouvelle_api_chacun_son_160ovhworld160

http://ovh.to/uiodPsua => http://www.ovh.com/fr/all/a991.ovh-meilleur-partenaire-vmware-2013

http://ovh.to/uocveasp => http://www.ovh.com/fr/all/a1067.vdsl-france-2013

http://ovh.to/utfRasco => https://hubic.com/pub/?ruid=aHR0cDovLzUuMTM1LjIwNS44Nzo4ODg4L3YxL0FVVEhfNjdiNmQ0MzI4NGQ3ZmIyNTJjMDFlMjY0MDdjMjY4NTgvZGVmYXVsdC8ub3ZoUHViLzEzNzE0NzQ3MDRfMTM3NDA2NjcwND90ZW1wX3VybF9zaWc9YmRkMTc2ODM4ZTYwNTk2YWExNTE1MTZkYzM4MWNjZDU2YzUzZGNiYyZ0ZW1wX3VybF9leHBpcmVzPTEzNzQwNjY3MDQ=

Comme vous le remarquez, le dernier lien nous envoi sur hubiC !

Step 4 : c’est quoi cette archive ?

Bon, j’avoue que là, j’me suis dit « WTF ? » quand j’ai vu une archive de 304Mo … surtout que je suis sur une connexion assez light durant la semaine…

Je télécharge donc le fichier README avant :

$ md5sum nntp-dwn-03.img.bin.xz
e00a9c53306edd165534f4fa4a761737 nntp-dwn-03.img.bin.xz

==

We found this illegitimate server hidden in the servers room
of our company. It seems it was here for some time, as suggests
the dust that covers it ! Hell, was some competitor spying on
us from the inside ?

The strange thing is that, the server was actually crashed when
we found it, and we couldn’t get it to even boot. The hardware
was pretty shitty, so it had to be expected somehow.

Bob plugged the disk in another machine and captured it, can you
have a look ? I fear there might be frigthening stuff on it…

Bon, ok pourquoi pas… l’archive contient donc une image disque d’un serveur « illégitime » qu’un technicien à trouver dans une salle serveurs… (c’est un peu fort là, comme mise en scène :p)

… 1h30 plus tard le temps de télécharger l’archive …

Alors déjà, l’archive se nomme « nntp » qui est l’acronyme d’un protocole réseau : Network News Transfer Protocol.

Assez étrange comme nom pour une image disque d’un serveur illégitime …

Bref, on extrait cette archive et on se retrouve avec un fichier .bin. Comme dit dans le README, il s’agit d’une image disque, essayons de la convertir en image disque Virtualbox afin de l’attacher à une machine virtuelle Ubuntu :

VBoxManage.exe convertdd OVHack.bin OVHack.vdi --format VDI

Pas d’erreur, niquel.

Attachons maintenant le disque à la machine virtuellement et démarrons là.

Ouvrons un terminal et demandons à Parted de nous en dire plus :

maiko@maiko-VirtualBox:~$ sudo parted /dev/sdb print
Modèle: ATA VBOX HARDDISK (scsi)
Disque /dev/sdb : 1074MB
Taille des secteurs (logiques/physiques): 512B/512B
Table de partitions : gpt

Numéro Début Fin Taille Système de fichiers Nom Fanions
1 1049kB 137MB 136MB zfs
2 137MB 274MB 136MB zfs
3 274MB 278MB 4194kB bios_grub
4 278MB 897MB 619MB ext2 démarrage
5 897MB 1073MB 176MB

Comme vous pouvez le voir, nous avons 5 partitions dont une au format ext2 et deux ZFS.

Step 5 : fouiller un pool ZFS

Installons les outils nécessaires pour ZFS via http://zfsonlinux.org/ afin d’avoir la dernière version disponible.

Maintenant nous devons dire à ZFS d’importer tous les pools disponible et d’afficher le statut des pools disponible :

# zpool import -a
# zpool status

pool: home
state: ONLINE
scan: none requested
config:

NAME STATE READ WRITE CKSUM
home ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-VBOX_HARDDISK_VB7cd1f5c4-c96cff8e-part1 ONLINE 0 0 0
ata-VBOX_HARDDISK_VB7cd1f5c4-c96cff8e-part2 ONLINE 0 0 0

Nous apprenons donc que notre pool se nomme « home ».

Définissons maintenant un point de montage pour celui-ci:

# zfs set mountpoint=/mnt/ZFS home
# zfs mount home

Rendons nous dans /mnt/ZFS. On se retrouve devant un dossier « nntpusers » qui contient des dossiers utilisateurs … contenant un dossier download… contenant des lolcats. #Suicide.

Bref, parcourons l’ensemble des dossiers et fichiers à la recherche de quelque chose d’intéressant…

C’est long… beaucoup de lolcats… les sources d’un jeu en C++… toujours rien… AH ! Une image du nom de « ovh.jpg » !

ovh

Final Step, part 1 : c’est quand même super les snapshot !

Bon, alors on a une image « Final step », mais elle n’est pas complète : pas cool.

On va faire un tour dans le snapshot ZFS quelques fois que l’image correcte y serais …

ls -l /mnt/ZFS/.zfs/snapshot/backup/nntpusers/kevin/download
-rw-rw-r–. 1 10550 5000 303104 May 13 2012 /mnt/ZFS/.zfs/snapshot/backup/nntpusers/kevin/downloads/ovh.jpg
-rw-rw-r–. 1 10550 5000 2400 May 13 2012 /mnt/ZFS/.zfs/snapshot/backup/nntpusers/kevin/downloads/ovh.par2
-rw-rw-r–. 1 10550 5000 158668 May 13 2012  /mnt/ZFS/.zfs/snapshot/backup/nntpusers/kevin/downloads/ovh.vol00+32.par2
-rw-rw-r–. 1 10550 5000 138272 May 13 2012 /mnt/ZFS/.zfs/snapshot/backup/nntpusers/kevin/downloads/ovh.vol32+28.par2

Bingo, on voit apparaître les fichiers par2 relatifs à notre image corrompue. (voir parchive sur wikipedia)

Il nous suffit maintenant de réparer notre image grâce au parchive :

# aptitude install par2
# cp  /mnt/ZFS/.zfs/snapshot/backup/nntpusers/kevin/downloads/ovh* /root/
# cd /root
# par2repair ovh.par2

Nous voici maintenant avec une image complète :

ovh (1)

On remarque sur la partie désormais visible de notre image une chaîne de caractère…

Final Step, part 2 : J’aime pas les XOR, j’en fait déjà (trop souvent) à l’école…

D’après l’image et le message qui l’accompagne, on peut en déduire que c’est du base64 encodé via un xor…

Effectuons la conversion du base64 et ouvrons le résultat dans notre éditeur hexadécimale :

xor1Afin de retrouver le texte original, nous devons effectué un XOR sur ce fichier, sauf que ne nous connaissons pas la « clé » de ce XOR.

Néanmoins, il nous est possible de la déduire… en effet, jusqu’ici nous avons eu droit à pas mal de lien ovh.to, serait-ce également le cas ici ?

Convertissons le texte « http://ovh.to/ via notre éditeur hexadécimal et effectuons un xor sur le fichier avec le ce résultat :

ovh.to

xor2

Ce qui nous donne comme résultat :

xor3

Comme vous pouvez le remarquer, la chaîne « 6pMz2vkzJe » se répète. Avons-nous trouver la clé nous permettant de déchiffrer notre fichier ?

Une seule manière de le savoir : tester !

Pour ce faire, nous allons simplement reprendre notre fichier originel et appliqué le XOR avec la clé « 6pMz2vkzJe » et non plus « http://ovh.to/ » :

xor4Il semblerait que nous ayons vus juste !

Rendons nous sur le lien http://ovh.to/pAmM5LvP2zg… qui n’est autre qu’un lien vers un fichier hubic, dont voici le contenu :

Everything that has a beginning, has an end.

You’ve proven that you know technologies we use.
We would be proud to invite you at #ndh2k13 by giving you
a free ticket.

To get a change to win it, follow @jobsatovh on Twitter,
wait for a follow back, and send us this *private* DM :
« Hey OVH! My smart brain finally get it. Please pick up my
cellphone (XX.XX.XX.XX.XX), and call me to bring me my ticket 🙂 »

If you already follow me, just unfollow/follow again. I tried to
make it easy.
If I’m not following back you in five minutes, just wait longer.

Be smart, the less you are to give me that sentence, the more
chances you have to be selected!

End Of Line.

Et voilà, il semble que nous sommes finalement arriver au bout de ce petit CTF !

Merci @OVH !
J’aurais bien aimé venir vous faire un petit coucou à la NDH2K13, mais je ne pourrais être là cette année… peut être l’année prochaine ? 😉

Merci à @gierschv qui m’a mis sur la piste pour le XOR ainsi que d’autres twittos avec qui j’ai discuté durant ce petit contest !

Attention ! Ce contenu a été publié il y a 11 ans. Merci de lire cette page en gardant son âge à l'esprit, son contenu étant potentiellement obsolète.
Published ininclassable

8 Comments

  1. Bravo,

    Car même en maitrisant les technologies que tu as utilisés, j’aurais jamais pensé qu’ils auraient poussé le bouchon si loin ! 🙂

    Pour info, tu y as passé combien de temps ?

    • Maïko Maïko

      Bonjour Bruno,

      D’après ce qu’on me dit, c’est assez light comme CTF ça … 😡

      J’y ai passé environs 15 heures au total, c’était mon premier CTF.
      J’ai commencer le Lundi dès 20h mais j’ai du rapidement arrêter car j’avais un examen le lendemains matin, j’ai repris dans la journée de mardi et j’ai bloqué sur le XOR…
      Faisant le contest pour le fun, j’ai laisser tomber, mais le mercredi j’ai voulu m’y remettre et grâce à l’un d’un Twittos, j’ai trouver la solution en à peine 20 minutes.

  2. Veovis Veovis

    Effectivement le challenge était plutôt facile.
    Je ne suis pas parmi les finalistes, par manque de temps personnel, et j’avoue que j’aurais séché sur les snapshots ZFS, c’est un format que je n’avais jamais utilisé.

    Pour la première étape, l’image ovhacked.png, j’avais comparé avec l’image originale ovh.png qui se trouvais sur la page d’accueil. On s’aperçoit que la partie « image » est identique, c’est la même image en réalité, et puis si la grande majorité des fichiers ont des magic numbers en en-tête, ce n’est pas forcément le cas en fin de fichier.

    Bravo quand même pour y être arrivé tout au bout. La navigation de pages en pages, c’était plutôt long comme étape.

  3. Salut,

    Merci pour ce tuto !!! J’ai réussi à faire toutes les étapes. (je n’aurais cependant jamais résolu tout seul ce casse tête !)

    Félicitation.

    kéké qui se fend la poire à voir tous les lolcats avec sa fille QUI VEUT PAS FAIRE LA SIESTE !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.


Fatal error: Uncaught TypeError: flock(): supplied resource is not a valid stream resource in /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/Cache_File_Generic.php:64 Stack trace: #0 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/Cache_File_Generic.php(64): flock() #1 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/PgCache_ContentGrabber.php(2191): W3TC\Cache_File_Generic->set() #2 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/PgCache_ContentGrabber.php(457): W3TC\PgCache_ContentGrabber->_maybe_save_cached_result() #3 [internal function]: W3TC\PgCache_ContentGrabber->ob_callback() #4 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/Util_Bus.php(21): call_user_func() #5 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/Generic_Plugin.php(563): W3TC\Util_Bus::do_ob_callbacks() #6 [internal function]: W3TC\Generic_Plugin->ob_callback() #7 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-includes/functions.php(5420): ob_end_flush() #8 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-includes/class-wp-hook.php(324): wp_ob_end_flush_all() #9 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters() #10 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-includes/plugin.php(517): WP_Hook->do_action() #11 /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-includes/load.php(1270): do_action() #12 [internal function]: shutdown_action_hook() #13 {main} thrown in /var/www/vhosts/maiko.sh/domains/maiko.sh/blog/wp-content/plugins/w3-total-cache/Cache_File_Generic.php on line 64