Le Minichallenge… la solution

090224-challengesCa y est, je crois que c’est le moment de publier la solution de mon minichallenge… Pour rappel, il s’agissait de récupérer un petit fichier sur mon site, et d’y retrouver deux codes sous la forme nnn-nnnn et nnn-nnn.

Tout d’abord un grand merci à vous tous, car j’ai été surpris de voir que tant de personnes se sont laissées prendre au jeu. J’ai suivi avec un grand intérêt vos manières de résoudre ces épreuves, et peux vous assurer qu’il n’y a pas eu deux démarches identiques. Comme Larry Wall le disait pour Perl, « there is more than one way to do it ».

Dans ce billet, je vais tout d’abord vous expliquer ce qu’il fallait trouver, puis donner quelques manières de procéder en citant directement ceux qui m’ont envoyé leur tutorial par email, et enfin vous expliquer comment j’ai fabriqué ce challenge.

Première partie : Ce qu’il fallait trouver

Si je vous le dis en quelques mots, le challenge paraît simple : Le fichier proposé est une image ISO compressée au format ZIP, qui contient un fichier son au format WAV et un fichier PDF. Lorsqu’on écoute le WAV je donne le premier code oralement, qui est 425-602. Le fichier PDF quant à lui affiche le second code qui est 1958-265. Simplissime ?

… En fait il y a plein de petits pièges, sinon ce ne serait pas vraiment un challenge. Voici les quelques subtilités pimentant le tout :

  • le fichier ZIP est légèrement corrompu, cela pose problème pour certains logiciels de décompression.
  • le nom du fichier ISO est particulier… sous Windows une fois le fichier extrait, il est très difficile d’accéder au fichier pour l’ouvrir et même pour le renommer ou le supprimer (niark !). D’où mon allusion lorsque j’ai publié le challenge qu’il vallait mieux faire ça dans une machine virtuelle. Les mystères de NTFS…
  • l’image ISO elle-même est un peu bricolée ce qui rend son montage un peu délicat.
  • le fichier wav n’est pas corrompu, il faut le jouer à l’envers pour avoir le code.
  • le fichier PDF a un numéro de version exotique qui perturbe les logiciels d’affichage comme Acrobat Reader etc.
  • si on arrive malgré tout à afficher le fichier PDF, on a une page blanche. Le code est pourtant bien affiché… mais dans une zone un peu lointaine.

Seconde partie : Les propositions des candidats

Suivant la manière de s’y prendre et sa propre expérience à faire ce type d’exercices, trouver la solution peut être plus ou moins long. Voici les méthodes par ordre chronologique de réponse. Je ne cite que ceux qui m’ont donné leur manière de procéder ! Ce qui est intéressant est qu’il n’y a pas deux méthodes identiques.

1. R: Le premier à me répondre a été « R » qui a trouvé les 2 codes moins d’une heure après que j’aie posté le challenge. Il m’a ensuite expliqué avoir utilisé (je cite) : « Winrar, UltraEdit, Soundrec et un bout de code qui fait de l’extraction de trucs compressés zlib ». Il était donc sous Windows.

2. Cédric Pernet n’a pas tardé peu après à m’envoyer les deux codes par email. Pour sa part, sous Linux il a utilisé (je cite) :

file, strings, ghex2, un extracteur d’archives (me souvient plus lequel, je suis sur une autre machine là), audacity. Pour le zlib, j’ai utilisé un script existant trouvé sur le net , je n’ai rien compilé  ;-)

et il a procédé de cette manière :

