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).

root@kali:~# 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.

root@kali:~# 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
make

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 https://github.com/tomhughes/libdwarf.git
apt-get install libelf1 libelf-dev
cd libdwarf/
./configure
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:

root@deb8:/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/System.map-3.16.0-4-686-pae as outlined in the Linux profile creation guide.

root@deb8:zip /root/debian8.zip /usr/share/volatility/tools/linux/module.dwarf /boot/System.map-3.16.0-4-686-pae
  adding: usr/share/volatility/tools/linux/module.dwarf (deflated 91%)
  adding: boot/System.map-3.16.0-4-686-pae (deflated 75%)

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

root@deb8:scp debian8.zip scp debian8.zip [email protected]:/usr/lib/python2.7/dist-packages/volatility/plugins/overlays/linux

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.

root@kali:~# 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.

root@kali:~# 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.

Analysis

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.

root@kali:~# 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.

root@kali:~# 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.

root@kali:~# 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.

root@kali:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_find_file -i 0xdca0aac0 -O /root/gpg
Volatility Foundation Volatility Framework 2.5
root@kali:~# 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.

root@kali:~# 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
root@kali:~# volatility -f /root/1.vmem --profile=Linuxdebian8x86 linux_find_file -i 0xdca0a0a0 -O /root/email.png
Volatility Foundation Volatility Framework 2.5
root@kali:~# 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:

root@kali:~# cat /root/email.txt
âââââ BEGIN PGP MESSAGEâââââ

hQEMASWjrr3e2ZSBAQgAIuBNWfx+I3GIUEeBhRoW/ZUNH017w94zï¬chtyawaxA
o+liIx//XFZSCUUGVaZIRGJyBiclMBrvrlsyPMFzMssz7+8a5vl3UU2rnJGuan
YIkavaRVQIhHiRXgue7Y28deUoK4xN3LthUMk144ILXCTGTJINBPchZIMquh
thQVngLuHPQTeiN/7pnCZinkPvaDQEvHon4RP/KVC8C15VSr0b05FwUJQ4Hy1
fr0+21112a5+0qxax29v6j7YAFGem1sPcp/tUhvafI3thQBPchGGNLOwPGR4a
kWEHdaFwaNf+AjCSUYVSglechj8M05+Dh5w1Tc54UCDADWVyhFmRQRJAEP/ZDD
fbllhsngRGwadUeuwHYVqQGQl+DffnJUSTxDXLNvaeUBvPTIuXSRlMT/402k7
2Rt+yoiSAwBle9qtb8ViT1K/qnFFZUNBaLvGIsGGgleKa+UTOb7XzXRJLGZoNy
d3q5ungZTeGyoUMYbprlXrntl/QOSAr47W7CPDXzfWUwIZEqQBquTFQfJe7p4
jX7/ceR15030v5e+532/gthiYOZQCprqISevaogznhraUUw882+cpCeeySzmt
nwv/Bj05vr25vaan0mAJ1K1deBaHGSsa0MRLEd/lokfw3FND39LzaEkaBoTX
8fkthqlGannGszswa1285w5EdKij3f1H/dPF74dmtVT/G+de+34D3leNh
aAX24hySUY95Lf7ptSGyIchvnCIOaZogKvDCw57V90+7KIBGhIsolE+1pqrfADy
ByngthLKZMyNiTVdvWUJlMsdGIZjFLMtMWIGbQLSGZG4ssSD20j5X0qB+3a290h
aoSMLblGLIPGZ5XWBBpGe4LGchhBUZPGGaj0/f0ung22Hygix9RIaR90p75129
RD+1DQRYDBp3DnhM35dkasAFKwdRBUCGSQdVDnLku1+iij32an+8tvbevbzs
t/pd0D47hijwywOfiuAUchuGustZT57jfSBMSGsALAcunZVkurZPJprBmByk
+EeGXa11mepZthY5TIk2Wp/uZGnJIdHKPgFSGdCcZLquXkSJZAy/r7lev823
T5hezYoWwY35ARWNUGkiw5dkAo+prU1PLrKBPGQQZzVumykaAeYongszYkKU
ZWteNBT+PUth1+P10EA749334WG4bfkmwlRquhnTaTXhdebew?Ca+Mn8u+z
uGAdLne/vaquCFQgVAHPNxz47chTEiArPTCRVLmCAHSNXBGIG+rgoG4Q=
=Y322

âââââ 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:

root@kali:~# cat /root/email.txt
-----BEGIN PGP MESSAGE-----

