PROJET AUTOBLOG


Le blog de Seboss666

Site original : Le blog de Seboss666

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Writeup #LeHACK 2019, 103spx

dimanche 7 juillet 2019 à 19:25

Autre challenge réussi à la sueur de mon front, ce challenge était beaucoup plus intéressant et m’a donné un peu de fil à retordre. Voyons donc comment je m’en suis sorti.

Le fichier à récupérer s’appelle « USB_a_analyser », sans extension, il fait 247Mo. File nous donne une première indication de ce à quoi on a affaire :

$ file USB_a_analyser 
USB_a_analyser: DOS/MBR boot sector, code offset 0x52+2, OEM-ID "NTFS    ", sectors/cluster 8, Media descriptor 0xf8, sectors/track 62, heads 8, dos < 4.0 BootSector (0x80), FAT (1Y bit by descriptor); NTFS, sectors/track 62, sectors 507903, $MFT start cluster 4, $MFTMirror start cluster 31743, bytes/RecordSegment 2^(-1*246), clusters/index block 1, serial number 06d84ef355f47cf91

On a vraisemblablement affaire à une image d’un disque, mais les choses se compliquent quand on tente de faire l’inventaire détaillé des partitions :

$ sudo fdisk -l ./USB_a_analyser 
Disque ./USB_a_analyser : 248 MiB, 260046848 octets, 507904 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets
Type d'étiquette de disque : dos
Identifiant de disque : 0x00000000

J’attaque un basique « strings », et je vois un message intéressant :

Si un jour je relis ce message, le mot de passe utilis
 pour chiffrer mon plus grand secret 
tait "vgrohhfyek0wkfi5fv13anexapy3sso6" et j'av
s utilis
 openssl.
