With more time spent at home due to COVID-19 restrictions, I worked on a MI5 cryptography challenge called Can You Solve This Puzzle. The premise is that given an image (below), can we identify the hidden message?
Typically with image-based challenges, the solution usually revolves around finding the right steganography encryption technique(s) like the LSB obfuscation. So to get some hint, I poked into its exif for some reconnaissance:
~$ exiftool puzzle.png 2>&1 | tee puzzle.exif ExifTool Version Number : 10.80 File Name : puzzle.png Directory : mi5 File Size : 1497 bytes ... File Type : PNG File Type Extension : png MIME Type : image/png Image Width : 92 Image Height : 163 Bit Depth : 8 Color Type : RGB with Alpha Compression : Deflate/Inflate Filter : Adaptive Interlace : Noninterlaced SRGB Rendering : Perceptual Gamma : 2.2 Pixels Per Unit X : 3779 Pixels Per Unit Y : 3779 Pixel Units : meters Comment : As I read, numbers I see. 'Twould be a shame not to count this art among the great texts of our time Image Size : 92x163 Megapixels : 0.015
Which was very lucky because
Comment gives us a clue:
As I read, numbers I see. 'Twould be a shame not to count this art among the great texts of our time
Sadly I hit a dead end for a while as I looked into its color spectrum, pixel distributions, negatives, decoder scans, etc. Having already tried the common decoding techniques to no avail, I decided to change my strategy and start observing the physical characteristics of the puzzle itself.
Striped patterns stretching from top to bottom, left to right. This gave me an idea that this puzzle had very similar traits as boolean (
No (pixel) row is ever populated with the same color. This was the strangest characteristic. Every row there is a switch between two colors. If no row is ever completely filled with a consistent, single color, does this mean that there is some sort of limit to the length of the contiguous pattern?
Only “two” color variations. Although this PNG file is composed with Alpha channel gradients (there are actually 284 color types, provided below) - we can make a general assumption that the pixels are either pink or blue.
I re-visited the clue and read it more carefully; and I noticed that the puzzle authors had used some strange choice of words: “numbers”, “count”, and “text”.
numbers, count, and text..
Ah! Piecing together the observations from earlier, I realized what they wanted was for us to count the contiguous colored pixels and, very likely, that will return some ASCII-like characters (since ASCII is represented using 8 bits).
itertools to quickly offload some implementation logics, but the idea is very simple: load the puzzle.png into memory and extract its’ pixels, remove alpha from the pixels since we only care about RGB, calculate the “median color” so that our solution can be more flexible against gradients, group the colors into counts, and finally decode the counts into ASCII.
And once we run the decoder against the image, we get the following message.
Congratulations, you solved the puzzle! Why dont you apply to join our team? mi5.gov.uk/careers