Santhackclaus CTF 2018 - Mission Impossible 1 (forensic)


Building our profile

Premièrement il nous faut déterminer le type de notre fichier.

switch :: pain ~/ctf/santack2018/MI1 $ file challenge.elf 
challenge.elf: ELF 64-bit LSB core file x86-64, version 1 (SYSV)
switch :: pain ~/ctf/santack2018/MI1 $ strings challenge.elf | egrep '^Linux.*[0-9.]{3,}.*SMP'
Linux version 3.16.0-6-amd64 (debian-kernel@lists.debian.org) (gcc version 4.9.2 (Debian 4.9.2-10+deb8u1) ) #1 SMP Debian 3.16.57-2 (2018-07-14)
Linux version 3.16.0-6-amd64 (debian-kernel@lists.debian.org) (gcc version 4.9.2 (Debian 4.9.2-10+deb8u1) ) #1 SMP Debian 3.16.57-2 (2018-07-14)
switch :: pain ~/ctf/santack2018/MI1 $ strings challenge.elf | grep PRETTY_NAME
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"

 

C'est un dump mémoire d'un Debian 8 (Jessie). Malheureusement je n'ai trouvé aucun profile Volatility correspondant sur internet donc j'ai dû créer le mien. On m'a souvent dit que c'était une étape chiante, je confirme qu'à moitié car il faut créer une VM à partir de la bonne iso avec une version de kernel exactement identique, ici Debian 8, version 3.16.0-6, disponible sur le site de Debian en net install pesant quelques centaines de mo.

 

Une fois installé on vérifie bien que la version du kernel est exactement : 3.16.0-6 avec un uname -a. Une fois la machine préparée il nous faut télécharger 2 / 3 babioles utiles :

 

sudo apt install volatility dwarfdump build-essential linux-headers-$(uname -r)
cd /usr/share/volatility/tools/linux
make

zip debian8.zip /usr/share/volatility/tools/linux/module.dwarf /boot/System.map-3.16.0-6-amd64

 

Cette commande permet de créer le profile Volatitliy pour cette version de Debian. Il suffira ensuite de glisser le fichier debian8.zip dans /usr/lib/python2.7/dist-packages/volatility/plugins/overlays/linux/ pour ma part.

 

switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_banner
Volatility Foundation Volatility Framework 2.6
Linux version 3.16.0-6-amd64 (debian-kernel@lists.debian.org) (gcc version 4.9.2 (Debian 4.9.2-10+deb8u1) ) #1 SMP Debian 3.16.57-2 (2018-07-14)

 

Investigations

La première chose à faire et de trouver les dernières commandes exécutées avec linux_bash 

switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_bash
Volatility Foundation Volatility Framework 2.6
Pid      Name                 Command Time                   Command
-------- -------------------- ------------------------------ -------
    1867 bash                 2018-12-16 16:17:45 UTC+0000   rm flag.txt 
    1867 bash                 2018-12-16 16:17:45 UTC+0000   ls
    1867 bash                 2018-12-16 16:17:45 UTC+0000   ls
    1867 bash                 2018-12-16 16:17:45 UTC+0000   sudo reboot
    1867 bash                 2018-12-16 16:17:45 UTC+0000   zip -r -e -s 64K backup.zip *
    1867 bash                 2018-12-16 16:17:45 UTC+0000   cat /dev/urandom > flag.txt 
    1867 bash                 2018-12-16 16:17:45 UTC+0000   cd /var/www/a-strong-hero.com/
    1867 bash                 2018-12-16 16:17:45 UTC+0000   sudo reboot
    1867 bash                 2018-12-16 16:17:49 UTC+0000   cd /var/www/a-strong-hero.com/
    1867 bash                 2018-12-16 16:17:49 UTC+0000   ls
    1867 bash                 2018-12-16 16:18:09 UTC+0000   find . -type f -print0 | xargs -0 md5sum > md5sums.txt
    1867 bash                 2018-12-16 16:18:10 UTC+0000   cat md5sums.txt 

 

Cependant la timeline ne semble pas être respectée, essayons une autre méthode.

 

switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_enumerate_files | grep bash_history
Volatility Foundation Volatility Framework 2.6
0xffff88003cdf4898                     10097 /home/evil-hacker/.bash_history
switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_find_file -i 0xffff88003cdf4898 -O bash_history
switch :: pain ~/ctf/santack2018/MI1 $ cat bash_history 
sudo reboot
cd /var/www/a-strong-hero.com/
ls
zip -r -e -s 64K backup.zip *
ls
cat /dev/urandom > flag.txt 
rm flag.txt 
sudo reboot

 

