C’est la rentrée

Académie de l’investigation - C’est la rentrée was an easy challenge and the first part of a series of forensic challenges (50 pts for this first part).

Bienvenue à l’académie de l’investigation numérique ! Votre mission, valider un maximum d’étapes de cette série afin de démontrer votre dextérité en analyse mémoire GNU/Linux. Première étape : retrouvez le HOSTNAME, le nom de l’utilisateur authentifié lors du dump et la version de Linux sur lequel le dump a été fait. Format du flag : FCSC{hostname:user:x.x.x-x-amdxx}

We have to find the hostname, authenticated user and kernel version of a given memory dump.

C’est la rentrée: Exploit

Volatility doesn’t have any Linux profile by default, and we don’t know the kernel version of this memory dump (That’s the point of the challenge).

So, we gonna have to use the best CTF tool: strings!

First of all, let’s search for the hostname:

magnussen@funcMyLife:~/cestlarentree$ strings dmp.mem | grep hostname:
%sset-hostname: hostname set via dbus failed, fallback to "sethostname"
%sset-hostname: couldn't set the system hostname to '%s': (%d) %s
%sset-hostname: you should use hostnamed when systemd hardening is in effect!
%sget-hostname: "%s" (last on set)
%sget-hostname: "%s" (from dbus)
%sget-hostname: couldn't get the system hostname: (%d) %s
%sget-hostname: system hostname too long: "%s"
%sget-hostname: "%s"
MESSAGE=<info>  [1585265017.0294] hostname: hostname changed from (none) to "challenge.fcsc"
MESSAGE=<info>  [1585265017.0294] hostname: hostname: using hostnamed
27 00:23:37 NetworkManager[636]: <info>  [1585265017.0294] hostname: hostname changed from (none) to "challenge.fcsc"
-[27 00:23:37 NetworkManager[636]: <info>  [1585265017.0294] hostname: hostname: using hostnamed1'

Good, now let’s check for the user, we know the hostname, so it’ll be pretty simple to find the authenticated user, let’s search for a prompt:

magnussen@funcMyLife:~/cestlarentree$ strings dmp.mem | grep @challenge
Lesage@challenge: ~/Documents 129x37
Lesage@challenge: ~/Documents/temp
Lesage@challenge: ~/Documents/temp 129x37
Lesage@challenge: ~/Documents/temp
)}root@challenge:~#
Lesage@challenge: ~e
Lesage@challenge: ~e
Lesage@challenge: ~e

Two out of three! Let’s get that kernel version! Let’s check for boot images:

magnussen@funcMyLife:~/cestlarentree$ strings dmp.mem | grep BOOT
BOOT_IMAGE=/boot/vmlinuz-5.4.0-4-amd64 root=UUID=536c82dd-f1c5-43ce-b65d-c94e5c4a5031 ro quiet
TIMESTAMP_BOOTTIME=905.989541
TIMESTAMP_BOOTTIME=905.989548
TIMESTAMP_BOOTTIME=905.989555
TIMESTAMP_BOOTTIME=10505.644058
TIMESTAMP_BOOTTIME=10505.644124
BOOTUP_THEMEI
BOOTUP_THEMEq
NOTICE BOOTSTRAP PROGRESS=100 TAG=done SUMMARY="Done"

Nice! We have everything, just have to format the flag and submit it!

FCSC{challenge.fcsc:Lesage:5.4.0-4-amd64}

This was an easy challenge to get started in the forensic category. It allows us to find the kernel version in order to create a volatility profile that we’ll be useful for the other challenges.

Porte Dérobée

Académie de l’investigation - Porte Dérobée was an easy challenge and the second part of a series of forensic challenges (50 pts for this second part).

Un poste distant est connecté au poste en cours d’analyse via une porte dérobée avec la capacité d’exécuter des commandes. Quel est le numéro de port à l’écoute de cette connexion ? Quelle est l’adresse IP distante connectée au moment du dump ? Quel est l’horodatage de la création du processus en UTC de cette porte dérobée ? Format du flag : FCSC{port:IP:YYYY-MM-DD HH:MM:SS}

