BSides Canberra 2017 CTF – Rekt Exfil Write-up

The BSides Canberra 2017 conference just wrapped up along with the capture the flag event and I wanted to document my solution to one of the two memory analysis challenges from the forensic category titled “Rekt Exfil”.

I was keen to try this challenge as I’m pretty interested in memory analysis. The first time I ever attempted a memory challenge was actually during the BSides Canberra 2016 CTF, so it’s been a full year since my first time.

Challenge overview

The challenge starts with the following information:

An employee has been escorted from the building due to frequent breaches of the IT Security Policy and turning up to work under the influence of alcohol. As a senior analyst in the organisation, you’ve been tasked with investigating the memory image of the employee’s virtual machine to search for evidence of data exfiltration or suspicious communications.

There was a link to the memory dump file ‘1.vmem’ which was around 512mb in size.

After downloading the memory dump, the first step was to work out what operating system the virtual machine was using. Usually you can do this using ‘imageinfo’ with Volatility, however in this instance the operating system was not identified as we don’t have a profile for it yet (more on this later).

[email protected]:~# volatility -f /root/1.vmem imageinfo
Volatility Foundation Volatility Framework 2.5
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : No suggestion (Instantiated with no profile)
                     AS Layer1 : FileAddressSpace (/root/1.vmem)
                      PAE type : No PAE

In order to manually determine what OS was in use, I ran strings over the memory dump file. I saw some GRUB strings at the top which made me think Linux, and then not long after I found references to Debian and the kernel version.

[email protected]:~# strings 1.vmem | grep "Linux version"
Linux version 3.16.0-4-686-pae ([email protected]) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.39-1 (2016-12-30)

Based on this information it looks like the virtual machine was running Debian 8 32-bit. By default Volatility does not ship with Linux profiles available, however there are a number available for download here. Unfortunately for me there was no Debian 8 x86 profile available for download here, or anywhere else on the Internet that I could find. This means that we need to create our own profile manually, this is the guide that I used to create my profile, which I’ll now discuss in detail.

Creating a profile

As per the linked guide, to create a profile we need to run the same Linux distribution with the same kernel version and the same architecture. After a quick Google search for Debian with the kernel version of 3.16.0-4 I found that this was Debian Jessie. I download the ISO for Debian Jessie 32-bit and installed it as a virtual machine.

Once the virtual machine was ready to use, I began by installing the packages outlined in the profile creation guide. Note that these are installed within the new VM as we are preparing it to create a profile from it to use with Volatility, which for me is being done in a separate Kali VM.

apt-get install dwarfdump build-essential linux-headers-$(uname -r)
cd /usr/share/volatility/tools/linux

If you’re lucky this should all go fine, however I received the following error:

dwarfdump ERROR:  dwarf_attrlist:  DW_DLE_UNKNOWN_FORM (242) Possibly corrupt DWARF data (242)

Despite the error the module.dwarf file was still created, so I tried making my profile with this however it didn’t work, I needed to fix dwarfdump and try again. I couldn’t find much information about this error, in the end I decided to try and compile dwarfdump from source to see if that would work better than the packaged version that I had installed. These are the steps that I took to complete this.

git clone
apt-get install libelf1 libelf-dev
cd libdwarf/
make dd
cp dwarfdump/dwarfdump /usr/local/bin/
cp dwarfdump/dwarfdump.conf /usr/local/lib/
cp libdwarf/libdwarf.a /usr/local/lib
/usr/local/bin/dwarfdump -di ./module.o > module.dwarf

Note: I also installed the libelf1 and libelf-dev packages, as without them I got the following error when running make.

dwarf_elf_access.c:53:2: error: #error Without libelf.h dwarf_elf_access.c cannot compile, so giving up.

Additionally if we run dwarfdump as before again it succeeded without error:

[email protected]:/usr/share/volatility/tools/linux# make
make -C //lib/modules/3.16.0-4-686-pae/build CONFIG_DEBUG_INFO=y M="/usr/share/volatility/tools/linux" modules
make[1]: Entering directory '/usr/src/linux-headers-3.16.0-4-686-pae'
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-4-686-pae'
  Building modules, stage 2.
  MODPOST 1 modules
make[1]: Leaving directory '/usr/src/linux-headers-3.16.0-4-686-pae'
dwarfdump -di module.ko > module.dwarf
make -C //lib/modules/3.16.0-4-686-pae/build M="/usr/share/volatility/tools/linux" clean
make[1]: Entering directory '/usr/src/linux-headers-3.16.0-4-686-pae'
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-4-686-pae'
  CLEAN   /usr/share/volatility/tools/linux/.tmp_versions
  CLEAN   /usr/share/volatility/tools/linux/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-3.16.0-4-686-pae'

At this point my module.dwarf file is looking a lot better than before, so I package it up into a .zip file along with /boot/ as outlined in the Linux profile creation guide.

[email protected]:zip /root/ /usr/share/volatility/tools/linux/module.dwarf /boot/
  adding: usr/share/volatility/tools/linux/module.dwarf (deflated 91%)
  adding: boot/ (deflated 75%)

Now I simply copy the profile over to my Kali system using scp.

[email protected]:scp scp [email protected]:[email protected]x

