Danish Christmas CTF 2021 by NC3/Police – Intermediary – Nisseminder

Okay - now to some fun memory forensics! This challenge in the intermediary category is called "Nisseminder" or in english "Elfs Memory". For the challenge, we are provided with a .tar.xz compressed archive-file.

NC3 Challenge: Nisseminder

Extracting the archive reveals one single file named nisseminder2021 and a quick file command just shows the file as "data". Not very useful. The file is rather large, and with the "data" type, using cat, head or similar normally doesn't give anything useful. But looking at the start of the file with hexdump reveals the ASCII characters of EMiL.

Nisseminder - hexdump

This means that we most likely are dealing with a memory-dump from a Linux-machine. Furthermore, doing a good-old strings nisseminder2021 | less on the file, gives us further believes that this is indeed a "LiME" Linux Memory Dump-file.

PCI Parity Error on Bus/Device/Function 
PCI System Error on Bus/Device/Function 
Operating System not found
Operating System not found, retrying boot now...        
Operating System not found, retrying boot in 
Windows XP Mode active
RAM slot #13
RAM slot #14
RAM slot #15
RAM slot #16
RAM slot #17
RAM slot #18
RAM slot #19
RAM slot #20
BOOT_IMAGE=/boot/vmlinuz-4.15.0-161-generic root=UUID=2f56d210-f23c-4b78-8d76-86d65bee6631 ro maybe-ubiquity

Okay, so lets treat the file as such and start deep diving info DFIR (Digital Forensics) and try figuring out what has happened in the volatile memory that could give us the flag for this challenge.

This is my first time going into memory forensics - in my day-to-day work I have worked with disk imaging, doing investigations with Autopsy and so on. But memory forensics are something rather high on the learning-dreams for me. So what an opportunity to head-dive right into it? Right?

Firstly we need some tools - I've already heard a lot about a Python-developed tool called volatility. So why not just start with that? Again, we are going to use Google where I found the guide https://seanthegeek.net/1172/how-to-install-volatility-2-and-volatility-3-on-debian-ubuntu-or-kali-linux/ for installing the tool with the dependencies and what not.
I tried to install and use volatility3 for Python 3, but was unable to get it working as there was issues with the requirement libyara. Looking at the Internet, and this seems to be an issue many others encounter. Even though I tried many suggestions, at one point I decided I had to move on as my time to allocate to the CTF was running out. So I tried installing volatility2 for Python 2.7, and that worked! At some point, when time is not as short-lived, I'm definitely going to produce a working guide - at least one that could help my self in the future..

So, the next task is to figure out what "profile" to use. For every kernel, the structure etc. for the memory - and therefore the memory dumps has changes and more. So to view the correct data from a memory dump, we need this "profile". For Linux memory dumps, we can run a strings command searching for the information used to decide what profile to use:

user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ strings nisseminder2021 | grep GNU/Linux
ext2fs_get_pathnameWelcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-161-generic x86_64)

This tells us that the memory dump is from a Ubuntu machine version 18.04.3 LTS with the kernel version 4.15.0-161-generic and with a 64-bit instruction-set. Okay. With that information we now need to find the correct profile we can use to interact with the memory dump. Again, looking at a guide from https://heisenberk.github.io/Profile-Memory-Dump/ we are guided to the GitHub https://github.com/volatilityfoundation/profiles where the Volatility Foundation has collected profiles for Linux and Mac.
In here we find a profile named Ubuntu18043.zip, so I grabbed that and copied it into the correct folder as instructed by the guide. But using that profile seems unsuccessful:

user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ vol.py -f nisseminder2021 --profile=Ubuntu18043x64 linux_banner
Volatility Foundation Volatility Framework 2.6.1
ERROR   : volatility.debug    : Invalid profile Ubuntu18043x64 selected

This most likely means, that the kernel-version is wrong. Sight. So we might be required to create our own profile, as a short search online didn't reveal any profile that we could verify the kernel for. To do this, we need the original version of Ubuntu - a version "so old" that it is not featured on their main download-site anymore. As a vived Linux-used my self, I looked into my ISO-store but unfortunately only found version 18.04.2 or 18.04.4 - not 18.04.3. Luckily enough, Ubuntu's site still have the old version up - just hidden a bit on the site https://old-releases.ubuntu.com/releases/18.04.3/. From here I created a virtual machine with standard defaults and saw that the kernel version was a bit too old - 4.15.0-55. But nothing a quick upgrade could fix with the command:

apt install linux-image-4.15.0-161-generic linux-headers-4.15.0-161-generic

A quick reboot, and the virtual machine was now on the same Ubuntu- and kernel version as the memory dump. So I then cloned the volatility-tool with git and produced the profile by running make from the volatility/tools/linux-directory. After the generation the profile needs to be packed with the System.map-file:

sudo zip Ubuntu18043-4-15-0-161-generic.zip module.dwarf /boot/System.map-4.15.0-161-generic