There’s a backdoor on the computer we’re analyzing, we have to find the listening port, the source ip of this backdoor and when this process was created.

Porte Dérobée: Exploit

I’ve created a volatility profile in order to analyze this memory dump (The profile is based on a Debian 9.2.1 with 5.4.0-4-amd64 kernel).

If you want to see the steps to create a Linux volatility profile, you can read Onosh’s write-up

Let’s enumerate the established connection at the time of the memory dump with volatility:

magnussen@funcMyLife:~/portederobee$ python /home/magnussen/tools/volatility/vol.py -f dmp.mem --profile LinuxDebianx64 linux_netstat | grep ESTABLISHED
Volatility Foundation Volatility Framework 2.6.1
TCP      10.42.42.131    :36970 116.203.52.118  :  443 ESTABLISHED                   tor/706  
TCP      10.42.42.131    :37252 163.172.182.147 :  443 ESTABLISHED                   tor/706  
TCP      fd:6663:7363:1000:c10b:6374:25f:dc37:36280 fd:6663:7363:1000:55cf:b9c6:f41d:cc24:58014 ESTABLISHED                  ncat/1515
TCP      10.42.42.131    :47106 216.58.206.226  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :55224 151.101.121.140 :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :55226 151.101.121.140 :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :53190 104.124.192.89  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :45652 35.190.72.21    :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :47102 216.58.206.226  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :47104 216.58.206.226  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :38186 216.58.213.142  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :47100 216.58.206.226  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :50612 104.93.255.199  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :58772 185.199.111.154 :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :38184 216.58.213.142  :  443 ESTABLISHED              chromium/119187
TCP      10.42.42.131    :57000 10.42.42.134    :   22 ESTABLISHED                   ssh/119468
TCP      fd:6663:7363:1000:c10b:6374:25f:dc37:36280 fd:6663:7363:1000:55cf:b9c6:f41d:cc24:58014 ESTABLISHED                    sh/119511
TCP      127.0.0.1       :38498 127.0.0.1       :34243 ESTABLISHED                   cli/119514
TCP      127.0.0.1       :34243 127.0.0.1       :38498 ESTABLISHED                   cli/119514
TCP      10.42.42.131    :51858 10.42.42.128    :  445 ESTABLISHED             smbclient/119577

Ok so we see that a connection from fd:6663:7363:1000:55cf:b9c6:f41d:cc24 was established on the port 36280 and that the process is netcat, this process is frequently used by reverse shell.

We know the attacker address and the port the backdoor uses, we just have to find when the process started, let’s use its PID to do so.

magnussen@funcMyLife:~/portederobee$ python /home/magnussen/tools/volatility/vol.py -f dmp.mem --profile LinuxDebianx64 linux_pslist -p 1515
Volatility Foundation Volatility Framework 2.6.1
Offset             Name                 Pid             PPid            Uid             Gid    DTB                Start Time
------------------ -------------------- --------------- --------------- --------------- ------ ------------------ ----------
0xffff9d72c014be00 ncat                 1515            1513            1001            1001   0x000000003e3d0000 2020-03-26 23:24:20 UTC+0000

Nice, we have our flag!

FCSC{36280:fd:6663:7363:1000:55cf:b9c6:f41d:cc24:2020-03-26 23:24:20}

This was an easy challenge, the hardest part was to create the volatility profile to analyze the memory dump.

Administration

Académie de l’investigation - Administration was an easy challenge and the fourth part of a series of Forensic challenges (50 pts for this fourth part).

Ce poste administre un serveur distant avec le protocole SSH à l’aide d’une authentification par clé (clé protégée par mot de passe). La clé publique a été utilisée pour chiffrer le message ci-joint (flag.txt.enc). Retrouvez et reconstituez la clé en mémoire qui permettra de déchiffrer ce message. Le fichier de dump à analyser est identique au challenge C’est la rentrée.

We have a file that was signed with the public ssh key and we have to read the content of this file.

Administration: Exploit

The file was encrypted with the public RSA key (signed), we have to find the private key to decrypt it. Let’s use rsakeyfind to find the private key:

