Shmooganography is a little CTF event that takes place each year at Shmoocon in Washington, DC. This CTF is focused on stegonagraphy, and related techniques. I ended up participating in, and coming in first place with my team. I wanted to showcase an interesting method of hiding data that was used in the fourth round of the event.

# Challenge basics

This level starts with a .pcap file which contains a single MPEG audio stream. A sample of the packets can be seen with tshark

$ tshark -r ../Downloads/time_turner.pcap
--- snip ---
    4   0.012998    127.0.0.1 → 127.0.0.1    MPEG TS 1364 PT=MPEG-II transport streams, SSRC=0xEA80289, Seq=65356, Time=1664842007 Program Association Table (PAT) Program Map Table (PMT) Service Description Table (SDT) [MP2T fragment of a reassembled packet]
    5   0.014997    127.0.0.1 → 127.0.0.1    MPEG-1 1364 Audio Layer 3, 160 kb/s, 44.1 kHz Audio Layer 3, 160 kb/s, 44.1 kHz Audio Layer 3, 160 kb/s, 44.1 kHz
--- snip ---

There were 5820 packets in total in this capture, and there is some extra information encoded within the packet, somewhere.

# IP header basics

The general structure of an IPv4 header according to rfc791 follows:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Each “-” in the above diagram represents one bit. We are concerned with, specifically, the Options field. In this field, there are many different type of “options” you can specify, however each packet we are looking at, has its type as 0x44, or the Timestamp option. The structure of this sub field follows:

+--------+--------+--------+--------+
|01000100| length | pointer|oflw|flg|
+--------+--------+--------+--------+
|         internet address          |
+--------+--------+--------+--------+
|             timestamp             |
+--------+--------+--------+--------+

The first packet we have has the Options field containing the following bytes 44 08 05 40 00 00 00 01, so lets break this down.

The first byte 0x44 is the first entry, specifying the type of this Options field. Next, we have 0x08 for our length, the total length of this field, obviously 0x05 is the pointer field, which we are not really concerned with. Next we have 0x4 which is the upper half nibble of the next byte, and this nibble is the chosen covert channel of communication for our challenge. This is a known method of data exfiltration and a rather interesting one at that. The rest of the data in the Options field is not important to us.

# Reconstructing the message

Equipped with our new knowledge of how the hidden message is encoded, we can use a quick and dirty method of extracting our full payload from the packet capture file. For this, I used tshark:

$ tshark -r data.pcap -T fields -e 'ip.options.timestamp' | grep -v '^$' | cut -c 7-7 | tr -d '\n' | xxd -r -p > payload.dat

A quick explanation of the above command, the tshark command is used to read our packet capture and extract the ip.options.timestamp field from each IPv4 packet, then the results are filtered to remove empty lines with grep. Next, the high nibble of the fourth byte is extracted with cut, and new lines are removed to join the nibbles together. Finally, xxd is used to transform the resulting hex data into the corresponding raw bytes, and we are left with payload.dat, a GIF file containing the flag for the current level: ELDER.

Cool technique.

# References