Brandon T. Elliott

home

CTF Writeup: Space Heroes CTF - "Conspiracy Nut"

space-heroes-ctf

The CTF

Space Heroes CTF took place from April 21, 2023 to April 23, 2023 and was built by FITSEC @ Florida Tech.

The Challenge

This forensics challenge began with the following description and a file conspiracy_nut.tar.gz to download and analyze:

conspiracy-nut

Something about the description of this challenge captivated me and it was definitely the most difficult challenge that I managed to solve during Space Heroes CTF.

It forced me to learn quite a bit about doing forensics on memory dumps, so with that being said, this writeup will partially go over the rabbit holes I went down (the worthwhile ones at least), as well as how I solved the challenge during the CTF, and an additional way I found to solve the challenge after the fact.

The Memory Dump

After extracting the contents of conspiracy_nut.tar.gz we are left with a single file conspiracy_nut.dump which is the memory dump we will analyze.

Admittedly, before I ended up approaching the challenge in a more sensible way, I initially ran binwalk on it with limited success, attempted to extract strings from it with strings, and even attempted to extract things like .png .jpg .bmp .gif .pdf .txt, etc. files from it manually using custom python scripts. Although I did garner a little bit of info from all of this, ultimately I wasted several hours only to realize that I needed to find the right tool for the job if I were going to have any amount of success with solving the challenge.

A little google-fu and struggling to install python dependencies later, and volatility ended up being exactly the tool I needed.

Volatility

Specifically, I ended up using volatility3 which is an amazing tool for analyzing memory dumps.

While I wasn’t successful overall with my prior approaches to the challenge, I did however manage to see that there was a flag.jpg file that was potentially downloaded during my analysis with strings.

Therefore, a good starting point will be to find .jpg files in the memory dump with something like the following:

vol -f conspiracy_nut.dump windows.filescan.FileScan | grep 'jpg'

After running this, we see that some Sample Pictures are included in the results, so with those removed:

┌──(kali㉿kali)-[~/conspiracy_nut]
└─$ vol -f conspiracy_nut.dump windows.filescan.FileScan | grep 'jpg' | grep -v 'Sample'

0x17eeb9ae0     \Users\tinfoil\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg
0x17eec5670     \Users\tinfoil\Desktop\IMG_2930.jpgpg 
0x17f0d42b0     \Users\tinfoil\Downloads\Patterson–Gimlin_film_frame_352.jpg  
0x17fb704b0     \Users\tinfoil\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg
0x17fc26ad0     \Users\tinfoil\Downloads\20230213_212116.jpg  
0x17fd59070     \Users\tinfoil\AppData\Local\Mozilla\Firefox\Profiles\iosz5xuz.default-release\settings\main\quicksuggest\icon-160380814674521.jpg

This leaves us with some initial things to look at, although unfortunately we don’t see the aforementioned flag.jpg.

We can extract specific files with a command similar to the following, specifying the address of the file from the left column:

vol -f conspiracy_nut.dump windows.dumpfiles.DumpFiles --physaddr 0x17fc26ad0

This, for example, would extract the photo \Users\tinfoil\Downloads\20230213_212116.jpg (which by the way, ended up being this picture of two cats):

cats

Interestingly, I used this same technique on \Users\tinfoil\Desktop\IMG_2930.jpgpg and \Users\tinfoil\Downloads\Patterson–Gimlin_film_frame_352.jpg as well but the data extracted didn’t appear to be valid images, but instead contained what looked like zone transfer information from the same IP I saw in my earlier analysis which flag.jpg was downloaded from? Kind of strange…

Downloads

Using the same filescan technique as before, I turned my focus to discovering what else was in the tinfoil user’s Downloads folder:

┌──(kali㉿kali)-[~/conspiracy_nut]
└─$ vol -f conspiracy_nut.dump windows.filescan.FileScan | grep 'tinfoil' | grep 'Downloads'

