Beyond Syntax

Looking beyond syntactical meaning

Sophos Holidy Puzzle Walkthrough

In case you missed the it there was a short holiday puzzle challenge over at the Sophos Naked Security blog. If you want to attempt solving it yourself I'd suggest going over and checking it out now before reading on because there will be plenty of spoilers. There is also a more Windows centric version on Belahzurs Thoughts, if that's what you would rather see that. Now, on with the challenges!

Step 1

The only hint is: =ImYndmbn1ieiBnLmJWdjJmZ.

The first things I noticed about this were the = at the beginning and the character set consisting of [A-Za-z0-9], meaning this is likely a reversed Base64 encoding. (Note that Base64 also includes + and /; they just don't appear here.) Using Python, these two actions are simple enough:

>>> '=ImYndmbn1ieiBnLmJWdjJmZ'[::-1].decode('base64')

That's still junk though, but now the junk looks a bit like a web address. Each letter is probably just shifted over a little bit (i.e. a becomes n). The most common form of character shift is to rotate the alphabet 13 characters ("rot13"). Well Python can do that as well:

>>> 'fbcubf.pbz-gnggbb'.decode('rot13')

(The preceeding u just means the string is in unicode.) Replace the - with a / and we've got the web address for step 2.

Step 2

Visiting the Step 2 site gives us our second puzzle: a text file with some hints and the following (suspicious block of text).

d320ae6fd64|  |etde2|  |83cba/       ||   _  \3c|   ____||           ||  |4h|  |54ddbf6b47asdl2063
8n34r58be58|  |840d6|  |04th|   (----`|  |_)  |0|  |__30g`---|  |----`|  |==|  |iaderf142179334fld
bwci6cbdfdt|  |91b52|  |6225c\   \d2aa|   _  <63|   __|328dbe|  |3d1c7|   __   |hf87ta3698hr193340
de1f9gdf023|  `====.|  |1.----)   |014|  |_)  |3|  |____f0o87|  |e72en|  |14|  |4t8dct07cde1964dd7
d124179/       |tb70/   \88374|  |010a6h025/   \1af2a|  \s|  |l|       \e|   ____||   _  \5822c768
80c9b2|   (----`722/  ^  \18e9|  |bdf3n50c/  ^  \1bf3|   \|  |2|  .--.  ||  |__3dd|  |_)  |e26276r
f0d8dd9\   \bdt66f/  /_\  \4ch|  |fc295d2/  /_\  \23f|  . `  |9|  |gi|  ||   __|2f|      /d89059c0
e25.----)   |52r6/  _____  \34|  `====.b/  _____  \5l|  |\   |0|  '--'  ||  |____4|  |\  \====.b07

This is most likely the starting point to the puzzle and one of the hints was that we'll need a password in this stage of the puzzle. After a bit of thinking I figured that a Zip file is the most likely candidate for cross-platform password protection, but how is that block of text a Zip file? Looking through the Wikipedia page shows that PK is the commonly the first two bytes of a Zip file, it just so happens that that translates to 504b in hexadecimal. Perhaps if I strip all the non-hex characters from the text block it will be a Zip file. This time I'll just use the Unix tr utility to strip non-hex characters:

$ tr -cd [A-Fa-f0-9] < > topsecret.hex

This deletes the compliment of the character set [A-Fa-f0-9] from the input file and outputs to topsecret.hex. The next step is to convert the ASCII representation of the hex digits to binary. Again, I turned to Python for this:

>>> infile = open('topsecret.hex')       # Sets up a file descriptor
>>> line = infile.readline()             # Reads the first line from infile (the only line)
>>> b = ''                               # An empty string we'll build on
>>> for c in range(0, len(line), 2) :    # Go through the characters (in steps of 2)
...     v = int(line[c:c+2], 16)         # Convert 2 ASCII values into their actual value
...     b += chr(v)                      # Append the actual value to b string
>>> infile.close()                       # Close the input file
>>> outfile = open('', 'w') # Open the output file in write mode
>>> outfile.write(b)                     # Write the contents of b to outfile
>>> outfile.close()                      # Close the output file

Now we've got a Zip file ready to go! We know the password was the cipher used to get from step 1 to step 2, so just unzip the file:

$ unzip
[...] password: rot13
  inflating: security-advice-for-train-commuters.gif  

Open up the file and you get to see a fantastic shade of pink!

A beautiful shade of pink!

We are probably not done quite yet, eh? We can look at the actual contents of the file by using xxd:

$ xxd security-advice-for-train-commuters.gif > security-advice-for-train-commuters.gif.dump

Opening that dump file up in a text editor and we see "Since when was pink a shade of gray?" Hmmm, maybe if we convert part of the from pink to gray we'll see something new. From years in web development you may know that #f1bbed is a shade of pink and that value shows up twice in the GIF file. I decided to change the first instance to 444444 a nice dark shade of gray. Now we can reverse the hex dump output back to the binary GIF format:

$ xxd -r security-advice-for-train-commuters.gif.dump > final.gif

Open that file and you get a much more clear version of the clue.


Probably not the final answer (it's an anagram). (I knew it was an anagram, but I couldn't figure out what it was saying so I emailed Paul Ducklin for a hint. -- I got stuck thinking "security" was in it with the "?" being any character.)

The hint was in a recent article about Lost USB keys, with the clue being "what is the article trying to tell you?"

Taking out "USB" from the image, it isn't too hard to determine the final answer:


I'm sure there are better tools to get to the answer, but this is how I did it!