Tout n'y est pas mais c'est déjà plus logique. On voit qu'une archive multipart (-s) a été créée et qu'elle contient notre flag.txt.

 

La commande find . -type f -print0 | xargs -0 md5sum > md5sums.txt, va nous permettre de récupérer la liste des fichiers présents dans /var/www/a-strong-hero.com/ et donc aux cotés de flag.txt dans l'archive.

 

Le contenu de flag.txt est ensuite overwrited avant d'être supprimé, puis la machine reboot pour supprimer toute traces de ce fichiers en mémoire.

 

Récupérons maintenant le contenu de md5sums.txt

switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_enumerate_files | grep md5sums.txt 
Volatility Foundation Volatility Framework 2.6
0xffff88001e61f0c8                    261718 /var/www/a-strong-hero.com/md5sums.txt
switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_find_file -i 0xffff88001e61f0c8 -O md5sums.txt
57c57e1f05f763892c8ac5e5e320a388  ./backup.z03
194577a7e20bdcc7afbb718f502c134c  ./jcvd-website/js/.DS_Store
4becdc9104623e891fbb9d38bba01be4  ./jcvd-website/js/bootstrap.min.js
895323ed2f7258af4fae2c738c8aea49  ./jcvd-website/js/jquery-1.11.3.min.js
8015042d0b4ac125867af5b096b175ce  ./jcvd-website/js/bootstrap.js
853e870c06a9640f81e8c1af2d2bba25  ./jcvd-website/js/custom.js
90e29070de7dcd28a451465ec74047be  ./jcvd-website/js/ie10-viewport-bug-workaround.js
9cda9e740bbf260a190f4041132b5105  ./jcvd-website/js/jquery.easing.min.js
43e5dec37a6f7ffbf1706855fb05ab95  ./jcvd-website/.DS_Store
af40dfa2736ae815ed3b46fa73fd6f96  ./jcvd-website/images/concert.jpg
194577a7e20bdcc7afbb718f502c134c  ./jcvd-website/images/.DS_Store
df60d79970dd2d551270a08d385896c5  ./jcvd-website/images/microphone.jpg
00642b16baba8c167489c0052233b1a1  ./jcvd-website/images/iphone.jpg
9178b5599157c55a5c2f8ba74c6f1c8e  ./jcvd-website/images/header.jpg
c90979c47c4debc2ef6289e83fbc479e  ./jcvd-website/images/writing.jpg
a0511c8d5181dc1add9f1d44aaa2a334  ./jcvd-website/images/pencil_sharpener.jpg
6f250457e1eb30b6fc8dd97685f91e4e  ./jcvd-website/index.html
e18bbf611f2a2e43afc071aa2f4e1512  ./jcvd-website/fonts/glyphicons-halflings-regular.ttf
448c34a56d699c29117adc64c43affeb  ./jcvd-website/fonts/glyphicons-halflings-regular.woff2
fa2772327f55d8198301fdb8bcfc8158  ./jcvd-website/fonts/glyphicons-halflings-regular.woff
f4769f9bdb7466be65088239c12046d1  ./jcvd-website/fonts/glyphicons-halflings-regular.eot
89889688147bd7575d6327160d64e760  ./jcvd-website/fonts/glyphicons-halflings-regular.svg
194577a7e20bdcc7afbb718f502c134c  ./jcvd-website/css/.DS_Store
957474c344c7131fb8e093449cc4893a  ./jcvd-website/css/bootstrap.css
81bc943c9854d26040b6b2ce65641471  ./jcvd-website/css/custom.css
5d5357cb3704e1f43a1f5bfed2aebf42  ./jcvd-website/css/bootstrap.min.css
dd3aa992145286544c200b2f0f5743bc  ./backup.z09
9fd94a0acb91bd0c9ff041b765b6e9dc  ./backup.z06
d48829a806651ba8248c97dff073ec2e  ./backup.z04
0548eb2c5d6a028d35d854dd81358be5  ./backup.z01
0ede2c77cf4633756e77148fe9f6eb97  ./backup.zip
18e00022bd3becb300f93b2b22933d48  ./backup.z08
2e3f70c94f921ef88d4966fab665bb47  ./md5sums.txt
7e792a0bb7a847b6da3fdcef162417e0  ./backup.z07
33d2e741f2b37377405284a010153155  ./backup.z05
60e129d4b37ada2be7254db4f1215f05  ./backup.z02

 

Ainsi on remarque deux choses :

  • Le fichier backup.zip est split en 10 parties (backup.z0* + backup.zip)
  • Le zip contient également un site web et des images

 

Nous allons donc reconstruire ce zip.