0x17ece7cb0     \Users\tinfoil\Links\Downloads.lnk
0x17ef2a4d0     \Users\tinfoil\Downloads\220517-ufo-mjf-0953-5ad8c4.webp  
0x17ef49d40     \Users\tinfoil\Downloads  
0x17f0d42b0     \Users\tinfoil\Downloads\Patterson–Gimlin_film_frame_352.jpg  
0x17f6596c0     \Users\tinfoil\Downloads\Firefox Installer.exe
0x17fada070     \Users\tinfoil\Downloads\virtio-win-guest-tools.exe   
0x17fb17f20     \Users\tinfoil\Downloads  
0x17fc26ad0     \Users\tinfoil\Downloads\20230213_212116.jpg  
0x17fdc1840     \Users\tinfoil\Downloads\desktop.ini  

The 220517-ufo-mjf-0953-5ad8c4.webp file ultimately ended up being similar to the zone transfer thing as described before.

The other file which piqued my interest here was the Firefox Installer.exe.

Clearly this meant that Firefox was used to download these images…

Firefox

A little bit of google-fu informed me that a user’s Firefox browsing history is stored in a places.sqlite database.

Therefore, we will find this file and extract it from the memory dump:

┌──(kali㉿kali)-[~/conspiracy_nut]
└─$ vol -f conspiracy_nut.dump windows.filescan.FileScan | grep 'places.sqlite'

0x17f01f650     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite-wal
0x17f2c7ca0     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite-wal
0x17fc5ac10     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite-wal
0x17fc91d00     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite
0x17fc95120     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite-wal
0x17fc97a20     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite-shm
0x17fc98dc0     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite
0x17fd23c00     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite
0x17fdaaea0     \Users\tinfoil\AppData\Roaming\Mozilla\Firefox\Profiles\iosz5xuz.default-release\places.sqlite

After extracting the places.sqlite file located at address 0x17fc91d00, we can now open up the database using sqlitebrowser which should allow us to look at the browsing history of the tinfoil user.

After browsing to the moz_places table, we see the following (with the IP of the server the files were downloaded from having been redacted by me):

browsing-history

It appears that the user browsed to some cat related xkcd comics, which was somewhat interesting given the cats picture discovered earlier, but ultimately this didn’t end up being of any use to me.

It also appears that the flag.jpg image was visited, and my next thought after seeing this was that maybe the image was cached. This thought led me down a rabbit hole of extracting everything from the user’s Firefox cache, which to summarize succinctly: although it did contain some cached images and other bits of data, there wasn’t anything that ultimately seemed relevant to the challenge. Therefore, I will spare the remaining details of this Firefox “rabbit hole” for now…

Wallpaper

You may have noticed in my earlier assessment of the .jpg files located in the memory dump, that there was one in particular that I didn’t extract or look at initially, and that was TranscodedWallpaper.jpg.

However, after going down the previous rabbit holes and getting stuck, I did end up wrapping back and taking a look at it, thinking (hoping) that maybe the flag.jpg was set as the user’s wallpaper at some point.

After extracting the file with volatility, I ended up with a mostly corrupted image which looked like this:

corrupted-flag

Luckily, the “Potentially Flat?” part I could see written on the top of the whiteboard strongly made me suspect that this image contained the flag, however it appeared like I would need to fix the corruption in the image data in order to obtain it.

JPEG Corruption

Disclaimer: I am NOT an expert on fixing corrupted images, please don't use this info to try to recover your own images. You do so at your own risk.

Doing some research on JPEG corruption, I learned that if an image is cut off and the rest is filled in with grey, it’s likely that this image data is recoverable.

This can be caused by something as simple as the bytes ff d9 being placed in the image data prematurely, as these bytes ultimately signal that it’s the end of the image data.

Opening TranscodedWallpaper.jpg up with a hex editor, we see that this is indeed the case with this extracted file.

At address 0x00025A15 we see a premature ff d9 that is followed by 4,073 null bytes:

ffd9

After deleting all of the aforementioned bytes and exporting the new file, we now have a slightly improved, but still corrupted, image:

slightly-less-corrupted-flag

At this point, I could see enough to know that the flag is indeed written on the whiteboard in the bottom left of the image, however it was not nearly clear enough to be able to capture it.

Although I did make several attempts to fix the corruption in a way that would properly recover the entire image, being pressed for time, and admittedly not being knowledgeable enough in this area (see previous disclaimer), I then turned to deleting chunks of bytes in areas of the hex where I thought the corruption may exist.

Knowing that the flag was contained in a relatively small portion of the image, I knew that I could delete a substantial part of the image data and still recover the flag.

For example, deleting the bytes from 0x00010000 to 0x000764FF resulted in this image (with an additional edit afterwards in order to redact the flag):

flag

It is worth mentioning that from conversation that took place after the CTF was finished, one person did mention this exact methodology of extracting the TranscodedWallpaper.jpg as being their solution, however they didn’t mention any issue about the image being corrupted, so I’m not quite sure why it was for me, but it did seem like I was using a different version of volatility, so I’m going to look into that further, but for now, I don’t have a reasonable explanation.

Update - 4/26/2023: I went back and tested it with the original version of volatility instead of volatility3 and the original version was able to extract TranscodedWallpaper.jpg much better, so if I hadn’t have tried to use the latest and greatest, I could have avoided the fixing the corruption part altogether.

It also became apparent to me after the fact that there were multiple ways you could have obtained the flag, and thus, I needed to backtrack to the Firefox “rabbit hole” in order to further my learning.

A Short Intermission

What makes some CTF challenges (and other challenges for that matter) cause you to question your ability and entire existence as a human being is that your line of thinking can sometimes be 100% correct, but you just miss the thing. This can lead to frustration, but also this is the part where you have an opportunity to learn, which is an amazing thing, and the most enjoyable part for me, personally.

Firefox - continued…

With that being said, my line of thinking with Firefox was correct, but the thing that I missed was that the image may be contained somewhere in the memory dump of (one of) the running Firefox processes.

So, the first step for another way to solve the challenge would be to first list all of the running Firefox processes in the memory dump like so:

┌──(kali㉿kali)-[~/conspiracy_nut]
└─$ vol -f conspiracy_nut.dump windows.pslist.PsList | grep 'firefox'

1936	1928	firefox.exe     0xfa800574d060
2404    1936    firefox.exe     0xfa8004a29b30
1344    1936    firefox.exe     0xfa800514da30
2772    1936    firefox.exe     0xfa8004c30060
1608    1936    firefox.exe     0xfa8004ca9310
800     1936    firefox.exe     0xfa8004d4f060
2532    1936    firefox.exe     0xfa8004ddb060
880     1936    firefox.exe     0xfa8004def920
2332    1936    firefox.exe     0xfa8004d495f0
1964    1936    firefox.exe     0xfa8004d14060
3128    1936    firefox.exe     0xfa8004cd9b30
3240    1936    firefox.exe     0xfa8004ce4ab0

This gives us a total of 12 different Firefox processes that we can dump with volatility’s memmap plugin using the PID from the left column. Since there are 12 of them and doing it one by one may be quite annoying, I will go ahead and create a bash script to do the remaining portion of the analysis, as this will likely come in handy in the future as well.

bash-script

The bash script I created above will automate the redundant actions of grabbing all 12 of the PIDs of the Firefox processes, dumping all of the memory from these PIDs, and subsequently using foremost to extract the file types we want from them (in this case, we know we want .jpg).

After running the script, we are left with a directory of all of the extracted .jpg files from all of the Firefox processes:

extracted

This ended up containing all of the images that I previously found in the Firefox cache, and even several more, as well as the flag.jpg image, which ended up being a quite humorous parody of a “conspiracy nut”, with the flag being written on a flag on the moon:

flag