Writeup – nomnom + ark (Bsides Canberra 2016)

I spent last weekend attending Bsides Canberra 2016 with the folks from the Platypus Initiative, and participated in the Bsides CTF as “Team Platypus Facts”, taking home 5/~30th place. During the CTF, there were two image manipulation challenges, which I wanted to provide a writeup on, due to the prevalence of these challenges in other CTFs.

Without further ado:


Ark was a classic data extraction puzzle – the provided PNG had a 7z file after the IEND chunk, which was easy enough to extract via a hex editor. This file contained a clue: something about the magic pixel being {0x69,0x23,0xXX}.

In the context of images, this is almost certainly a reference to a specific color, likely in RGB format. This was quickly confirmed by zooming in on the image:

dat mismatched pixel

go go gadget ENHANCE!

At this point, I should mention the excellent Python Imaging Library (commonly, “import PIL”). This works with most image formats, and can easily do manipulation of pixel values.  We can use this to build a quick python script, to extract each pixel which matches the magic pixel’s Red and Green value, and then (on a hunch), print out the Blue value as a character, giving us the flag:




Nomnom was a corrupted PNG file – this time, instead of extra data, the PNG had been stripped such that each block of two zero bytes turned into a single zero byte: that is:

00 00 -> 00
00 00 00 -> 00 00 
00 00 00 00 -> 00 00

Initially, my team misinterpreted the rules, thinking that single null bytes were somehow immune to this effect (this was relatively early on Saturday, before the more serious drinking efforts took effect; I’m not sure how we got to this conclusion). This led us to believe that brute forcing the ten-ish blocks of two and three null bytes would get us a flag and we’d be on our way.

After realizing our error, we took a deeper look into the PNG file itself, using the 010 text editor and a PNG template:

look ma, no hands!

look ma, no hands!

Thankfully, PNG files are structured in a block format, with clear human-readable block markers of 4 ascii characters in length (in 010 template form, the “CTYPE” header). Looking at the above, we can immediately see that the IHDR block is missing a zero before it (thus the “HDR” CTYPE): the only logical place is that the “00 00” in the chunk size is missing a zero.

Entering the missing 00, and hitting F5 to force a template refresh, shows us a more complete IHDR chunk. From here, we can immediately notice that the file dimensions are broken – a quick manual inspection reveals a file of 0x000F0000*0x00096008: some additional zeroes quickly sorts this out:

now with reasonable dimensions!

now with reasonable dimensions!

From here, the challenge is super easy to follow: simply manually repair each chunk by inserting zeroes such that the chunk header lines up. Inspect each chunk, and if you see anything extraordinarily out of place (especially values higher than they should be), you probably need to insert a zero byte.

Fifteen minutes / approximately 30 PNG chunk headers later (and with about half an hour left on the CTF timer), this one is (somewhat) in the bag:

dat flag

dat flag

Note that the PNG is effectively still broken, as some of the IHDR chunks we got were still broken: they were the right length but zeroes had been inserted in the wrong places. Still, the PNG image data was in the right place and we had the flag, so we didn’t really stress this point.

Overall, Bsides was a fantastic experience. As always, thanks to the organisers for putting together a fun weekend of CTFs and ~content~.

Special thanks to chancey for making Team Platypus Facts ~happen~!

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Bards, Computers, Jesting and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s