* lancement de « file » sur le bin
* renommage du bin en .zip
* extraction
* check rapide avec file : iso
* extraction again
* recherche d’un outil pour jouer avec le wav : audacity sous Linux, ça m’a permis de le découvrir :p
* inversion effectuée et soluce 1.
* j’avais à je ne sais plus quel stade zieuté avec ghex2. J’avais vu en fin le %PDF, je savais qu’il y aurait un truc autour de PDF
* examen du PDF : version 0.0
* Tentative foireuse d’ouverture avec un PDF reader …
* Comparaison du header avec un PDF valide : ajout d’un « 0D » ou « 0A » dans les entêtes, mais je ne sais pas si ça a servi à quelque chose.
(Note de Bruno : Non ça n’était pas utile !)
* Recherches autour des streams de ce genre sur Google et découverte de PDFTK, et de son option « uncompress ».
* PDFTK sur le fichier : invalide.
* Par dépit (je n’y croyais pas une seconde), changement de 0.0 en 1.1 et miracle : PDFTK accepte et décompresse.
Voilà … C’est donc bien le PDF qui m’a pris le plus de temps ;-)

3. Une petite équipe sécurité de Thomson Labs dont je connais quelques membres éminents et sympathiques depuis quelques années grâce au SSTIC a trouvé également les codes. Ils ont fait cela sous Windows et m’en ont un peu voulu lorsqu’ils se sont retrouvés avec le fameux fichier ineffaçable !

4. Mathieu Gaspard a fait cela sous Linux. Son tutoriel est assez précis :

On vérifie qu’on a bien le fichier (je passe sur le MD5 et SHA1..)

mathieu@machine:~/tmp/ker$ ll
total 64
-rw-r–r– 1 mathieu mathieu 61101 2009-02-26 16:05 090224-minichallenge_kerouanton-01.bin

Quel est donc ce fichier :

mathieu@machine:~/tmp/ker$ file 090224-minichallenge_kerouanton-01.bin
090224-minichallenge_kerouanton-01.bin: Zip archive data

OK, c’est apparemment un ZIP, decompressons le:

mathieu@machine:~/tmp/ker$ unzip 090224-minichallenge_kerouanton-01.bin
Archive:  090224-minichallenge_kerouanton-01.bin
inflating:

Hum, bizarre, pas de fichier decompressé??

mathieu@machine:~/tmp/ker$ ll
total 128
-rw-r–r– 1 mathieu mathieu 61440 2038-01-19 04:14
-rw-r–r– 1 mathieu mathieu 61101 2009-02-26 16:05 090224-minichallenge_kerouanton-01.bin

Ha si, mais son nom est  » « , renommons le:

mathieu@machine:~/tmp/ker$ mv  »  » unknown.bin
mathieu@machine:~/tmp/ker$ ll
total 128
-rw-r–r– 1 mathieu mathieu 61101 2009-02-26 16:05 090224-minichallenge_kerouanton-01.bin
-rw-r–r– 1 mathieu mathieu 61440 2038-01-19 04:14 unknown.bin

OK, quel est donc ce nouveau fichier

mathieu@machine:~/tmp/ker$ file unknown.bin
unknown.bin: ISO 9660 CD-ROM filesystem data

Une image CD, montons la et regardons ce qu’il y a dedans

mathieu@machine:~/tmp/ker$ sudo mount -t iso9660 -o loop unknown.bin /tmp/unknown/
mathieu@machine:~/tmp/ker$ ll -a /tmp/unknown/
total 14
dr-xr-xr-x  1 root root  2048 2009-02-20 00:04 .
drwxrwxrwt 15 root root 12288 2009-02-26 16:06 ..

Bon, apparemment, il n’y a rien dans l’image
Mais connaissant le challenge, on doit quand meme avoir des données

mathieu@machine:~/tmp/ker$ df -h
Sys. de fich.            Tail. Occ. Disp. %Occ. Monté sur
/dev/loop0             60K   60K     0 100% /tmp/unknown

On a apparemment 60 ko de données, on va aller fouiller un peu plus

mathieu@machine:~/tmp/ker$ sudo umount /tmp/unknown
mathieu@machine:~/tmp/ker$ strings unknown.bin

RIFF
WAVEfmt