magnussen@funcMyLife:~/administration$ rsakeyfind dmp.mem
FOUND PRIVATE KEY AT c64ac50
version =
00
modulus =
00 d7 1e 77 82 8c 92 31 e7 69 02 a2 d5 5c 78 de
a2 0c 8f fe 28 59 31 df 40 9c 60 61 06 b9 2f 62
40 80 76 cb 67 4a b5 59 56 69 17 07 fa f9 4c bd
6c 37 7a 46 7d 70 a7 67 22 b3 4d 7a 94 c3 ba 4b
7c 4b a9 32 7c b7 38 95 45 64 a4 05 a8 9f 12 7c
4e c6 c8 2d 40 06 30 f4 60 a6 91 bb 9b ca 04 79
11 13 75 f0 ae d3 51 89 c5 74 b9 aa 3f b6 83 e4
78 6b cd f9 5c 4c 85 ea 52 3b 51 93 fc 14 6b 33
5d 30 70 fa 50 1b 1b 38 81 13 8d f7 a5 0c c0 8e
f9 63 52 18 4e a9 f9 f8 5c 5d cd 7a 0d d4 8e 7b
ee 91 7b ad 7d b4 92 d5 ab 16 3b 0a 8a ce 8e de
47 1a 17 01 86 7b ab 99 f1 4b 0c 3a 0d 82 47 c1
91 8c bb 2e 22 9e 49 63 6e 02 c1 c9 3a 9b a5 22
1b 07 95 d6 10 02 50 fd fd d1 9b be ab c2 c0 74
d7 ec 00 fb 11 71 cb 7a dc 81 79 9f 86 68 46 63
82 4d b7 f1 e6 16 6f 42 63 f4 94 a0 ca 33 cc 75
13
publicExponent =
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01
privateExponent =
62 b5 60 31 4f 3f 66 16 c1 60 ac 47 2a ff 6b 69
00 4a b2 5c e1 50 b9 18 74 a8 e4 dc a8 ec cd 30
bb c1 c6 e3 c6 ac 20 2a 3e 5e 8b 12 e6 82 08 09
38 0b ab 7c b3 cc 9c ce 97 67 dd ef 95 40 4e 92
e2 44 e9 1d c1 14 fd a9 b1 dc 71 9c 46 21 bd 58
88 6e 22 15 56 c1 ef e0 c9 8d e5 80 3e da 7e 93
0f 52 f6 f5 c1 91 90 9e 42 49 4f 8d 9c ba 38 83
e9 33 c2 50 4f ec c2 f0 a8 b7 6e 28 25 56 6b 62
67 fe 08 f1 56 e5 6f 0e 99 f1 e5 95 7b ef eb 0a
2c 92 97 57 23 33 36 07 dd fb ae f1 b1 d8 33 b7
96 71 42 36 c5 a4 a9 19 4b 1b 52 4c 50 69 91 f0
0e fa 80 37 4b b5 d0 2f b7 44 0d d4 f8 39 8d ab
71 67 59 05 88 3d eb 48 48 33 88 4e fe f8 27 1b
d6 55 60 5e 48 b7 6d 9a a8 37 f9 7a de 1b cd 5d
1a 30 d4 e9 9e 5b 3c 15 f8 9c 1f da d1 86 48 55
ce 83 ee 8e 51 c7 de 32 12 47 7d 46 b8 35 df 41
prime1 =
00
prime2 =
00
exponent1 =
00
exponent2 =
00
coefficient =
00