End-of-central-directory signature not found

Je vais pas vous le cacher j'en ai pas un chier pour reconstruire ce zip, j'avais de la merde un peu partout sur moi mais j'ai quand même réussi.

 

La première étape va être de récupérer les 10 parties du zip.

switch :: pain ~/ctf/santack2018/MI1 $ volatility -f challenge.elf --profile=LinuxDebian811x64 linux_find_file -i offset -O zip/backup.z0*
switch :: pain ~/ctf/santack2018/MI1/zip $ cat backup.z01  backup.z02  backup.z03  backup.z04  backup.z05  backup.z06  backup.z07  backup.z08  backup.z09  backup.zip > tmp.zip
switch :: pain ~/ctf/santack2018/MI1/zip $
switch :: pain ~/ctf/santack2018/MI1/zip $ unzip -l tmp.zip 
Archive:  tmp.zip
warning [tmp.zip]:  zipfile claims to be last disk of a multi-part archive;
  attempting to process anyway, assuming all parts have been concatenated
  together in order.  Expect "errors" and warnings...true multi-part support
  doesn't exist yet (coming soon).
warning [tmp.zip]:  589824 extra bytes at beginning or within zipfile
  (attempting to process anyway)
  Length      Date    Time    Name
---------  ---------- -----   ----
       30  2018-12-16 16:57   flag.txt
        0  2018-12-16 15:51   jcvd-website/
        0  2018-12-16 15:51   jcvd-website/js/
     6148  2018-12-16 15:51   jcvd-website/js/.DS_Store
    36816  2018-12-16 15:51   jcvd-website/js/bootstrap.min.js
    95957  2018-12-16 15:51   jcvd-website/js/jquery-1.11.3.min.js
    68890  2018-12-16 15:51   jcvd-website/js/bootstrap.js
       79  2018-12-16 15:51   jcvd-website/js/custom.js
      641  2018-12-16 15:51   jcvd-website/js/ie10-viewport-bug-workaround.js
     5564  2018-12-16 15:51   jcvd-website/js/jquery.easing.min.js
    12292  2018-12-16 15:51   jcvd-website/.DS_Store
        0  2018-12-16 15:51   jcvd-website/images/
    37682  2018-12-16 15:51   jcvd-website/images/concert.jpg
     6148  2018-12-16 15:51   jcvd-website/images/.DS_Store
    52003  2018-12-16 15:51   jcvd-website/images/microphone.jpg
    49276  2018-12-16 15:51   jcvd-website/images/iphone.jpg
    91733  2018-12-16 15:51   jcvd-website/images/header.jpg
    26267  2018-12-16 15:51   jcvd-website/images/writing.jpg
   133773  2018-12-16 15:51   jcvd-website/images/pencil_sharpener.jpg
     7384  2018-12-16 15:51   jcvd-website/index.html
        0  2018-12-16 15:51   jcvd-website/fonts/
    45404  2018-12-16 15:51   jcvd-website/fonts/glyphicons-halflings-regular.ttf
    18028  2018-12-16 15:51   jcvd-website/fonts/glyphicons-halflings-regular.woff2
    23424  2018-12-16 15:51   jcvd-website/fonts/glyphicons-halflings-regular.woff
    20127  2018-12-16 15:51   jcvd-website/fonts/glyphicons-halflings-regular.eot
   108738  2018-12-16 15:51   jcvd-website/fonts/glyphicons-halflings-regular.svg
        0  2018-12-16 15:51   jcvd-website/css/
     6148  2018-12-16 15:51   jcvd-website/css/.DS_Store
   147430  2018-12-16 15:51   jcvd-website/css/bootstrap.css
     8335  2018-12-16 15:51   jcvd-website/css/custom.css
   122540  2018-12-16 15:51   jcvd-website/css/bootstrap.min.css
---------                     -------
  1130857                     31 files

 

Bon nous avons notre petit zip tout beau, tout propre. Dézippons le :

switch :: pain ~/ctf/santack2018/MI1/zip $ unzip tmp.zip 
Archive:  tmp.zip
warning [tmp.zip]:  zipfile claims to be last disk of a multi-part archive;
  attempting to process anyway, assuming all parts have been concatenated
  together in order.  Expect "errors" and warnings...true multi-part support
  doesn't exist yet (coming soon).
warning [tmp.zip]:  589824 extra bytes at beginning or within zipfile
  (attempting to process anyway)
file #1:  bad zipfile offset (local header sig):  589828
  (attempting to re-compensate)
[tmp.zip] flag.txt password: 

 

Ah oui l'options -e, lors de la création du zip.

 