In this example I directly copy the profile into /usr/lib/python2.7/dist-packages/volatility/plugins/overlays/linux which is where my installation of Volatility checks for additional Linux profiles.

Now if I run ‘imageinfo’ again as shown before, we can see that it’s identified as Linuxdebian8x86.

[email protected]:~# volatility -f /root/1.vmem imageinfo
Volatility Foundation Volatility Framework 2.5
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : No suggestion (Instantiated with Linuxdebian8x86)
                     AS Layer1 : IA32PagedMemoryPae (Kernel AS)
                     AS Layer2 : FileAddressSpace (/root/1.vmem)
                      PAE type : PAE

Additionally the profile shows up when we run --info.

[email protected]:~# volatility --info | grep Linux
Volatility Foundation Volatility Framework 2.5
Linuxdebian8x86          - A Profile for Linux debian8 x86

I’ve also uploaded the Volatility profile for Debian 8 32-bit here if you’d like to use it.


As this point I start looking around with various Linux Volatility commands. I highly suggest referring to this Volatility Linux command reference page. As the challenge mentioned “suspicious communications” I initially started looking for network connections etc but didn’t find anything interesting. I tried almost all of these commands on the memory dump file to get a good idea of what was going on which took some time.

I found the first interesting piece of information with ‘linux_psaux’ as shown below.

[email protected]:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_psaux
Pid    Uid    Gid    Arguments
726    1000   1000   ristretto /home/rekt/email.png
736    1000   1000   bash
739    1000   1000   nano privatekey.gpg

After a quick Google search ristretto appears to be an image viewer, and we can see that the privatekey.gpg file was edited with the nano text editor. Additionally we can also see the last process listed above as the only entry in the bash history.

[email protected]:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_bash
Volatility Foundation Volatility Framework 2.5
Pid      Name                 Command Time                   Command
-------- -------------------- ------------------------------ -------
     736 bash                 2017-01-30 07:10:07 UTC+0000   nano privatekey.gpg

These files seem interesting, let’s see if we can grab a copy of them from the memory dump.

[email protected]:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_find_file -F "/home/rekt/privatekey.gpg"
Volatility Foundation Volatility Framework 2.5
Inode Number          Inode File Path
---------------- ---------- ---------
          262495 0xdca0aac0 /home/rekt/privatekey.gpg

We can see that the Inode is 0xdca0aac0, which we can use with the -i option, followed by the -O option to specify where we want to save the file.

[email protected]:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_find_file -i 0xdca0aac0 -O /root/gpg
Volatility Foundation Volatility Framework 2.5
[email protected]:~# file /root/gpg
/root/gpg: PGP\011Secret Key - 4096b created on Mon Jan 23 12:48:08 2017 - RSA (Encrypt or Sign) e=65537 Plaintext or unencrypted data

Now let’s do the same for the email.png file.

[email protected]:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_find_file -F "/home/rekt/email.png"
Volatility Foundation Volatility Framework 2.5
Inode Number          Inode File Path
---------------- ---------- ---------
          932637 0xdca0a0a0 /home/rekt/email.png
[email protected]:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_find_file -i 0xdca0a0a0 -O /root/email.png
Volatility Foundation Volatility Framework 2.5
[email protected]:~# file /root/email.png
/root/email.png: PNG image data, 1286 x 946, 8-bit/color RGBA, non-interlaced

If we open the image up we’re presented with the following PGP message:

PGP Message

Great, so at this point I assume we need to use the GPG key to decrypt the PGP message. The only problem is that we have an image of the PGP message rather than text. I tried a couple of different tools to convert this, and in the end stuck with tesseract-ocr. I first install this, then run it against the email.png file to create email.txt as shown here.

apt-get install tesseract-ocr -y
tesseract /root/email.png /root/email

The result looks like this:

[email protected]:~# cat /root/email.txt


âââââ END PGP MESSAGEâââââ

That was definitely suboptimal.. Is character recognition really still this bad? I spent the next 1-2 hours manually going through it and fixing the mistakes in about 3 separate passes (keep in mind it was now approaching 5am and using my eyes/brain was somewhat difficult). Finally I’d turned the output into this:

[email protected]:~# cat /root/email.txt


I imported the GPG file as shown below:

[email protected]:~# gpg --allow-secret-key-import --import /root/gpg
gpg: key 48BF872B125E12C7: "Rekt Son " not changed
gpg: key 48BF872B125E12C7: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:  secret keys unchanged: 1

Now for the moment of truth, can we decrypt the PGP message?

[email protected]:~# gpg -d /root/email.txt
gpg: encrypted with RSA key, ID 9C23AEBDDECD9F3A
gpg: encrypted with 4096-bit RSA key, ID 9657284599141124, created 2017-01-23
      "Rekt Son "
That thing you asked me for: I took it to the shit store in a backpack and sold it, because I had to (the shit museum was closed).



As suspected the PGP message contains the flag, rekt son indeed.


Overall the challenge was really fun, it was quite difficult for me to get the custom Debian 8 x86 profile created as I had to build dwarfdump from source for some reason. It was a little tedious fixing up the PGP message after converting the image from text, I’d be interested in finding better software for doing this if it exists as that would save a lot of time. I learned a lot from the challenge and the BSides Canberra 2017 CTF was awesome, can’t wait for 2018!

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>