FOUND PRIVATE KEY AT 1084c490
version =
00
modulus =
00 d7 1e 77 82 8c 92 31 e7 69 02 a2 d5 5c 78 de
a2 0c 8f fe 28 59 31 df 40 9c 60 61 06 b9 2f 62
40 80 76 cb 67 4a b5 59 56 69 17 07 fa f9 4c bd
6c 37 7a 46 7d 70 a7 67 22 b3 4d 7a 94 c3 ba 4b
7c 4b a9 32 7c b7 38 95 45 64 a4 05 a8 9f 12 7c
4e c6 c8 2d 40 06 30 f4 60 a6 91 bb 9b ca 04 79
11 13 75 f0 ae d3 51 89 c5 74 b9 aa 3f b6 83 e4
78 6b cd f9 5c 4c 85 ea 52 3b 51 93 fc 14 6b 33
5d 30 70 fa 50 1b 1b 38 81 13 8d f7 a5 0c c0 8e
f9 63 52 18 4e a9 f9 f8 5c 5d cd 7a 0d d4 8e 7b
ee 91 7b ad 7d b4 92 d5 ab 16 3b 0a 8a ce 8e de
47 1a 17 01 86 7b ab 99 f1 4b 0c 3a 0d 82 47 c1
91 8c bb 2e 22 9e 49 63 6e 02 c1 c9 3a 9b a5 22
1b 07 95 d6 10 02 50 fd fd d1 9b be ab c2 c0 74
d7 ec 00 fb 11 71 cb 7a dc 81 79 9f 86 68 46 63
82 4d b7 f1 e6 16 6f 42 63 f4 94 a0 ca 33 cc 75
13
publicExponent =
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01
privateExponent =
62 b5 60 31 4f 3f 66 16 c1 60 ac 47 2a ff 6b 69
00 4a b2 5c e1 50 b9 18 74 a8 e4 dc a8 ec cd 30
bb c1 c6 e3 c6 ac 20 2a 3e 5e 8b 12 e6 82 08 09
38 0b ab 7c b3 cc 9c ce 97 67 dd ef 95 40 4e 92
e2 44 e9 1d c1 14 fd a9 b1 dc 71 9c 46 21 bd 58
88 6e 22 15 56 c1 ef e0 c9 8d e5 80 3e da 7e 93
0f 52 f6 f5 c1 91 90 9e 42 49 4f 8d 9c ba 38 83
e9 33 c2 50 4f ec c2 f0 a8 b7 6e 28 25 56 6b 62
67 fe 08 f1 56 e5 6f 0e 99 f1 e5 95 7b ef eb 0a
2c 92 97 57 23 33 36 07 dd fb ae f1 b1 d8 33 b7
96 71 42 36 c5 a4 a9 19 4b 1b 52 4c 50 69 91 f0
0e fa 80 37 4b b5 d0 2f b7 44 0d d4 f8 39 8d ab
71 67 59 05 88 3d eb 48 48 33 88 4e fe f8 27 1b
d6 55 60 5e 48 b7 6d 9a a8 37 f9 7a de 1b cd 5d
1a 30 d4 e9 9e 5b 3c 15 f8 9c 1f da d1 86 48 55
ce 83 ee 8e 51 c7 de 32 12 47 7d 46 b8 35 df 41
prime1 =
00
prime2 =
00
exponent1 =
00
exponent2 =
00
coefficient =
00

Ok, we just have to recreate the key pair and dump the private key, here’s the python script:

#!/usr/bin/python3
from Crypto.PublicKey import RSA

n = 27156259324364494546819374388173785636458745291644993656824052031192832665358626503824931967165063745738985155119632190909321739257721575254417781138851315918480436949082522936024649499965168635833472768161976247672142217286254570819498806298839620160775476215759967149684677314805111395364593027482965588868928996365215081601336731466193713741949208719563914532447046849652165136410573886954569273298157849675625380629094578684611548488935568178937156287424712755109581855128863319366210889843193945634323967939306175015830804489787158898856492500262280275347410451775447871929463819519225112797600024987362493494547
e = 65537
d = 12460793603648154172634576294324764356921851601543376249263971385355308664001474224072254667082530432608492326239491878557534268321073641012723370224568362486847791322959696503229217995375933460744071182449104318476534793448468002100858570014170698345588600649409245649408999743821342293382425828500964969230457875702866061208039614953232618242245516551805487351387027773141972856162319523928419780405972969066802476877491166892646959172911316485769848621265023891332664138536799344975526764381672350159251366511979950064130731366992390823381013182186815338822199229913107286819591289270388870750262162515570617343809

private_key = RSA.construct((n, e, d))

with open('private.pem', "wb") as target:
    target.write(private_key.exportKey())

We have the private key, let’s use openssl to decrypt the flag.txt.enc file.

