NDH 2018 - Infected
Event | Challenge | Category | Points | Solves |
---|---|---|---|---|
Nuit du hack 16 | Infected | Forensic | 550 | 3 (first blood \o/) |
Description
This forensic task was submitted at Nuit du hack 2018 in Paris. This challenge took me around 5 hours! In this write-up, we will deal with Linux memory dump, Windows 10 memory dump, Windows mechanics and a bit of steganography.
TL;DR
At the beginning of this task, I started with the file infected.exe
(~600 Mo). A quick analysis later, it occurred to me the infected.exe
file was a PNG file instead of PE.
With binwalk
I’ve been able to carve 2 BMP pictures and 1 encrypted archive (Zip). The password is hidden in the second BMP file, with LSB method (extracted with stegsolve
).
After decrypting the archive, I got 1 other encrypted archive and a Linux memory dump. To use volatility
on this dump I had to create a new profile:
OS: Ubuntu 14.04.1
Kernel: 3.13.0-66-generic
The password to decrypt the second archive is in the bash history.
In the second encrypted archive, there is a Windows 10 memory dump. Windows can use 8-bits encoded data, but it uses 16-bits encoded data too.
Then, I did a strings -e l
on the memory dump and I found a SHA1 hash to crack, and flag :-)
State of the art
Well, I started this challenge at midnight approximately (the time is important).
The first step, determine if the infected.exe
file is really a PE file.
$ file infected.exe
infected.exe: PNG image data, 244 x 337, 8-bit/color RGBA, non-interlaced
$ ll infected.exe
-rw-r--r-- 1 maki users 599M 2 juil. 14:40 infected.exe
Well, a picture of 599 Mo… Let’s extract some data ;-)
$ binwalk -e infected.png
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 PNG image, 244 x 337, 8-bit/color RGBA, non-interlaced
12488 0x30C8 Zip archive data, at least v1.0 to extract, compressed size: 627739148, uncompressed size: 627739148, name: step1.zip
627751653 0x256ABAE5 End of Zip archive
628094451 0x256FF5F3 End of Zip archive
$ ll _infected_binwalk
-rw-r--r-- 1 maki users 599M 4 juin 15:59 step1.zip
-rw-r--r-- 1 maki users 1,2M 4 juin 14:45 билэ.bmp
-rw-r--r-- 1 maki users 901K 4 juin 15:51 ключ.bmp
The step1.zip
is encrypted and contains 2 files:
$ zipinfo step1.zip
Archive: step1.zip
Zip file size: 627739148 bytes, number of entries: 2
-rw-a-- 6.3 fat 557933864 Bx lzma 18-Jun-04 09:50 1.elf
-rw-a-- 6.3 fat 499247924 Bx stor 18-Jun-04 14:24 2.zip
2 files, 1057181788 bytes uncompressed, 627738858 bytes compressed: 40.6%
Step1 - Stegano
The password of the step1.zip
is hidden in the ключ.bmp (renamed in img2.png).
I used StegSolve
to exract the password:
Fig 1 - Zip password in LSB
After many tries and revert the picture, I finally found the password:
I13eYu&!yd2lC@lne
$ 7za x step1.zip
[...]
Enter password (will not be echoed): I13eYu&!yd2lC@lne
$ ll step1
-rw-r--r-- 1 maki users 533M 4 juin 09:50 1.elf
-rw-r--r-- 1 maki users 477M 4 juin 14:24 2.zip
Right, at this time we are probably at 1 AM.
Step2 - Linux memory dump
Let’s start with real forensic stuff.
Determine OS and Kernel version
First, the 1.elf
is a Linux memory dump:
$ strings 1.elf | grep "Linux version" | sort | uniq
[ 0.000000] Linux version 3.13.0-66-generic (buildd@lgw01-26) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #108-Ubuntu SMP Wed Oct 7 15:20:27 UTC 2015 (Ubuntu 3.13.0-66.108-generic 3.13.11-ckt27)
Jun 4 09:44:32 caine kernel: [ 0.000000] Linux version 3.13.0-66-generic (buildd@lgw01-26) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #108-Ubuntu SMP Wed Oct 7 15:20:27 UTC 2015 (Ubuntu 3.13.0-66.108-generic 3.13.11-ckt27)
Linux version 3.13.0-66-generic (buildd@lgw01-26) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #108-Ubuntu SMP Wed Oct 7 15:20:27 UTC 2015 (Ubuntu 3.13.0-66.108-generic 3.13.11-ckt27)
$ strings 1.elf | grep "Ubuntu 14.0" | sort | uniq
# deb cdrom:[Ubuntu 14.04.1 LTS _Trusty Tahr_ - Release amd64 (20140722.2)]/ trusty main restricted
Description: Ubuntu 14.04 Wallpapers
elcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-66-generic x86_64)
"Ubuntu 14.04.3 LTS"
Ubuntu 14.04.3 LTS
Wallpapers from the Ubuntu 14.04 community contest
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-66-generic x86_64)
Kernel: 3.13.0-66-generic
OS: Ubuntu 14.04.3
We know one thing: we have to do a new volatility profile. It’s not the regular kernel version for Ubuntu 14.04.
#### Profile creation
First of all, download the right Ubuntu version: http://old-releases.ubuntu.com/releases/14.04.1/ubuntu-14.04.1-desktop-amd64.iso
And install it in your favorite hypervisor. When the install is done, just install the new Linux Kernel:
```bash
$ sudo apt-get update && sudo apt-get install linux-image-3.13.0-66-generic linux-headers-3.13.0-66-generic volatility-tools
Well, the new kernel is installed, we have to reboot the machine. Now, let’s create the good profile.
$ uname -a
Linux ubuntu 3.13.0-66-generic #108-Ubuntu SMP Wed Oct 7 15:20:27 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ cd /usr/src/volatility-tools
$ chmod -R 777 linux/ # I know, it's bad
$ cd linux && make
$ ll
-rwxrwxrwx 1 root root 378 Mar 25 2013 Makefile*
-rwxrwxrwx 1 root root 13831 Mar 30 2013 module.c*
-rw-rw-r-- 1 toto toto 1732757 Jul 2 06:17 module.dwarf
drwxrwxrwx 2 root root 4096 Jun 30 16:15 pmem/
$ zip ndh_infected.zip /usr/src/volatility-tools/linux/module.dwarf /boot/System.map-3.13.0-66-generic
Now, just place this new volatility profile in the right place (on the machine containing the memdump obviously).
$ sudo cp ~/Documents/CTF/ndh16/infected/ndh_infected.zip /usr/lib/python2.7/site-packages/volatility/plugins/overlays/linux
$ volatility --info | grep infected
Volatility Foundation Volatility Framework 2.6
Linuxndh_infectedx64 - A Profile for Linux ndh_infected
$ volatility -f 1.elf --profile=Linuxndh_infectedx64 linux_banner
Volatility Foundation Volatility Framework 2.6
Linux version 3.13.0-66-generic (buildd@lgw01-26) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #108-Ubuntu SMP Wed Oct 7 15:20:27 UTC 2015 (Ubuntu 3.13.0-66.108-generic 3.13.11-ckt27)
Great, our volatility profile seems to work. But we have to stay focus on our goal: Find the password of the encrypted archive.
You can download my volatility profile here: ndh_infected.zip
Find the password
Let’s check the bash history:
$ volatility -f 1.elf --profile=Linuxndh_infectedx64 linux_bash
Volatility Foundation Volatility Framework 2.6
Pid Name Command Time Command
-------- -------------------- ------------------------------ -------
5986 bash 2018-06-04 07:46:54 UTC+0000 loadkeys fr
5986 bash 2018-06-04 07:47:01 UTC+0000 sudo loadkeys fr
5986 bash 2018-06-04 07:47:09 UTC+0000 cls
5986 bash 2018-06-04 07:47:16 UTC+0000 clear
5986 bash 2018-06-04 07:47:27 UTC+0000 loadkeys
5986 bash 2018-06-04 07:47:33 UTC+0000 loadkeys fr
5986 bash 2018-06-04 07:47:38 UTC+0000 sudo loadkeys fr
5986 bash 2018-06-04 07:47:47 UTC+0000 sudo bash
5986 bash 2018-06-04 07:48:28 UTC+0000 setxkbmap fr
5986 bash 2018-06-04 07:48:34 UTC+0000 cls
5986 bash 2018-06-04 07:48:37 UTC+0000 clear
5986 bash 2018-06-04 07:48:43 UTC+0000 reset
5986 bash 2018-06-04 07:49:14 UTC+0000 echo "ObP&CWfh2K18"
w00t! I found the second password:
ObP&CWfh2K18
It looks easy, but during the challenge I didn’t wait long enough, I just stopped the command because it was too long… And after that, I lost 1 big hour…
Well, no problem, we keep going.
Step3 - Windows stuff
No more encrypted zip archive, the final part! We’re close!
Let’s play with volatility…
Which OS?
$ strings 2.elf | grep 'Linux version'
# No output...
$ volatility -f 2.elf imageinfo
Volatility Foundation Volatility Framework 2.6
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win10x64_10586, Win10x64_14393, Win10x64, Win2016x64_14393
AS Layer1 : Win10AMD64PagedMemory (Kernel AS)
AS Layer2 : VirtualBoxCoreDumpElf64 (Unnamed AS)
AS Layer3 : FileAddressSpace (/home/maki/Documents/CTF/ndh16/infected/temp/_infected.png.extracted/step1/step2/2.elf)
PAE type : No PAE
DTB : 0x1aa000L
KUSER_SHARED_DATA : 0xfffff78000000000L
Image date and time : 2048-12-31 20:59:32 UTC+0000
Image local date and time : 2048-12-31 23:59:32 +0300
Windows 10, nice. Well, we have a memory dump from a sandbox, then there is some malware on the desktop:
- NJRAT_REMAKE.EXE
- DEFENDERCONTROL\DefenderControl\DefenderControl.exe
- NJRAT_0_7D.EXE
- XENOS64.EXE
- WINMM_NET.DLL
- CLASSLIBRARY1.DLL
- …
My first hypothesis was: reverse the NJRAT_REMAKE.EXE
and try to find the flag. After a while, I started to analyze XENOS64.EXE
and DDLs but nothing too…
It’s around 5 AM now, and we’re tired and a bit angry.
…But don’t need it.
After chatting with @Big5, he released 1 hint per step. For the last step the hint was something like:
Volatility is so high level… lol
And I understood that I have to deal with strings
and grep
. But, Windows uses 16-bits encoded data, and by default strings
is looking for 8-bits encoded data.
So let’s try something:
$ strings -a -e l 2.elf > memdump_strings_16bits
$ cat memdump_strings_16bits | grep "ndh"
ndh_crackedhash
[...]
Hmmm.. I tried to validate the task with that, obviously, it didn’t work.
Step 4 - Crack the hash
Well, after strings .. grep
, let’s go for less
:
$ less memdump_strings_16bits
[...]
ndh_crackedhash
FileVersion
InternalName
CALC
LegalCopyright
64ce3703bc4937a1b9edc6f15bfa1e9357807ce4
[...]
64ce3703bc4937a1b9edc6f15bfa1e9357807ce4
Go to hashkiller to break the SHA1, the clear text is:
NO2603
Flag
Finally the flag:
ndh_NO2603
And now it’s around 5h30AM! I spent a lot of time on this task (5 hours maybe more), but it was worth, we earned 650 points with the “First blood”.
@makhno and @shutdown spent a lot of time on this task too, they validate it with their team few minutes after, GG to all of us! :)
Feel free to contact me on twitter @AlanMarrec1 if you have any question or anything else.
Thanks for reading.