%PDF-0.0
9 0 obj<</Type /Catalog /Pages 8 0 R>>endobj
8 0 obj<</Type /Pages /Kids 7 0 R /Count 1>>endobj
7 0 obj[6 0 R]endobj
6 0 obj<</Type /Page /Parent 8 0 R /MediaBox [0 0 1 1]/CropBox [0 0 1 1]/Resources <</Font <</FXF1 5 0 R>>>>/Contents 4 0 R>>endobj
5 0 obj<</Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding>>endobj
4 0 obj<</Length 135 /Filter /FlateDecode>>stream
t`;b
endstream endobj
trailer<</Root 9 0 R>>%%EOF

(en fait, j’ai édité le fichier avec un éditeur hexa et j’ai cherché « à la main » les parties intéressantes)
On a donc l’air d’avoir un fichier (RIFF WAVE) et un PDF

Un petit coup de google me dit que RIFF WAVE, c’est un WAV

je récupère via l’éditeur hexa la partie de fichier qui a l’air de correspondre au fichier WAV (j’ai regardé dans le fichier « magic » de « file » a quoi ressemble un fichier WAV pour savoir quel morceau prendre) et la copie dans un nouveau fichier
un « file » dessus me dit que c’est bien un wav

j’essaie de le jouer.. bon, il y a du son, mais ca n’a pas l’air top..
on dirait que le son est joué à l’envers

Un coup d’audacity plus tard, je joue le son à l’envers et je récupère le premier code

Pour le 2e code (le PDF), j’extrais la partie correspondant au PDF dans un nouveau fichier et l’ouvre.
Il n’y a qu’une seule vignette, sans aucun texte

en regardant le contenu du PDF plus en détail, je remarque :

obj<</Length 135 /Filter /FlateDecode>>stream   ….. endstream

5 min de google pour voir que c’est un contenu compressé avec la zlib standard

je récupère les 135 octets compressés et les mets dans un nouveau fichier, puis je décompresse avec 4 lignes de python :

>>> fd = open(« flatedecode.bin », »rb »)
>>> a = fd.read(200)
>>> import zlib
>>> zlib.decompress(a)
‘BT\n/DeviceRGB cs 0 0 0 scn /DeviceRGB CS 0 0 0 SCN /FXF1 10 Tf 0.208412 0 0 0.184382 0 0 Tm 3 Tr 1 i -3537.89 2095.54 TD[(Bravo ! Le code est : 1958-265)]TJ\nET\n’

Ma méthodologie était un peu « brute » mais a quand même marché ;)

5. Le tutoriel suivant nous vient de Mr KaliMan, sous Linux.

Ma démarche :

Tout d’abord, on ouvre le fichier dans un éditeur hexadécimal.
On remarque tout de suite l’entête « PK », signe d’une archive zip.
Le seul fichier a pour nom un simple espace.
On décompresse ce fichier, dans mon cas je l’ai renommé « forensic.hex » directement dans l’archive avant de décompresser pour éviter des soucis liés au nom avec winzip.
On se retrouve donc avec un fichier « forensic.hex » de type indéfini.

Pas d’entête connue au premier coup d’oeil.
Un coup de file :

kali@nas:~/challs/bruno.kerouanton$ file forensic.hex
forensic.hex: ISO 9660 CD-ROM filesystem data UDF filesystem data (unknown version, id ‘NSR0d’) ’1                              ‘

Petit souci lié au nom pour monter l’image sous windows.
Du coup on cherche directement dans le fichier d’autres entêtes connues.
On trouve un « RIFF » à l’offset 0xC800 et un « %PDF » à l’offset 0xE800.
Donc un fichier wave et un pdf.
On extrait donc manuellement les 2 fichiers à l’éditeur hexa qu’on nommera : forensic.wav et forensic.pdf.

Pour forensic.wav, on l’écoutant on se rend compte que le son est inversé.
Inversion du sens avec audacity et on a le premier code.

Pour forensic.pdf, mon lecteur de pdf ne veut pas l’ouvrir, donc on s’arrange autrement.
On va chercher directement la chaine compressée à l’aide d’un éditeur hexadécimal de l’offset 0×197 à 0x21D, soit :
78 9C 4D 89 3D 0B C2 30 18 06 F7 FC 8A C7 4D 87 A6 F9 D4 C4 31 AD 15 44 1C EC 3B 14 C4 41 62 84 0E 5A 68 A4 BF 5F B0 0E 72 D3 DD 05 62 65 9D A6 3E A6 F3 3E 20 66 88 2F 39 BE F0 D7 AB F6 D7 DB EA 84 B2 E9 1A 09 29 40 0F 08 AE 84 33 52 CD 9B 4B 67 B4 9B 85 9E D0 A0 11 12 3D 0A 6D F5 86 3B 0F 25 BC E5 D6 80 EA CB 32 8C B7 69 C0 02 C7 84 38 DC 13 52 7E 63 0B E9 AD 2B D4 DA AE AE 74 60 3B 62 1F 4A EF 26 62
Je la décompresse avec la fonction php gzuncompress() et on tombe sur notre second code « Bravo ! Le code est : … »

Voilà, fin de ma démarche…

6. Christophe Monnier (du FCCU Belgique), quant à lui va encore plus loin et me propose son challenge en vidéo ! Résolu en 12 minutes, bravo ;)

Sous Debian Gnu/Linux

Outils utilisés :
* file
* grep
* dd
* sox
* hexedit
* python

1) vérifier le contenu du fichier avec file

2) unzip du fichier avec « unzip -p »

3) vérifier le contenu du fichier « dézippé » avec file

4) comme l’image iso semble endommagée, on envisage un carving. Comme l’image n’est pas trop grande , on peut utiliser dd et file comme suit :
# for i in $(seq 0 119); do echo $i ; dd if=image.iso count=1 skip=$i | file – ; done

5) On découvre une signature de mp3, de wav et de pdf.

6) le mp3 est sans doute un faux positif (ça arrive souvent, la signature est petite).

7) Le wav est OK mais semble à l’envers, on le renverse avec sox (et au passage, on l’amplifie un peu parce que le son est faible) :

sox fichier.wav reverse.wav reverse norm

On obtient le premier code.

8) Le PDF semble endommagé. Après inspection avec un éditeur hexa, on constate un stream compressé de 135 bytes mis en évidence par les balises « /Filter /Flate Decode>>stream ».
Ces streams sont compressés par libzip. On sauve le stream depuis l’éditeur hexa et on décompresse avec python comme suit:
>>> >>> import zlib
>>> >>> f = open(‘stream.gz’,'r’)
>>> >>> content = f.read()
>>> >>> uz = zlib.decompress(content)
>>> >>> print uz
BT
/DeviceRGB cs 0 0 0 scn /DeviceRGB CS 0 0 0 SCN /FXF1 10 Tf 0.208412 0 0
0.184382 0 0 Tm 3 Tr 1 i -3537.89 2095.54 TD[(Bravo ! Le code est :
1958-265)]TJ
ET

Et voilà.
J’ai fait ça en plus ou moins 12 minutes mais je pense qu’il est possible d’aller plus vite si on enlève les essais/erreur et le temps de réflexion.
Voir le screncast de l’opération ici : http://lnx4n6.be/minichallenge.ogv

Je remercie tous les participants, et ceux qui m’ont donné leurs solutions ! Merci à Christophe Monnier pour son Screencast !

Troisième partie : Comment j’ai fabriqué ce challenge

Assez simplement en fait. Les outils dont je me sers pour ce challenge font depuis longtemps partie de ma panoplie de base :

  • IsoBuster : Un utilitaire pour réparer les CD/DVD et lire ces derniers en mode RAW, avec éditeur hexa inclus.
  • UltraISO : Un utilitaire pour créer/éditer des images ISO. On peut ainsi altérer une ISO et y ajouter des fichiers, changer des paramètres etc.
  • ISORecorder : Un petit plugin de l’explorateur pour créer/graver des images ISO. Très pratique.
  • VirtualCloneDrive : Pour monter les images ISO directement. Gratuit et indispensable.
  • X-Ways WinHex : Un éditeur Hexadécimal très puissant. Je m’en sers sous la forme « X-Ways Forensics » très régulièrement.
  • EmEditor : Un éditeur texte/hexa capable de supporter de très gros fichiers et des codes pages spécifiques y compris toutes les variantes d’Unicode
  • FoxIT PDF Editor : Un éditeur de fichiers PDF, me permettant de modifier certaines caractéristiques
  • 7Zip : Un compresseur/décompresseur de fichiers OpenSource.
  • Cygwin : de très nombreux outils Linux sous Windows
  • GoldWave : Un éditeur audio assez performant.

Maintenant que vous avez la liste des outils, voyons comment j’ai créé le tout.

Etape 1 : le fichier son. J’ai simplement lancé Goldwave pour enregistrer ma voix, trouver quelques réglages de compression du son et du codec le moins gourmand en taille (GSM), puis inverser le son. J’ai enfin tenté de voir ce que je pouvais altérer dans le fichier sans perdre ses caractéristiques, mais sans succès.

Etape 2 : le fichier PDF. J’ai créé un fichier PDF vide sous OpenOffice Writer, puis y ai jeté un coup d’oeil avec EmEditor. Une fois sa structure assimilée, j’ai lancé Foxit Editor pour y ajouter le champ de texte contenant le code, et ai fait attention à le mettre loin de la page affichée (en haut à gauche en fait). Pour cela, j’ai modifié l’échelle d’affichage et si vous ouvrez le PDF à l’aide (par exemple) de Foxit Reader vous ne verrez qu’une page blanche certes, mais le facteur de zoom est de l’ordre de 65000… Cela peut être un indice également, en dézoomant fortement  on arrive à obtenir le texte. Sous PDF Editor on le voit immédiatement. J’ai enfin repris le tout sous WinHex puis EmEditor, remis en forme le contenu (notamment en supprimant tout ce qui n’était pas strictement pas nécessaire et en optimisant manuellement le code), puis reformaté et changé les valeurs de l’entête afin de faire croire à une version « 0.0″, ce qui manifestement ne plaît pas du tout aux logiciels d’affichage. J’ai tenté d’autres altérations mais sans trouver de choses amusantes – bien que je me sois moi-même amusé à découvrir des subtilités en modifiant des séquences de chaînage des sous-parties du PDF. Intéressant…

Etape 3 : l’image ISO. Un coup de IsoRecorder sur le fichier son pour créer l’image ISO de petite taille. Un coup de WinHex pour copier/coller le fichier PDF à la main en « fin de disque », et UltraISO pour faire quelques retouches sur les caractéristiques de l’image obtenue. De nouveau WinHex pour altérer un peu la table d’allocation et le nom du volume (qui apparaît alors en chinois sous Windows) afin que les fichiers n’apparaîssent pas bien et que l’image ISO se monte mal (mais elle se monte pourtant bien avec Virtual CloneDrive)

Etape 4 : le fichier Zip. Un coup de 7Zip pour compresser l’image ISO obtenue, et une petite altération avec WinHex pour d’une part modifier le nom du fichier de l’image ISO en  »  » (espace). Cela m’a bien amusé car d’une part ça perturbe les outils de décompression comme 7zip, et surtout une fois le fichier décompressé on se retrouve comme un idiot avec un fichier présent sur le disque qu’on ne peut ni ouvrir ni renommer ni supprimer…  Pas sérieux chez Microsoft, cette gestion de filesystems. Enfin j’ai tripatouillé les différentes structures et signatures de ZIP en début, milieu et fin de fichier mais sans parvenir à faire des choses géniales. Le simple fait de changer la signature, le mode de compression etc posaient souci lorsqu’on tentait d’ouvrir, ce que je ne voulais pas non plus.

A chaque étape, j’ai bien entendu testé les résultats de manière répétée afin de voir comment se comportaient les logiciels que j’avais sous la main. Voilà tout !

7 Comments »

Bruno Kerouanton on mars 8th 2009 in Conferences - Speakings, IT Security

7 Responses to “Le Minichallenge… la solution”

  1. R responded on 09 mar 2009 at 10:16 #

    Voici ma solution un peu plus en detail:

    Download du binaire, un coup de ultraedit pour voir le ‘PK’ d’un fichier zip. Tentative avec winrar d’utiliser « rename » sur le fichier ‘ ‘. Erreur, l’archive est corrompue. Utilisation de la fonction « fix archive » puis « rename », et enfin extraction.

    Re-ultraedit ou on voit la structure classique d’un ISO (vers 0×8000 je crois). Tentative infructueuse de montage (grr comme a insomni’hack08 ou l’impossiblite d’extraire le PRG correctement m’avait empeche de gagner). Look a la main avec ultraedit dans l’ISO pour trouver les headers Wav et PDF. Extraction sous ultraedit a la louche pour le wav et avec le EOF pour le PDF.

    Ecoutage du wav qui est clairement inverse. Un coup de soundrec et le tour est joue.

    Tenative d’affiche du PDF. Meme en dezoomant j’ai pas trouve le texte. Alors download d’un des milliers de petits scripts qui extraient le texte d’un PDF.

    J’ai adore la video de solution. C’est fou ce qu’on peut faire en command line et avec Python. Faut vraiment que je trouve le temps de m’y remettre un jour.

    PS: le post s’affiche mal sous IE7.

  2. pythonpowaa responded on 09 mar 2009 at 11:55 #

    En deux lignes avec python :

    import zlib
    print zlib.decompress(open(’file’,’r’).read())

    \o/

  3. Julien responded on 09 mar 2009 at 14:26 #

    Pour analyser l’iso, j’ai utilisé http://www.cgsecurity.org/wiki/TestDisk, mais il n’a pu récupéré que le fichier .wav. Mais j’ai même pas eu l’idée de l’inversé…
    Sinon, merci pour ce mini challenge et pour la solution !

  4. Kr responded on 09 mar 2009 at 14:52 #

    arrggg je n’étais vraiment pas loin, je n’ai absolument pas pensé à jouer le wav à l’envers vu qu’à l’endroit je n’entendais rien du tout….

    sinon pour la méthode, éditeur hexa pour voir que le header du fichier semblait être un zip, après avoir essayé (en vain) de réparer ‘à la main’, un petit coup de google, object fix zip, ça ressemble à un iso, google, isobuster…

    J’attends avec impatience le suivant!

  5. Bruno Kerouanton responded on 09 mar 2009 at 22:03 #

    @kr : object fix zip, je ne connaissais pas. Quant à IsoBuster, bien que j’aie la licence je n’avais même pas pensé à le lancer pour tester l’image ISO : En effet il me récupère le wav et le pdf en un clin d’oeil (normal, c’est un outil de récupération de CD corrompus…) !

    @R: Pas de souci d’affichage du post sous IE7 pour moi… curieux.

    Content que ça vous ait plu. A bientôt.

  6. R responded on 10 mar 2009 at 12:21 #

    Oups, ma langue fourche, je voulais dire IE6.

  7. Guillaume responded on 02 mai 2009 at 15:34 #

    Moi qui suis pas du tout (mais pas du tout du tout!) de votre niveau, je trouve l’exercice intéressant, enrichissant. Juste en vous lisant, j’ai appris de trucs, et l’esprit d’ »investigation » est sympa.
    En espérant qu’il y en aura d’autres.
    Bonne continuation.

Trackback URI | Comments RSS

Laisser un commentaire