Notre zip est chiffré et en plus zip à l'air de nous dire que notre zip contient des erreurs, anyway ça marchera quand même ..

 

AHAHAHAHAHAHA. non.

Error: unknown signature (ZIP file may be corrupt)

J'ai cherché environs 20/30 minutes, voir si le password n'était pas caché quelque part en mémoire (j'ai compris l'utilité des reboot après) et à coups de strings | grep, du forensic quoi ..

 

Mais rien, puis je me suis rappelé d'une attaque sur les fichiers zip que j'ai déjà utilisé lors du BreizhCTF. L'utilitaire PKcrack fait des merveilles de ce coté : https://www.unix-ag.uni-kl.de/~conrad/krypto/pkcrack.html

 

Il nous suffit de 4 choses :

  • Le zip chiffré, bah ouais .. logique ..
  • Le chemin vers un fichier de ce zip chiffré que l'on possède
  • Un zip contenant un fichier connu du zip chiffré
  • Notre fichier connu du zip chiffré

 

Rappelons nous, notre archive contient également des images, je me suis donc empressé de récupérer jcvd-website/images/concert.jpg. Puis j'ai lancé PKcrack avec la commande suivante :

switch :: pain ~/ctf/santack2018/MI1/zip $ ~/tools/bruteforce/pkcrack/bin/pkcrack -C tmp.zip -c jcvd-website/images/concert.jpg -P essaie.zip -p concert.jpg
Read unknown signature: 0x7a254d90
Error: unknown signature (ZIP file may be corrupt)

 

 

J'ai donc rapidement jeté un oeil au fichier zip précédément créé

