8891 – Santas leak (Hackvent 2015 Teaser)

04 Dec 2015
CTF: Hacking Lab
Link to challenge:
Date Completed: 04 December 2015

This was a fun and interesting challenge to kick off Hackvent. It took me 4 days to solve the problem! I strongly suggest you attempt the problem yourself before reading by solution.

You can get the single image you need to do the challenge here (santa.png):

Download Starting Image

These are all the files/scripts I ended up with after the challenge (zipped):

Download Solution Files and Scripts

The Challenge


The solution to this challenge is pretty long and has multiple steps. I’ve explained what I have done in detail and I have also explained approaches I tried which did not work.

Initially, we have the Christmas ball png image which I will call santa.png.

Santa Leak New Image

I take the original image and use a QR reader to read the message.

I get the string:
nyy lbh arrq vf urer

This looks like rot13 to me (vf is the same as is, I recognised this instantly).
I pass the string through an online rot13 encoder/decoder (link) to decode to get:
all you need is here

Essentially this tells me that the only file I was given (santa.png) contains the solution.

Now, the HV15 nugget is of form: HV15-aaaa-bbbb-cccc-dddd-eeee
The solution to this teaser will start start with HV15-  based on rules.
Thus, we need 29 characters in the final solution.
Keep this in mind as we progress.

Next I try to open the santa.png with Winzip on Windows (to search for any hidden files within).
Luckily I get a file, 2.wav!

I play the WAV file and hear DTMF tones (probably generated via Audacity).
I use an online tool (link) to turn the codes in numbers and get the following number:

These look like ASCII codes! I try to space them out so they give me regular character [A-Za-z0-9].
I get (using space as a separator):

Converting this to ASCII I get:
just possible within such a rar

This hint doesn’t tell me much right away.
I try various others things such as binwalk on linux to try and reveal hidden files within.
Binwalk finds the header for a YAFFS filesystem at 0x3AAD4.
I try to mount this filesystem using yaffs2utils (which supports YAFFS1) but the process fails. This is a dead end and the header was just a coincidence.

I then look at Windows tools and find the SFind tool by McAfee.
I find hidden streams only visible on an NTFS system and see that 2.wav contains a file, namely 3.txt.

I extract the contents and feed it to notepad:

I notice that the entire contents of 3.txt are encoded in base64. I use the python script below to decode the base64 encoded contents.

Inspecting the output with HxD editor, I realise that we have a PDF version 1.5 file!
I open this in a PDF viewer and the file is valid.

The PDF contains the Brainfuck code below:

I run it through an online Brainfuck interpreter (link).

The following message is printed:

At this stage I use binwalk to inspect the pdf for more files. I use the recursive flag with high depth to extract as much as possible. The latest version of binwalk also extracts Zlib’s for me which was nice.

I run:

I get a png image of a Christmas ball (blank) among other various files as output.

Most of the files are rubbish but I do notice one file that contains 25 SHA1 hashes (due to the 40 hex characters). I see if these hashes have been cracked using online tools, they have not. I keep this hashes in mind as I continue.

Visiting the website:
I manage to extract more files from the pdf (that binwalk could not).
I obtain 3 images:

  • a png image of a christmas ball (with “Wrong One” written on it),

Wrong One Christmas ball

  • a png image of a grey empty Christmas ball, and

Grey Empty Christmas Ball

  • a jpeg image which appears to contain static.

JPEG Static Magic Eye Image

Later, I discover that this jpeg is a magic eye image.

I use an online magic eye solver (link) to find the solution.

The result is the following image which looks like heiroglyphs:

Windings Hidden Message
I shortly realise that the characters resemble the Windings font.
I use a character map for Windings 1 to determine what each symbol means (ie what is its ASCII equivalent symbol).

I obtain the following message:

Or (on one line):


This seems to be related to the 25 SHA1 hashes I found earlier.
[01]{25}  looks like regexp meaning a permutation of 25 0’s and 1’s.

I write a python script to get all 25 length permutations of 1 and 0, and hash them using SHA1.
The script checks to see if we get a match with any SHA1 sum in our list from earlier (cross reference check).

This is the result after running the tool (took ~5 minutes to complete):

I generated a total of 33554432 (225) hashes.
I find that we obtain 25 results that match our list of SHA1 sums!

I try many things at this stage but eventually decide to order the inputs that generate the 25
SHA1 sums in the same order as the file containing the 25 SHA1 sums.
This is what I get when looking at the 1’s and 0’s (I added some spaces in for the layout, you’ll see why shortly).

After some time I see that each corner of the binary grid contains a sequence of 0’s which is odd. I think back to HACKvent challenges and they almost always end up with you scanning a QR code.
This bit grid looks like a QR code!

After some research I determine that the code is a Version 2 QR code (25 x 25 pixels).
I write a script that takes in the 1’s and 0’s and outputs an image.
I invert all the bits before feeding it to my program so that the right parts are black or white.
This generated a QR image!

Original QR Image

I enlarge the image (zooming in on photo viewer) and try to scan it but fail.
Online tools also fail to scan it.

There are obviously errors in the QR code (by checking the QR specification), namely:

  • Finder pattern incorrect
  • Dark module is white (a single black pixel at y coord 17 (in case of Version 2))
  • Alignment pattern incorrect
  • Check bits and redundant copies of check bits are incorrect

I assume that the issue is with the check bits so I write a python script to determine the correct number of check bits. This script is based on the content here.

I try many inputs and eventually get some partial results using the following parameters:

I generate a modified version of the QR code which fixes all of the above issues and I get a partial result:


Note: I got the above result using a good QR scanner (link) which detects a lot of errors and offers debugging. My QR code still had errors in it but it was able to decode some of it anyway.

The beginning of the result matches our flag pattern but the middle is all messed up.

I ask for a clue on the hacking-lab IRC channel and somebody tells me I need to solve the errors using “one big change”. This leads me to believe I need to do something simple like swap rows etc.
I learn that swapping rows does not correct the issues.

However, if I take an inner block (square) where the endpoints are determined by the error in each finder pattern (and alignment pattern) and invert the bits, I can fix the Finder pattern error, the Alignment pattern error as well as the Dark Module error all in one move!

Illustration showing bits to invert (highlighted yellow):

Inner Square Bits to Invert

I guess that this could solve the check bits too. I modify my QR generator script so it inverts all bits within this inner square and produce a QR code. This is the modified (final) script:

This produced a valid QR code that scans!

Note: QR code images have all been enlarged to 350×350 pixels.
Refer to downloads at the top of this post for 25×25 pixel versions.

Final QR Code for Santa Leak

We use a QR reader to fetch the flag:


Reading this as English:
HV15 Will Rock this xMas Hobo


No Comments

Posted in Hacking Lab


Leave a Reply