CSAW CTF - Forensics

Monday, October 01, 2012 » airmack, csaw, ctf, luks, robbje, spq

Forensics challenges of the 2012 CSAW CTF

Forensics200 a and b

Given is only a PNG-image called version1.png. Opening it with hachoir-urwid reveals 500 text sections holding fields size, tag, keyword, text and crc32. The text are seemingly random names enclosed by the csaw ctf key{...} tag. The picture itself shows the text "One of those things is not like the other", indicating that one of these names might be unique and therefore the sought key. To make parsing the data easier, one can carve out the interesting data using dd.

1
dd if=version1.png of=data bs=1 skip=3585 count=19451

A quick-and-dirty python script should check, if the checksums in the file match the checksum calculated from the concatenation of tag, keyword and text. At this point there was some confusion wether the checksum should be in network-byte-order, rather than host-byte-order. However, all of those checksums were correct, except one, which is the key for the first forensics challenge: key{takeuchi gregory}.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/python

import binascii

fh = open("data", "rb")

for i in range(0, 500):
    size = fh.read(4)
    tag = fh.read(4)
    keyword = fh.read(8)
    name = fh.read(ord(size[3])-8)
    crc = fh.read(4)
    crc32 = ""
    for x in range(0,4,1):
        x = hex(ord(crc[x])).replace("0x","")
        if len(x) == 1:
            x = "0" + x
        crc32 += x
    a = hex(binascii.crc32(tag+keyword+name) & 0xffffffff)
    b = hex(int(crc32, 16) & 0xffffffff)
    if a != b:
        print name
fh.close()

Using the same method on version2.png reveals, that all but one of the given checksums do not match the calculated checksum. Using above script, changing a != b to a == b gives the flag key{johnnie tigger}.

Forensics 500

This was one of the challenges introduced halfway through the game and was solved immediately by a couple of teams. Seeing this, an easy approach seemed best. The file downloaded was called core. Not caring about what it is,

1
strings core | grep {

gives the flag: k3y{this_should_be_pretty_hard_unless_you_use_grep}.