switch :: pain ~/ctf/santack2018/MI1/zip $ xxd tmp.zip | head
00000000: 504b 0708 504b 0304 0a00 0900 0000 2b57  PK..PK........+W
00000010: 904d 257a 05ee 2a00 0000 1e00 0000 0800  .M%z..*.........
00000020: 1c00 666c 6167 2e74 7874 5554 0900 03e2  ..flag.txtUT....
00000030: 7516 5c16 7616 5c75 780b 0001 04e9 0300  u.\.v.\ux.......
00000040: 0004 e903 0000 e8e3 42c0 ef41 80c8 3eb6  ........B..A..>.
00000050: 956e f8ca 97c7 7112 6e17 16f1 25aa 9ab8  .n....q.n...%...
00000060: d82d 5c31 08ad 4f6b 5471 f996 16b6 dd90  .-\1..OkTq......
00000070: 504b 0708 257a 05ee 2a00 0000 1e00 0000  PK..%z..*.......
00000080: 504b 0304 0a00 0000 0000 7b4e 904d 0000  PK........{N.M..
00000090: 0000 0000 0000 0000 0000 0d00 1c00 6a63  ..............jc

 

La signature est mauvaise, en effet, on fixe ça rapidement (j'ai utilisé HxD)

 

switch :: pain ~/ctf/santack2018/MI1/zip $ ~/tools/bruteforce/pkcrack/bin/pkcrack -C hell2.zip -c jcvd-website/images/concert.jpg -P essaie.zip -p concert.jpg
Files read. Starting stage 1 on Mon Dec 24 17:26:20 2018
Generating 1st generation of possible key2_37569 values...done.
Found 4194304 possible key2-values.
Now we're trying to reduce these...
Lowest number: 935 values at offset 30502
Lowest number: 916 values at offset 30485
Lowest number: 879 values at offset 30446
Lowest number: 873 values at offset 30444
Lowest number: 872 values at offset 30443
Lowest number: 852 values at offset 30442
Lowest number: 848 values at offset 30433
Lowest number: 841 values at offset 30426
Lowest number: 807 values at offset 30420
Lowest number: 732 values at offset 30417
Lowest number: 722 values at offset 30416
Lowest number: 712 values at offset 30414
Lowest number: 693 values at offset 30412
Lowest number: 668 values at offset 30411
Lowest number: 627 values at offset 30364
Lowest number: 586 values at offset 30362
Lowest number: 562 values at offset 30360
Lowest number: 528 values at offset 30359
Lowest number: 512 values at offset 30356
Lowest number: 511 values at offset 30354
Lowest number: 510 values at offset 26624
Lowest number: 496 values at offset 26622
Lowest number: 461 values at offset 26621
Lowest number: 437 values at offset 26618
Lowest number: 376 values at offset 26617
Lowest number: 365 values at offset 26616
Lowest number: 347 values at offset 26615
Lowest number: 338 values at offset 26614
Lowest number: 301 values at offset 26611
Lowest number: 296 values at offset 26608
Lowest number: 286 values at offset 26602
Lowest number: 274 values at offset 26601
Lowest number: 272 values at offset 26595
Lowest number: 270 values at offset 26594
Lowest number: 264 values at offset 26549
Lowest number: 261 values at offset 26526
Lowest number: 242 values at offset 26524
Lowest number: 224 values at offset 26517
Lowest number: 219 values at offset 26508
Lowest number: 210 values at offset 26505
Lowest number: 200 values at offset 26504
Lowest number: 195 values at offset 26470
Lowest number: 182 values at offset 26460
Lowest number: 164 values at offset 26459
Lowest number: 163 values at offset 26447
Lowest number: 159 values at offset 26446
Lowest number: 153 values at offset 26374
Lowest number: 143 values at offset 26372
Lowest number: 139 values at offset 26371
Lowest number: 137 values at offset 26364
Lowest number: 133 values at offset 26358
Lowest number: 122 values at offset 26332
Lowest number: 118 values at offset 26330
Lowest number: 110 values at offset 26329
Lowest number: 95 values at offset 26268
Done. Left with 95 possible Values. bestOffset is 26268.
Stage 1 completed. Starting stage 2 on Mon Dec 24 17:26:47 2018
Ta-daaaaa! key0=751f036a, key1=397078fa, key2=d156dfac
Probabilistic test succeeded for 11306 bytes.
Ta-daaaaa! key0=751f036a, key1=397078fa, key2=d156dfac
Probabilistic test succeeded for 11306 bytes.
Ta-daaaaa! key0=751f036a, key1=397078fa, key2=d156dfac

 

Et pafff nous avons nos 3 clés : key0=751f036a, key1=397078fa, key2=d156dfac. Je vous invite à lire le PDF que j'ai mis dans mes sources qui explique très bien à quoi servent ces clés.

 

J'ai perdu 2 / 3 heures à attendre que PKcrack me sorte le mot de passe, mais bon avec les clés c'est inutile ..

 

switch :: pain ~/ctf/santack2018/MI1/zip $ /tmp/pkcrack/bin/zipdecrypt 751f036a 397078fa d156dfac hell2.zip final.zip
switch :: pain ~/ctf/santack2018/MI1/zip $
switch :: pain ~/ctf/santack2018/MI1/zip $ unzip final.zip 
Archive:  final.zip
warning [final.zip]:  zipfile claims to be last disk of a multi-part archive;
  attempting to process anyway, assuming all parts have been concatenated
  together in order.  Expect "errors" and warnings...true multi-part support
  doesn't exist yet (coming soon).
 extracting: flag.txt                
   creating: jcvd-website/
   creating: jcvd-website/js/
  inflating: jcvd-website/js/.DS_Store  
  inflating: jcvd-website/js/bootstrap.min.js  
  inflating: jcvd-website/js/jquery-1.11.3.min.js  
  inflating: jcvd-website/js/bootstrap.js  
  inflating: jcvd-website/js/custom.js  
  inflating: jcvd-website/js/ie10-viewport-bug-workaround.js  
  inflating: jcvd-website/js/jquery.easing.min.js  
  inflating: jcvd-website/.DS_Store  
   creating: jcvd-website/images/
  inflating: jcvd-website/images/concert.jpg  
  inflating: jcvd-website/images/.DS_Store  
  inflating: jcvd-website/images/microphone.jpg  
  inflating: jcvd-website/images/iphone.jpg  
  inflating: jcvd-website/images/header.jpg  
  inflating: jcvd-website/images/writing.jpg  
  inflating: jcvd-website/images/pencil_sharpener.jpg  
  inflating: jcvd-website/index.html  
   creating: jcvd-website/fonts/
  inflating: jcvd-website/fonts/glyphicons-halflings-regular.ttf  
  inflating: jcvd-website/fonts/glyphicons-halflings-regular.woff2  
  inflating: jcvd-website/fonts/glyphicons-halflings-regular.woff  
  inflating: jcvd-website/fonts/glyphicons-halflings-regular.eot  
  inflating: jcvd-website/fonts/glyphicons-halflings-regular.svg  
   creating: jcvd-website/css/
  inflating: jcvd-website/css/.DS_Store  
  inflating: jcvd-website/css/bootstrap.css  
  inflating: jcvd-website/css/custom.css  
  inflating: jcvd-website/css/bootstrap.min.css  
switch :: pain ~/ctf/santack2018/MI1/zip $ cat flag.txt 
IMTLD{z1p_1s_n0t_alw4y5_s4fe}
switch :: pain ~/ctf/santack2018/MI1/zip $ 

 

The flag is : IMTLD{z1p_1s_n0t_alw4y5_s4fe}