En revanche, j'ai effac
 par erreur le fichier contenant mon plus grand secret (voir s'il existe des techniques de la mort pour le retrouver mon fichier secret.xz sha256(0fb08681c2f8db4d3c127c4c721018416cc9f9b369d5f5f9cf420b89ee5dfe4e) de 136 octets) et de toute fa
on, impossible de me rappeler de l'algo utilis
 -_- (donc si je le retrouve... il faudra aussi retrouver l'algo pour utiliser ce mot de passe).

Beaucoup d’informations ici, on sait donc qu’il faut récupérer un fichier qui a été chiffré avec openssl avec le mot de passe mentionné. Certes on a pas le nom du fichier, ni l’algorithme utilisé, mais on s’en préoccupera plus tard. Dans ma trousse à outils il y a donc binwalk et foremost, qui se font un plaisir d’analyser le contenu d’un fichier pour en extraire d’autres. J’ai déjà pu extraire des photos cachées dans d’autres photos. Ils me trouvent des pages web avec photos de mobylettes (le nom du challenge n’est pas là par hasard), mais rien qui ressemble à un fichier chiffré avec openssl. Rien d’autre dans les strings, ce qui implique que le fichier n’est pas stocké en clair.

Il paraît qu’elle a fait rêver pas mal de jeunes 🙂

Le fichier semble contenir une ou plusieurs partitions, j’entreprends alors de chercher comment faire pour les monter directement depuis le fichier dans un dossier temporaire. Comme je l’ai dit la difficulté c’est que fdisk ne me donne pas de détails sur les offsets à indiquer pour le montage, et toutes mes recherches pointent sur le fait qu’il faut cette information. C’est alors que Djerfy me glisse une suggestion : « t’as essayé volatility ? »

A là base c’est une suite d’outils en python pour extraire quantité d’informations sur des systèmes majoritairement Windows, ce qui n’est pas si con puisque le fichier contient des partitions NTFS et FAT32. Je ne connaissais pas, je m’empresse d’installer, lis un peu la doc et l’aide embarquée, et j’en viens à ça :

$ volatility -f ./USB_a_analyser mftparser --output=body -D ./vol_extract --output-file=extract.body
$cat extract.body
(...)
0|[MFT STD_INFO] message.txt (Offset: 0x14000)|64|---a-----------|0|0|0|1562415259|1562415034|1562415159|1562415159
0|[MFT FILE_NAME] Peugeot103SPXFILI.jpg (Offset: 0x14400)|65|---a-----------|0|0|0|1562415159|1562415159|1562415159|1562415159
0|[MFT STD_INFO] Peugeot103SPXFILI.jpg (Offset: 0x14400)|65|---a-----------|0|0|0|1562415159|1562370380|1562415159|1562415159
0|[MFT FILE_NAME] .Trash-1000\files\secret.xz (Offset: 0x14800)|66|---a-----------|0|0|136|1562415159|1562414956|1562415159|1562415159
0|[MFT STD_INFO] .Trash-1000\files\secret.xz (Offset: 0x14800)|66|---a-----------|0|0|136|1562415159|1562414956|1562415256|1562415159
0|[MFT FILE_NAME] Peugeot 103 SPX : tous les modèles de 1987 à 2003 | Actualités de la mobylette par Mobylette Mag_files (Offset: 0x14c00)|67|---a---------D-|0|0|0|1562415169|1562415169|1562415169|1562415169
0|[MFT STD_INFO] Peugeot 103 SPX : tous les modèles de 1987 à 2003 | Actualités de la mobylette par Mobylette Mag_files (Offset: 0x14c00)|67|---a-----------|0|0|0|1562415222|1562415170|1562415170|1562415169
(...)

Mais c’est gentil de lui donner un tel nom ! On a donc un fichier secret.xz, supprimé comme l’indiquait l’indice original car dans un dossier « .Trash-1000 », il a été mis dans la corbeille (l’auteur aurait donc pu le récupérer, mais ça serait moins drôle pour nous). Par contre, alors que je passe l’option -D je n’arrive pas à récupérer le moindre fichier, rien dans le dossier « vol_extract » créé pour ce besoin. Rageant…

J’en vient à tenter le tout pour le tout : je monte directement le fichier dans un dossier avec le type ntfs. Ma surprise fut totale quand j’ai vu la commande se terminer sans erreur :

$ l tmp/.Trash-1000/files/
total 201K
drwxrwxrwx 1 root root 4,0K 06.07.2019 14:14  ./
drwxrwxrwx 1 root root    0 06.07.2019 14:14  ../
drwxrwxrwx 1 root root 4,0K 06.07.2019 14:13 "CERT-FR – Centre gouvernemental de veille, d'alerte et de réponse aux attaques informatiques_files"/
drwxrwxrwx 1 root root 4,0K 06.07.2019 14:12 'Peugeot 103 — Wikipédia_files'/
-rwxrwxrwx 1 root root  33K 06.07.2019 14:13 "CERT-FR – Centre gouvernemental de veille, d'alerte et de réponse aux attaques informatiques.html"*
-rwxrwxrwx 1 root root 151K 06.07.2019 14:12 'Peugeot 103 — Wikipédia.html'*
-rwxrwxrwx 1 root root  136 06.07.2019 14:09  secret.xz*

Eh oui, notre secret.xz est bien là. Je le copie donc sur mon disque, et l’extrait. Le fichier a bien été chiffré avec openssl :

$ file secret
secret: openssl enc'd data with salted password

Nous voilà donc à la phase finale : identifier l’algo utilisé pour chiffrer le secret. Le souci, c’est que ça va être trop compliqué d’aborder ça de manière artisanale :

$ openssl help
Standard commands
asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dhparam           
dsa               dsaparam          ec                ecparam           
enc               engine            errstr            gendsa            
genpkey           genrsa            help              list              
nseq              ocsp              passwd            pkcs12            
pkcs7             pkcs8             pkey              pkeyparam         
pkeyutl           prime             rand              rehash            
req               rsa               rsautl            s_client          
s_server          s_time            sess_id           smime             
speed             spkac             srp               storeutl          
ts                verify            version           x509              

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md4               
md5               mdc2              rmd160            sha1              
sha224            sha256            sha3-224          sha3-256          
sha3-384          sha3-512          sha384            sha512            
sha512-224        sha512-256        shake128          shake256          
sm3               

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb      
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb      
aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1     
aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb      
aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8     
aria-256-ctr      aria-256-ecb      aria-256-ofb      base64            
bf                bf-cbc            bf-cfb            bf-ecb            
bf-ofb            camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  
camellia-192-ecb  camellia-256-cbc  camellia-256-ecb  cast              
cast-cbc          cast5-cbc         cast5-cfb         cast5-ecb         
cast5-ofb         des               des-cbc           des-cfb           
des-ecb           des-ede           des-ede-cbc       des-ede-cfb       
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb      
des-ede3-ofb      des-ofb           des3              desx              
idea              idea-cbc          idea-cfb          idea-ecb          
idea-ofb          rc2               rc2-40-cbc        rc2-64-cbc        
rc2-cbc           rc2-cfb           rc2-ecb           rc2-ofb           
rc4               rc4-40            seed              seed-cbc          
seed-cfb          seed-ecb          seed-ofb          sm4-cbc           
sm4-cfb           sm4-ctr           sm4-ecb           sm4-ofb

On le voit dans la partie « Cipher commands », y’a du monde, je ne me vois pas tout faire à la main un par un. Et rien dans le contenu du fichier ne permet de guider un type d’algo plutôt qu’un autre.

J’ai donc extrait la liste de ces cipher commands, organisées dans un fichier, et j’ai là aussi tapé un script à l’arrache pour faire le boulot :

cat script.sh 
#!/bin/bash +x
for i in $(cat cipherlist.txt); do openssl $i -in secret -out "secret.${i}" -d -k vgrohhfyek0wkfi5fv13anexapy3sso6 ; done

J’ai en résultat, un fichier par cipher. Alors y’a beaucoup de fichiers, et malgré une taille identique pour beaucoup d’entre eux, la somme de contrôle me dit qu’ils sont tous différents. Je me rabats donc sur un classique mais toujours efficace grep afin de pouvoir identifier mon vainqueur :

$ grep lh_ secret.*
secret.aes-192-ecb:flag : lh_6c31ba64e522b5f9326b7bee0abef6547f60d214

Et voilà 🙂