Now we just have to extract the profile and use it. To perform this step, I used https://transfer.sh/ which is a really nice and easy utility to use for command-line uploading via e.g. curl.

user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ vol.py -f nisseminder2021 --profile=LinuxUbuntu18043x64 linux_banner
Volatility Foundation Volatility Framework 2.6.1
Linux version 4.15.0-161-generic (buildd@lcy01-amd64-012) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #169-Ubuntu SMP Fri Oct 15 13:41:54 UTC 2021 (Ubuntu 4.15.0-161.169-generic 4.15.18)

Alright! It worked! We now have access to the memory. Running the command vol.py --info | grep linux_ will give us a full list of the plugins etc. we can use for our linux-forensics.

A quick look at linux_pslist to see if anything interesting processes was running, but nothing here. Only a ./avml nisseminder2021 - but that's a process for creating this very memory dump we are looking at. So the next thing very interesting to look into, is the command-history. For this we have the plugin linux_bash, where we really see some suspicious commands and files.

user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ vol.py -f nisseminder2021 --profile=LinuxUbuntu18043x64 linux_bash
Volatility Foundation Volatility Framework 2.6.1
Pid      Name                 Command Time                   Command
-------- -------------------- ------------------------------ -------
    1516 bash                 2021-11-03 13:12:45 UTC+0000   cmd
    1516 bash                 2021-11-03 13:12:45 UTC+0000   powershell
    1516 bash                 2021-11-03 13:12:45 UTC+0000   xxd jul.txt.enc
    1516 bash                 2021-11-03 13:12:45 UTC+0000   HA!
    1516 bash                 2021-11-03 13:12:45 UTC+0000   exit
    1516 bash                 2021-11-03 13:12:45 UTC+0000   exit
    1516 bash                 2021-11-03 13:12:45 UTC+0000   openssl enc -aes-256-cbc -nosalt -e -in jul.txt -out jul.txt.enc -K '4b404e5f4a65475f4875736b335f645f6865725f6b4f64656f72643f3f3f3f3f' -iv '2d4e4333435446326f32314a554c212d'
    1516 bash                 2021-11-03 13:12:45 UTC+0000   cd c:\windows
    1516 bash                 2021-11-03 13:12:45 UTC+0000   ls
    1516 bash                 2021-11-03 13:12:45 UTC+0000   exit
    1516 bash                 2021-11-03 13:12:45 UTC+0000   ??HH NEJ, det er jo LINUX
    1516 bash                 2021-11-03 13:12:45 UTC+0000   rm jul.txt
    1516 bash                 2021-11-03 13:12:52 UTC+0000   sudo cat /etc/shadow
    1516 bash                 2021-11-03 13:13:06 UTC+0000   cat jul.txt.enc 
    1516 bash                 2021-11-03 13:13:11 UTC+0000   xxd jul.txt.enc 
    1516 bash                 2021-11-03 13:13:23 UTC+0000   sudo ./avml nisseminder2021

So, as far as we can see, they are encrypting a file called jul.txt ("christmas.txt") and then deleting the original file. The only "problem" here, is the fact that all the information used to encrypt the file is available to us for decryption. Nice!

To decrypt the file, we need to extract it from the memory dump. Using the plugin linux_find_file -F "jul.txt.enc" could not find the file for us. So lets use linux_enumerate_files and use grep to filter the output.

user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ vol.py -f nisseminder2021 --profile=LinuxUbuntu18043x64 linux_enumerate_files | grep jul.txt.enc
Volatility Foundation Volatility Framework 2.6.1
0xffff898674f5dad0                    923322 /home/storenisse/jul.txt.enc

And like that, we now have the location of the file. With linux_find_file we can now retrieve the Inode-information for the file using the -F for finding the file and then -i with a -O to extract the file from the memory dump:

user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ vol.py -f nisseminder2021 --profile=LinuxUbuntu18043x64 linux_find_file -F "/home/storenisse/jul.txt.enc"
Volatility Foundation Volatility Framework 2.6.1
Inode Number                  Inode File Path
---------------- ------------------ ---------
          923322 0xffff898674f5dad0 /home/storenisse/jul.txt.enc
user@hostname:~/CTF/NC3/2021-12/Øvet/Nisseminder$ vol.py -f nisseminder2021 --profile=LinuxUbuntu18043x64 linux_find_file -i 0xffff898674f5dad0 -O jul.txt.enc
Volatility Foundation Volatility Framework 2.6.1

We know from the bash-command line history, that the file was encrypted with openssl enc, so let us use that to decrypt the file again:

openssl enc -aes-256-cbc -d -in jul.txt.enc -out jul.txt -K 4b404e5f4a65475f4875736b335f645f6865725f6b4f64656f72643f3f3f3f3f -iv 2d4e4333435446326f32314a554c212d

And with that - we have a flag:


1 comment

Leave a Reply

Your email address will not be published. Required fields are marked *