This challenge provided you with a file that appeared to be a PNG that had been modified or corrupted by some means. Opening the file in a image viewer yielded nothing as the format had obviously been rendered unrecognizable. My intuition was to try and repair the structure of the PNG using whatever data was still correct.

http://en.wikipedia.org/wiki/Portable_Network_Graphics

After a little googling, I found a reference to PNG on wikipedia to help me through this challenge. I grabbed some code I had previously written in Java to parse PNGs and set out to figure out what had been altered. I also opened my handy hex editor so I could try and spot any obvious abnormalities in the format.

 

PNG_Uncorrupt

 

 

Looking at the header, it is easy to see that the fifth byte, 0xD, appears to be missing.

 

 

 

 

A PNG is composed of a header and a variable number of PNG chunks. The chunks follow the format detailed in the following image. By adding print statements to my PNG Parser, I was able to locate the parts of the file format that had been corrupted.

 

 

 

 

 

Parsing through the file revealed that the length of several of the PNG chunks were short of the lengths specified. The differences in actual lengths ranged between 0 and 3 bytes. I presumed that I could easily brute force the missing byte for the chunks missing only one byte by shuffling every byte possibility through the length of the chunk and seeing if the CRC checksum matched the one provided.  This technique appeared to work and I was able to repair at least a few chunks. However, this technique would not work for the larger missing chunks as the possibilities become exponential.

After determining the missing byte using the brute force method, I recognized that each missing byte was also a 0xD, like the one missing in the header, and always preceded a 0xA. My gut told me that this file had probably been corrupted by some software that had tried to convert line feeds between systems. Going on a hunch, I decided to locate all instances of the 0xA byte in each chunk, and only calculating the CRC checksum for each combination of these preceded by a 0xD. I ran across a combinatorics library that made quick work of outputting each combination of the 0xA candidates. I plugged the library into my Java code and wrote out the unmangled PNG to produce the following picture that revealed the flag.

 

corrupt_fixed

 

 

 

Your welcome to take a look at my code if you like but it’s pretty quick and dirty and will likely need some tweaking to link together all of the steps.