sigsegv2

Writeups


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 /builddans /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 the system.map file into a zip file. Then move this zip file under volatility/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 versiondans 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.txtdans 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 sigsevgau 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}