magnussen@funcMyLife:~/administration$ openssl rsautl -decrypt -inkey private.pem -in flag.txt.enc -out flag.txt
magnussen@funcMyLife:~/administration$ cat flag.txt
FCSC{ac5cad66114d4866a4b55e43cb8896cc4947855241b5af8d2f8a123c36083d98}

Yeah! We have our flag!

This was an easy challenge, the hardest part was to find the good tool to extract the key.

Premiers artéfacts

Académie de l’investigation - Premiers artéfacts was a medium challenge and the fifth part of a series of Forensic challenges (200 pts for this first part).

Pour avancer dans l’analyse, vous devez retrouver : Le nom de processus ayant le PID 1254. La commande exacte qui a été exécutée le 2020-03-26 23:29:19 UTC. Le nombre d’IP-DST unique en communications TCP établies (état ESTABLISHED) lors du dump. Format du flag : FCSC{nom_du_processus:une_commande:n}

We have to find the process with the PID 1254, the command executed at 2020-03-26 23:29:19 UTC and the number of established connection.

Premiers artéfacts: Exploit

Let’s use our volatility profile to retrieve the name of the process with the PID 1254:

magnussen@funcMyLife:~/premierartefact$ python /home/magnussen/tools/volatility/vol.py -f dmp.mem --profile LinuxDebianx64 linux_psxview |grep 1254
Volatility Foundation Volatility Framework 2.6.1
INFO    : volatility.debug    : SLUB is currently unsupported.
0x000000003fdccd80 pool-xfconfd           1254 False  True   False    False      False   False

For the command executed at 2020-03-26 23:29:19 UTC, we’ll use linux_bash:

magnussen@funcMyLife:~/premierartefact$ python /home/magnussen/tools/volatility/vol.py -f dmp.mem --profile LinuxDebianx64 linux_bash
Volatility Foundation Volatility Framework 2.6.1
Pid      Name                 Command Time                   Command
-------- -------------------- ------------------------------ -------
    1523 bash                 2020-03-26 23:24:18 UTC+0000   rm .bash_history
    1523 bash                 2020-03-26 23:24:18 UTC+0000   exit
    1523 bash                 2020-03-26 23:24:18 UTC+0000   vim /home/Lesage/.bash_history
    1523 bash                 2020-03-26 23:24:27 UTC+0000   ss -laupt
    1523 bash                 2020-03-26 23:26:06 UTC+0000   rkhunter -c
    1523 bash                 2020-03-26 23:29:19 UTC+0000   nmap -sS -sV 10.42.42.0/24
    1523 bash                 2020-03-26 23:31:31 UTC+0000   ?+??U
    1523 bash                 2020-03-26 23:31:31 UTC+0000   ip -c addr
    1523 bash                 2020-03-26 23:38:00 UTC+0000   swapoff -a
    1523 bash                 2020-03-26 23:38:05 UTC+0000   swapon -a
    1523 bash                 2020-03-26 23:40:18 UTC+0000   ls
    1523 bash                 2020-03-26 23:40:23 UTC+0000   cat LiME.txt
    1523 bash                 2020-03-26 23:40:33 UTC+0000   cd LiME/src/
    1523 bash                 2020-03-26 23:40:54 UTC+0000   
    1523 bash                 2020-03-26 23:40:54 UTC+0000   insmod lime-5.4.0-4-amd64.ko "path=/dmp.mem format=lime timeout=0"

So the command is nmap -sS -sV 10.42.42.0/24. We just have to find the ESTABLISHED connection, let’s use linux_netstat.

magnussen@funcMyLife:~/premierartefact$ python /home/magnussen/tools/volatility/vol.py -f dmp.mem --profile LinuxDebianx64 linux_netstat | grep ESTABLISHED | awk '{print $4}' | sort | uniq | wc -l
Volatility Foundation Volatility Framework 2.6.1
13

So the flag is: FCSC{pool-xfconfd:nmap -sS -sV 10.42.42.0/24:13}

Nice challenge, as for the previous ones, the hardest part was to create the volatility profile.

Thanks to the FCSC team, this was an awesome CTF, I’ve learned a lot and had a lot of fun. Congratulation for the organization, see you next year!