hQEMA5wjrr3ezZ86AQgAluBNWfx+I30IuEeBhRoW/ZUNHOi7w94z0WwctyawVxxA
o+liIx//Xrz5cuU0Va2/R0Jy6ic1M3rvrlsyPMFzMszSw7+8a6v/3UU2rnJ0unjX
YIkavaRVQIhHiRXgue7YZ8xDdUoK4xN3LtKdUMkl44ILXc707JlN6PcfUZ1MRqmh
VhgQVdgXLuHP97eiN/7pnCZinkPOxvD9EvHon4RP/KVC8Cl5vSrObO5FwUJQ4Hy1
frQ+ZII12a5+Oqxaxz9vGj7YAFGemlsPcp/tUhUvyfI3btNQBPTccGGNLOwP0R4a
kWEHdaFwWxNf+AjC8UYVSg1GPcgj8M06+Dh5WlTc64UCDAOWVyhFmRQRJAEP/2OO
fbllhsgl2RGGxwdUeuwHYVq9GQ1+DffnJUSTxOXLNYbveU6vPTIuX8R/MT/4OZk7
2Rt+yoiSAwB1Fw9qtb8ViTlK/qnFFZUN6aLv0IsGGg1VpKa+UTOb7XzXRJLG2oNy
d3q5uzIgZTeGyoUMYbfpB1Xrnt1/QOsAr47W7CPDXzfWUwIZEqQByq7TF9fJe7p4
jX7/ceR1S03Ov5e+532/gdh5iYo29CypYqI8ebCvo9znhraUUw882+cpCeeySzmt
nwv/Bjo6vr26wvNaIqOmAJ1K1dRdBaH08saOMRLEd//okfw3FND39LzaEfkDBoTX
8fkzh8q1GaqCn09zpswp3128Sw6EdKHvj3f1H/dPF74dmtVT/0+pdK+34D31KwNh
aAX24hySUYg5Lf7ptS0yILcqvnC/OaZogKvDCwS7V90+7KlBGhIso1E+lpqrfAOy
BynghvKLKZMyNiTVdvWUJ1MsdGI2jFLMtMWlGb9L5GZ04ss8D2Qj5XOqB+3az90h
aoSMLblGLIPG25XWB6pGe4L0cMdhBUZPGGajo/fQugxA2ZHygix9RIaR9Op7512g
RD+lDQRYOBp3DnhM36dFkmsAFKwdR6UC0SQdVDnLkul+ixLj3znbH+8tvbfQvbzs
t/pdOD47hyJjwywOfiuAUpXcu0ubDsZT57jf56M50sALAcun2VkurZPJGpb6m6yk
+Ee0Xal1xCmpZUvtY5TIkzWp/uZGnJIdHKPgr80dCcZLq2jXkSJZAy/r7wJ1v8zB
T5hezYoWwY3SARWNU0kiw5dkAo+fNpU1PLrK3P0Q9zzVumyvVkAeYIoxgZxsYkKU
ZWeIjNBT+PUqNh1+P1OEA749J34W04bfkmw1Ruz3hnTaTXhfKdb9xw7Ca+Mn8u+z
uGAdLne/PvbqRbCFQgVAHPNxz47mcBTEiArP7cRVLmCAH5Nx3d1G+rgoG4Q=
=Y3Zz
-----END PGP MESSAGE-----

I imported the GPG file as shown below:

root@kali:~# 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?

root@kali:~# 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).

Morty

BSIDES_CTF{G37_Y0uR_5h1T_70g3tH3r}

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

Summary

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!

  1. I am also having a similar issue. Can you clarify this step?

    ‘cp libdwarf/libdwarf.a /usr/local/lib
    /usr/local/bin/dwarfdump -di ./module.o > module.dwarf’

    Is this two seperate commands? I have done the first one, however unsure on what to do with second command.

    Thanks

  2. /usr/local/bin/dwarfdump -di ./module.o > module.dwarf’
    when i enter this line it keep telling me error can not locate module.o
    can you help me on this ??

    • Were there any issues during the make? I’m guessing the module.o file is not being created due to some other failure.

      • well this is make result:

        /usr/share/volatility/tools/linux# make
        make -C //lib/modules/4.4.0-72-lowlatency/build CONFIG_DEBUG_INFO=y M=”/usr/share/volatility/tools/linux” modules
        make[1]: Entering directory ‘/usr/src/linux-headers-4.4.0-72-lowlatency’
        CC [M] /usr/share/volatility/tools/linux/module.o
        Building modules, stage 2.
        MODPOST 1 modules
        CC /usr/share/volatility/tools/linux/module.mod.o
        LD [M] /usr/share/volatility/tools/linux/module.ko
        make[1]: Leaving directory ‘/usr/src/linux-headers-4.4.0-72-lowlatency’
        dwarfdump -di module.ko > module.dwarf
        make -C //lib/modules/4.4.0-72-lowlatency/build M=”/usr/share/volatility/tools/linux” clean
        make[1]: Entering directory ‘/usr/src/linux-headers-4.4.0-72-lowlatency’
        CLEAN /usr/share/volatility/tools/linux/.tmp_versions
        CLEAN /usr/share/volatility/tools/linux/Module.symvers
        make[1]: Leaving directory ‘/usr/src/linux-headers-4.4.0-72-lowlatency’

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>