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}