sigsegv2
05/12/2019Writeups
10 questions about my system
Auteur: noraj
Difficulté estimée : moyen
Format de Flag : sigsegv{sha1(flag)}
Description :
- openSUSE Leap 15.1
4.12.14-lp151.28.32-default (4.12.14-lp151.28.32.1)
Question n°1: Quelle est la commande que noraj a utilisé à 2019-11-19 22:57:38 UTC+0000
?
Question n°2: Quelle version de gcc a été utilisée pour compiler le kernel ? (string entière)
Question n°3: Quel est le message de debug à 1105416124.1
?
Question n°4: Quelle est l’adresse IP de eth0
et son adresse MAC? (concatène la réponse)
Question n°5: Quelle est la 3ème bibliothèque chargée par sshd
? (chemin entier)
Question n°6: Quels sont le système de fichier et les options de montage de /tmp
? (concatène la réponse)
Question n°7: Quels sont le nom/pid du processus qui utilise le socket UNIX 18707
?
Question n°8: Quelle est la commande entière du pid 364 ?
Question n°9: Quel est l’invocation ID de bash ?
Question n°10: Quel est le PPID of qmgr
process ?
Résolution
$ file chall.raw
chall.raw: ELF 64-bit LSB core file x86-64, version 1 (SYSV)
$ du -sh chall.raw
279M chall.raw
$ strings -a ./chall.raw | grep -i 'Linux version' | uniq
Patch-mainline tags that instead refer to a Linux version number,
[ 0.000000] Linux version 4.12.14-lp151.28.32-default (geeko@buildhost) (gcc version 7.4.1 20190905 [gcc-7-branch revision 275407] (SUSE Linux) ) #1 SMP Wed Nov 13 07:50:15 UTC 2019 (6e1aaad)
Avec la description de ce challenge, on comprend rapidement ce que l’on doit faire: utiliser Volatility afin d’analyser ce dump de mémoire RAM Linux.
The Volatility Framework is a completely open collection of tools, implemented in Python under the GNU General Public License, for the extraction of digital artifacts from volatile memory (RAM) samples.
Volatility et profil
Pour être capable d’analyser un dump de RAM il est nécessaire de fournir à Volatility ce que l’on appelle un profil. Ce dernier permet à Volatility de comprendre l’organisation de la mémoire du dump (structure de données, algorithmes et symboles à utiliser).
Pour Linux, un profil est lié à une distribution ainsi qu’à une version de noyau. D’après la description du challenge, on peut voir que le dump provient d’une machine sous OpenSUSE version 15.1
avec un kernel version 4.12.14-lp151.28.32-default (4.12.14-lp151.28.32.1)
. Nous devons alors trouver un profil respectant exactement ces versions.
Il existe une petite base de profils ici, mais en allant dans Linux > OpenSUSE > x64
, on peut voir que les profils vont de la version 10.2
à 13.1
d’OpenSUSE…
Même après quelques recherches, aucun profil pour OpenSUSE 15.1 n’est disponible.
Nous devons alors créer notre propre profil pour continuer.
OpenSUSE 15.1
Pour pouvoir être en mesure d’analyser notre dump correctement, nous devons installer une OpenSUSE 15.1 avec un kernel 4.12.14-lp151.28.32-default (4.12.14-lp151.28.32.1)
.
On peut prendre la net install car plus légère à télécharger (125 MB).
À l’étape System Role
de l’installation, on peut choisir une installation de type Server
, qui sera plus rapide à installer (car pas d’interface graphique).
# OpenSUSES 15.1
$ uname -a
Linux linux-ua2c 4.12.14-lp151.28.32-default #1 SMP Wed Nov 13 07:50:15 UTC 2019 (6e1aaad) x86_64 x86_64 x86_64 GNU/Linux
$ uname -r
4.12.14-lp151.28.32-default
Après installation, on peut voir que nous avons exactement la bonne version du noyau que nous voulions.
Contrairement à d’autres challenges semblables, où il est nécessaire de télécharger une version spécifique du kernel.
Nous possédons alors la bonne version de la distribution (OpenSUSE 15.1) ainsi que le bon kernel ( 4.12.14-lp151.28.32-default
). On peut donc passer à la création de notre profil.
Création du profil
Nous allons utiliser cette page du wiki de Volatility qui explique comment créer un profil sous Linux.
Installation des dépendances
# OpenSUSES 15.1
$ sudo zypper install libdwarf-tools
Installation de Volatility
# OpenSUSES 15.1
$ sudo zypper install git
$ git clone https://github.com/volatilityfoundation/volatility
Création du profil
# OpenSUSES 15.1
$ cd volatility/tools/linux/
$ make
make -C //lib/modules/4.12.14-lp151.28.32-default/build CONFIG_DEBUG_INFO=y M="/home/user/volatility/tools/linux" modules
make[1]: *** //lib/modules/4.12.14-lp151.28.32-default/build: No such file or directory. Stop.
make: *** [Makefile:10: dwarf] Error 2
Lors de la création du profil, nous avons une erreur de compilation, en effet, il manque le dossier /build
dans /lib/modules/4.12.14-lp151.28.32-default
…
Après quelques recherches on tombe sur ce post d’un forum sur OpenSUSE.
I tried to resolve it by installing
kernel-source
,kernel-devel
packages
On y apprend qu’on peut essayer d’installer le package kernel-devel
pour avoir un dossier /build
.
# OpenSUSES 15.1
$ sudo zypper install kernel-devel
$ make
make -C //lib/modules/4.12.14-lp151.28.32-default/build CONFIG_DEBUG_INFO=y M="/home/user/volatility/tools/linux" modules
make[1]: Entering directory '/usr/src/linux-4.12.14-lp151.28.32-obj/x86_64/default'
CC [M] /home/user/volatility/tools/linux/module.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/user/volatility/tools/linux/module.mod.o
LD [M] /home/user/volatility/tools/linux/module.ko
make[1]: Leaving directory '/usr/src/linux-4.12.14-lp151.28.32-obj/x86_64/default'
dwarfdump -di module.ko > module.dwarf
make -C //lib/modules/4.12.14-lp151.28.32-default/build M="/home/user/volatility/tools/linux" clean
make[1]: Entering directory '/usr/src/linux-4.12.14-lp151.28.32-obj/x86_64/default'
CLEAN /home/user/volatility/tools/linux/.tmp_versions
CLEAN /home/user/volatility/tools/linux/Module.symvers
make[1]: Leaving directory '/usr/src/linux-4.12.14-lp151.28.32-obj/x86_64/default'
# OpenSUSES 15.1
$ sudo zypper install zip
$ sudo zip OpenSUSE151.zip volatility/tools/linux/module.dwarf /boot/System.map-4.12.14-lp151.28.32-default
adding: volatility/tools/linux/module.dwarf (deflated 91%)
adding: boot/System.map-4.12.14-lp151.28.32-default (deflated 79%)
La compilation s’est bien passée, notre profil est maintenant prêt. Pour terminer, nous devons créer un zip (OpenSUSE151.zip
) avec les fichiers nécessaires. Il ne reste plus qu’à l’envoyer sur notre machine de travail.
# hôte
$ sudo socat tcp-listen:7777 - > OpenSUSE151.zip
# OpenSUSES 15.1
$ sudo cat OpenSUSE151.zip | nc -N 192.168.56.1 7777
Utiliser le profil
On peut maintenant ajouter notre profil à Volatility.
To create the profile, place both the
module.dwarf
and thesystem.map
file into a zip file. Then move this zip file undervolatility/plugins/overlays/linux/
.
$ cp OpenSUSE151.zip /opt/volatility/volatility/plugins/overlays/linux/
$ vol.py --info | grep 'Linux'
...
LinuxOpenSUSE151x64 - A Profile for Linux OpenSUSE151 x64
...
On peut maintenant utiliser Volatility pour manipuler notre image.
L’option --info
permet d’avoir de nombreuses informations, notamment les profils supportés, on retrouve bien notre profil sous le nom LinuxOpenSUSE151x64
.
Pour trouver les bonnes informations pour chaque question, nous allons utiliser cette page du wiki. Cette dernière permet de ne pas se perdre parmis les nombreuses commandes de Volatility.
Question n°1: Quelle est la commande que noraj a utilisé à 2019-11-19 22:57:38 UTC+0000
?
linux_bash
- Recover bash history from bash process memory
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_bash
Pid Name Command Time Command
----- ------- ------------------------------ -------
...
1498 bash 2019-11-19 22:57:38 UTC+0000 python3 -m http.server 1337
...
$ echo -n 'python3 -m http.server 1337' | openssl dgst -sha1 | awk '{print $2}'
1d4893cc25cc5453be125227fb8ac34988c29ad0
sigsegv{1d4893cc25cc5453be125227fb8ac34988c29ad0}
Question n°2: Quelle version de gcc
a été utilisée pour compiler le kernel ? (string entière)
linux_banner
- Prints the Linux banner information
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_banner
Linux version 4.12.14-lp151.28.32-default (geeko@buildhost) (gcc version 7.4.1 20190905 [gcc-7-branch revision 275407] (SUSE Linux) ) #1 SMP Wed Nov 13 07:50:15 UTC 2019 (6e1aaad)
$ echo -n 'gcc version 7.4.1 20190905 [gcc-7-branch revision 275407] (SUSE Linux)' | openssl dgst -sha1 | awk '{print $2}'
524993e05b0ded8e112a134c68d04b319de13423
sigsgv{524993e05b0ded8e112a134c68d04b319de13423}
Question n°3: Quel est le message de debug à 1105416124.1
?
linux_dmesg
- Gather dmesg buffer
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_dmesg | grep -i '1105416124.1'
[1105416124.1] Magic number: 11:134:907
$ echo -n 'Magic number: 11:134:907' | openssl dgst -sha1 | awk '{print $2}'
77038af8d03d8b4cdb28e6e592b87a2c3195d1fe
sigsegv{77038af8d03d8b4cdb28e6e592b87a2c3195d1fe}
Question n°4: Quelle est l’adresse IP de eth0
et son adresse MAC ? (concatène la réponse)
linux_ifconfig
- Gathers active interfaces
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_ifconfig
Interface IP Address MAC Address Promiscous Mode
----------- ------------------ ------------------ ---------------
lo 127.0.0.1 00:00:00:00:00:00 False
eth0 192.168.1.94 08:00:27:93:fe:6c False
lo 127.0.0.1 00:00:00:00:00:00 False
$ echo -n '192.168.1.9408:00:27:93:fe:6c' | openssl dgst -sha1 | awk '{print $2}'
cba34462a24124ada4e4882a4db5104b254343f8
sigsegv{cba34462a24124ada4e4882a4db5104b254343f8}
Question n°5: Quelle est la 3ème bibliothèque chargée par sshd
? (chemin entier)
linux_library_list
- Lists libraries loaded into a process
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_library_list | grep -i 'sshd'
Task Pid Load Address Path
---------- ------ ------------------ ----
sshd 1271 0x00007f0e8ec8a000 /usr/lib64/libgpg-error.so.0
sshd 1271 0x00007f0e8eeaa000 /lib64/libresolv.so.2
sshd 1271 0x00007f0e8f0c1000 /usr/lib64/libkeyutils.so.1
sshd 1271 0x00007f0e8f2c5000 /usr/lib64/libkrb5support.so.0
...
$ echo -n '/usr/lib64/libkeyutils.so.1' | openssl dgst -sha1 | awk '{print $2}'
bcf5ae7945ce4e711d11861ec2cc1f75efbe758b
sigsegv{bcf5ae7945ce4e711d11861ec2cc1f75efbe758b}
Question n°6: Quels sont le système de fichier et les options de montage de /tmp
? (concatène la réponse)
$ strings -a chall.raw | grep -i '/tmp'
/@/tmp /tmp rw,relatime shared:32 - btrfs /dev/sda2 rw,space_cache,subvolid=260,subvol=/@/tmp
$ echo -n 'btrfsrw,relatime' | openssl dgst -sha1 | awk '{print $2}'
d27802b77f4a14b3745ab47aaa86cfdc3c231394
sigsegv{d27802b77f4a14b3745ab47aaa86cfdc3c231394}
Question n°7: Quels sont le nom/pid du processus qui utilise le socket UNIX 18707
?
linux_lsof
- Lists file descriptors and their path
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_lsof
Offset Name Pid FD Path
------------------ ---------------- -------- ----- ----
...
0xffff88000c2481c0 wickedd-nanny 866 4 socket:[18707]
...
$ echo -n 'wickedd-nanny/866' | openssl dgst -sha1 | awk '{print $2}'
6b95288247a023c860fe0848f3990cc25ce7d697
sigsegv{6b95288247a023c860fe0848f3990cc25ce7d697}
Question n°8: Quelle est la commande entière du pid 364?
linux_psaux
- Gathers processes along with full command line and start time
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_psaux | grep 'haveged'
Pid Uid Gid Arguments
364 0 0 /usr/sbin/haveged -w 1024 -v 0 -F
$ echo -n '/usr/sbin/haveged -w 1024 -v 0 -F' | openssl dgst -sha1 | awk '{print $2}'
4c0bed3d6381e2014d77a35e6931d604e4bd8ec1
sigsegv{4c0bed3d6381e2014d77a35e6931d604e4bd8ec1}
Question n°9: Quel est l’invocation ID de bash ?
linux_psenv
- Gathers processes along with their static environment variables
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_psenv
Name Pid Environment
...
bash 1498 LANG= PATH=/usr/local/bin:/bin:/usr/bin INVOCATION_ID=d6dd8e717833428bac595d565958fdf4 TERM=linux JOURNAL_STREAM=9:21427 LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= HOME=/home/noraj USER=noraj SHELL=/bin/bash MAIL=/var/mail/noraj LOGNAME=noraj XDG_SESSION_ID=1 XDG_RUNTIME_DIR=/run/user/1000 XDG_SEAT=seat0 XDG_VTNR=1
$ echo -n 'd6dd8e717833428bac595d565958fdf4' | openssl dgst -sha1 | awk '{print $2}'
a64603f7b14cdd948ab9f065befc350854e0a25d
sigsegv{4c0bed3d6381e2014d77a35e6931d604e4bd8ec1}
Question n°10: Quel est le PPID of qmgr
process?
linux_pslist
- Gather active tasks by walking the task_struct->task list
$ vol.py -f chall.raw --profile=LinuxOpenSUSE151x64 linux_pslist
Offset Name Pid PPid Uid Gid DTB Start Time
------------------ -------------------- --------------- --------------- --------------- ------ ------------------ ----------
0xffff88000a6f2180 qmgr 1371 1368 51 51 0x000000000d35c000 2019-11-19 22:53:07 UTC+0000
$ echo -n '1368' | openssl dgst -sha1 | awk '{print $2}'
570722b44ec7003126d686b70703051e72ff7408
sigsegv{570722b44ec7003126d686b70703051e72ff7408}
Je rim et je ram
Description
Auteur: jenaye
Difficulté estimée : facile
Description:
- J’ai l’impression que le propriétaire de l’ordi fait encore des trucs bizarres.
Si vous avez trouvé un flag trivial c’est un fake flag !
Résolution
$ file yolo2.raw
yolo2.raw: ELF 64-bit LSB core file x86-64, version 1 (SYSV)
$ strings -a ./yolo2.raw | grep -i 'Linux version' | uniq
$ du -sh yolo2.raw
1,1G yolo2.raw
Aucune trace de la chaine Linux version
dans ce dump, il s’agit peut-être d’un dump Windows.
ìmageinfo
- Identify information for the image
$ vol.py -f yolo2.raw imageinfo
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win2008SP2x64, VistaSP2x64, VistaSP1x64, Win2008SP1x64
AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
AS Layer2 : VirtualBoxCoreDumpElf64 (Unnamed AS)
AS Layer3 : FileAddressSpace (/home/adel/ctf/sigsegv/forensic_je_rim_et_je_ram/yolo2.raw)
PAE type : No PAE
DTB : 0x124000L
KDBG : 0xf80001988f20L
Number of Processors : 1
Image Type (Service Pack) : 2
KPCR for CPU 0 : 0xfffff8000198a500L
KUSER_SHARED_DATA : 0xfffff78000000000L
Image date and time : 2019-11-14 23:06:11 UTC+0000
Image local date and time : 2019-11-15 00:06:11 +0100
Nous avons bien un dump Windows, les profils conseillés sont Win2008SP2x64, VistaSP2x64, VistaSP1x64, Win2008SP1x64
.
pslist
- Print all running processes by following the EPROCESS lists
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 pslist
Offset(V) Name PID PPID Thds Hnds Sess Start
------------------ -------------- ------ ------ ------ -------- ------ ------ --------
...
0xfffffa8001222c10 iexplore.exe 2284 3016 18 710 1 1 21:37:58
0xfffffa8003f1f760 notepad.exe 156 2748 1 51 1 0 22:40:37
...
On peut voir 2 processus intéressants, une instance d’Internet Explorer et une autre de Notepad.
Internet Explorer
iehistory
- Reconstruct Internet Explorer cache / history
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 iehistory
...
**************************************************
Process: 844 svchost.exe
Cache type "URL " at 0x135d2200
Record length: 0x100
Location: :2019111520191116: sigsegv@http://10.0.2.2:8000/url.log
Last modified: 2019-11-15 00:00:58 UTC+0000
Last accessed: 2019-11-14 23:00:58 UTC+0000
File Offset: 0x100, Data Offset: 0x0, Data Length: 0x0
**************************************************
...
La sortie de la commande iehistory
étant très longue, nous allons commencer par filtrer sur le motif http
.
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 iehistory | grep -ioE 'http.*'
...
https://www.google.fr/?url=https://cryptobin.co/71q7y462
...
https://www.google.fr/search?hl=fr&source=hp&biw=&bih=&q=https%3A%2F%2Fprivatebin.net%2F%3F9d8a660cfd4f182f%23HK8pYJaHwjMWJaWRx3zvr81uHE5drHTHw61NqHeXXsib&btnG=Recherche+Google&iflsig=AAP1E1EAAAAAXc6smtsHa_VLLEJu4aNDlsItMaA0O13F&gbv=2
...
On peut voir 2 recherches Google intéressantes dans l’historique de navigation:
https://cryptobin.co
https://privatebin.net
Ces 2 sites sont similaires à pastbin.com
, la seule différence est que les notes sont chiffrées et qu’il faut donc un mot de passe pour accéder à la note partagée.
Sur https://cryptobin.co/71q7y462
, nous avons des données en base64
que nous devons déchiffrer.
$ echo -n 'eyJpdiI6IkVXWlVOY0trNDN6YXlZb3VtZVFPa2c9PSIsInYiOjEsIml0ZXIiOjEwMDAsImtzIjoyNTYsInRzIjo2NCwibW9kZSI6ImNjbSIsImFkYXRhIjoiIiwiY2lwaGVyIjoiYWVzIiwic2FsdCI6InJjQXVrZXAwbEdvPSIsImN0IjoiYTN5SWpoWG9YNDA4M2lyZzk5SURTWHVEUjg2elRsT0VMTGlCWmVNRSJ9' | base64 -d
{
"iv":"EWZUNcKk43zayYoumeQOkg==",
"v":1,
"iter":1000,
"ks":256,
"ts":64,
"mode":"ccm",
"adata":"",
"cipher":"aes",
"salt":"rcAukep0lGo=",
"ct":"a3yIjhXoX4083irg99IDSXuDR86zTlOELLiBZeME"
}
Sur https://privatebin.net/?9d8a660cfd4f182f#HK8pYJaHwjMWJaWRx3zvr81uHE5drHTHw61NqHeXXsib
, nous devons aussi fournir un mot de passe pour accéder aux données. Nous devons peut-être trouver ce mot de passe dans le dump.
Flag trivial
filescan
- Pool scanner for file objects
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 filescan | grep -i '\\sigsegv' | grep -v -i 'AppData'
...
0x000000001bf0ff20 15 0 RW-rw- \Device\HarddiskVolume1\Users\sigsegv\Documents\user.txt
...
On remarque un fichier user.txt
dans l’espace de l’utilisateur sigsegv
. Essayons de dumper le fichier grace à son offset.
dumpfiles
- Extract memory mapped and cached files
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 dumpfiles -Q 0x000000001bf0ff20 --dump-dir=.
DataSectionObject 0x1bf0ff20 None \Device\HarddiskVolume1\Users\sigsegv\Documents\user.txt
$ file file.None.0xfffffa8005f4da30.dat
file.None.0xfffffa8005f4da30.dat: ASCII text, with no line terminators
$ cat file.None.0xfffffa8005f4da30.dat
sigsevg{MySuperFlag}
C’est sûrement le flag trivial de la consigne. Ce dernier ne respecte pas le bon format, nous avons un sigsevg
au lieu d’un sigsegv
.
Notepad
On se rappelle qu’une instance de Notepad a été lancée, peut-être que le mot de passe à été saisie dans celle-ci. Ce post explique comment bien analyser un dump de Notepad.
pslist
- Print all running processes by following the EPROCESS lists
# trouver le PID de notepad
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 pslist | grep -i 'notepad'
0xfffffa8003f1f760 notepad.exe 156 2748 1 51 1 0 2019-11-14 22:40:37 UTC+0000
memdump
- Dump the addressable memory for a process
# dumper le processus
$ vol.py -f yolo2.raw --profile=Win2008SP2x64 memdump --dump-dir=. -p 156
Volatility Foundation Volatility Framework 2.6.1
************************************************************************
Writing notepad.exe [ 156] to 156.dmp
# recherche
$ strings -e l 156.dmp | grep -i 'password'
password : RTFM_YELAA
# -e encoding
# s = single-7-bit-byte characters
# S = single-8-bit-byte characters
# b = 16-bit bigendian
# l = 16-bit littleendian
# B = 32-bit bigendian
# L = 32-bit littleendian
La petite subtilité de Notepad est que ce dernier stock les fichiers texts en 16 bits en little-endian. C’est pour cela que l’on fourni l’option -e l
à strings
.
On trouve alors le mot de passe RTFM_YELAA
, ce dernier permet de déchiffrer le contenu présent sur https://cryptobin.co/71q7y462
. On trouve alors le flag.
sigsegv2{Pow3r_oF_Vol}