Tags: misc re

Rating: 0

# Proprietary Format - Reversing - 326 points - 19 teams solved

> The villains are communicating with their own proprietary file format. Figure out what it is.
>
> \$ nc proprietary.ctfcompetition.com 1337
>
> [Attachment](./c0f3178a1f16d1a2c8b281fd8cd10b24da2fc9eafa551664f73357efe091f189.zip)

The attachement is a file named flag.ctf - looking at it in a hex editor I saw four magic bytes GCTF at the
start, then little endian 32 bit values corresponding to 600 and 400 - so I assumed it was some kind of
picture format.

At first I completely missed that there was a network address in the challenge description, so I spent a lot of
time doing analysis of the content of the file. It seemed like some kind of stream format - each "element" was a
byte in the range 0x00-0x0f, where all elements except 0x0f was followed by a 3-byte value. Interpreting
these 3-byte values in isolation as RGB pixels gave some garbled pastel colored gradients, which suggested that
the picture format assumption was correct.

Due to lack of progress I dropped the challenge until near the end of the contest, when someone made me aware of
the network address. After a bit of error message guided fuzzing, I found out that the service first required
three lines each terminated by LF, first the format specifier P6, then the width and height of the picture,
like 320 240, and finally some unknown value that always had to be 255. Then it read in width*height raw RGB
pixel values, and in return it sent the picture encoded in the proprietary format.

With a reference encoder, I finally made some progress. I quickly realized that it was some kind of 2D based
lossy encoding, but couldn't figure out the specifics before time ran out.

Some days after the contest I realized what was missing from the puzzle and managed to write a decoder. First,
find the largest power of 2 square that can fit the entire picture - in the case of flag.ctf this is a
1024x1024 pixel square. Then, split the picture into quadrants, and read the first "command" byte. Here, each
bit corresponds to a512x512 pixel quadrant:

1 2
4 8

where a set bit means that you should recursively parse that quadrant, and a cleared bit means that you should
paint the entire quadrant with the color following after the command byte. (Since 0x0f means recursively parse
all quadrants, no color follows it.)

As an example, this is the format of the sample file, excluding the 12 byte header:

This means that the definition of the upper left 512x512 block comes first, then the definition of the upper
original picture was only 400 pixels high, this makes sense.
the flag CTF{P1c4Ss0_woU1d_B3_pr0UD}