CTF 2006 Prequal Walkthrough: Forensics
This category was lots of fun. It required a good deal of attention to detail, creative thinking, and a wide knowledge base. Above all else, we recommend getting enough sleep so you don't miss something obvious really early and blow 4 hours banging your head against an easy problem. But we're not bitter. :)
100: Base64 is your friend
The tarball contained a set of files, all with trashed filenames, but with image extensions (jpg, gif, png, tiff). Looking at file characteristics, they all had the same modification time except one, which also had a "._" prefix. (This kind of file is what OSX uses to store resource fork information.)
total 12764
-rw-r--r--  1 drb drb   24699 2006-06-09 13:34 zVfjQDpW.png
-rw-r--r--  1 drb drb  681997 2006-06-09 13:34 zlsZ6Xb6.jpg
...
-rw-r--r--  1 drb drb    7559 2006-06-09 13:34 2PPLguSy.gif
-rw-r--r--  1 drb drb   60730 2006-06-09 13:56 V1ojSXNb.jpg
-r--------  1 drb drb   58103 2006-06-09 13:56 ._V1ojSXNb.jpg
Using "file" on all the files seemed to match the filename extensions, so we moved on to "strings" our suspect "V1ojSXNb.jpg" file, which showed a mess of XML. Picking through the XML, there was one set of tags that seemed to stand out from the rest, unrelated to printing or colors:
  <photoshop:Instructions>a2Vuc2hvdG8ga2V5OiByaHViYXJi<photoshop:Instructions>
The string "a2Vuc2hvdG8ga2V5OiByaHViYXJi" is entirely alphanumeric, so shoving it through a base64 decoder seems like a good idea if you've gotten enough sleep. (If it had been mis-aligned, the string would have ended in "=" characters, and that would have been a dead give-away that it was base64 encoded.) The decoded string was:
kenshoto key: rhubarb
The encoded string is actually repeated in an earlier part of the file too, just to further draw your attention to it.
200: Frequency analysis
This tarball held a single WAV file. There is nothing funnier in the world than a cappella telephony, and we recommend listening to this WAV any time you're feeling tense about the other challenges.
The goal here was to recover the phone number dialed, and then figure out if we could get a BBS name from the number. After playing around briefly and unsuccessfully with a few DTMF decoding tools that had trouble dealing with the background noise, we resorted to using Audacity to directly examine the frequency bands for each touch-tone ("Analyze/Plot Spectrum..."). Finding both frequency spikes in each tone (Dual Tone Multi-Frequency, remember?) we made a list of tones, and then referenced them against the DTMF chart to get the numbers dialed:
        lo     hi   digit
Tone 1  920 / 1197    *
Tone 2  860 / 1225    7
Tone 3  948 / 1334    0
Tone 4  860 / 1224    7
Tone 5  710 / 1225    1
Tone 6  710 / 1486    3
Tone 7  786 / 1225    4
Tone 8  786 / 1486    6
Tone 9  860 / 1225    7
Tone 10 860 / 1225    7
Tone 11 710 / 1225    1
Tone 12 710 / 1225    1
Tone 13 710 / 1485    3
Initially the first tone was hard to make out, so we just skipped it, figuring only the final 10 digits mattered (and that the prior digits were for international dialing), we Googled 713-467-7113, and it gave us a link at textfiles.com which showed this number to have belonged to Hacker's Haven. More careful tone analysis shows the first three to be "*70", to disable call waiting.
300: FAT undelete
This tarball contained a FAT filesystem disk image. The easiest way to hide information in a FAT filesystem is to just delete a file; this will leave the contents, but drop the name from the directory listing. Looking at the start of the image in a hex editor, we saw that several filenames had, in fact, been deleted (FAT replaces the first character with a "deleted" marker):
00000600  e5 54 45 47 4b 45 59 20  4a 50 47 20 00 00 00 00  |åTEGKEY JPG ....|
00000610  00 00 00 00 00 00 b8 aa  8d 34 03 00 79 96 00 00  |......¸ª.4..y...|
00000620  57 45 4c 43 4f 4d 45 20  54 58 54 20 00 00 00 00  |WELCOME TXT ....|
00000630  00 00 00 00 00 00 bb aa  8d 34 16 00 0e 06 00 00  |......Ȼ.4......|
00000640  e5 43 4f 52 49 4e 47 20  50 59 20 20 00 00 00 00  |åCORING PY  ....|
00000650  00 00 00 00 00 00 11 ab  8d 34 17 00 57 00 00 00  |.......«.4..W...|
After restoring the filenames, we mounted the image and ran "file" on our collection, discovering that the .py file is not Python at all:
scoring.py:  gzip compressed data, was "payload", from Unix
stegkey.jpg: ERROR: cannot read `stegkey.jpg' (Input/output error)
welcome.txt: ASCII English text
After gunzip'ing scoring.py, we found the key:
$ gunzip -c scoring.py 
the key for this level is:
"Forensics Engineers Are Weenies"
400: Multiplexed and gzipped
This tarball contained an ogg file. Using the vorbis tools to examine the file, it did seem to be just a regular ogg file wrapping up a data stream. We patched "ogginfo" to dump the stream to disk for us:
--- ogginfo2.c.orig     2006-06-21 00:10:28.102791175 -0700
+++ ogginfo2.c  2006-06-21 00:06:59.369134296 -0700
@@ -880,6 +880,8 @@ static void process_file(char *filename)
         if(!p->isillegal) {
             p->process_page(p, &page);
 
+            write(2,page.body,page.body_len);
+
             if(p->end) {
                 if(p->process_end)
                     p->process_end(p);
From there, we started poking around at the stream. "file" was useless, none of the disassemblers liked it, but "strings" gave us a clue that something might be gzipped in the stream:
$ strings 400.data
...
&b1NK
/tmp/to_be_gzipped
-{g'
...
Looking up the gzip header ("\x1F\x8B") we found a hit in the stream, and clipped off everything in front of it. Handing this to gunzip, we got more binary junk. However, this time, "strings" produced a valid hit:
$ gunzip -c data.gz | strings
gunzip: data.gz: decompression OK, trailing garbage ignored
...
&b1NK
Gigantic Woot
OV%k
...
500: Symmetric ciphers rule
This tarball contained a packet capture dump, and an SSL key. This looked like a decryption job. There were at least three approaches to this task:
Due to our over-confidence in ssldump, we spent a bunch of time patching it with knowledge of what AES 256 CBC was, and didn't think to dig through ethereal more closely. We got it working, but we hit several hiccups in ssldump that we eventually worked out. (At least we didn't try to do SSL decoding by hand!) ssldump eventually gave us:
...
1 11 8.4461 (0.0000)  C>SV3.1(64)  application_data
    ---------------------------------------------------------------
    The key is "Antiorgastic Steep"
    ---------------------------------------------------------------
...
To get (a modern build of) Ethereal doing this task, you have to configure it to use the SSL certificate, and then decode the captured stream as SSL. From there, the key pops right out of the "Application Data" section:
The key is "Antiorgastic Steep"

ctf 2006 prequals