An error occurred while uploading 2712 là gì năm 2024

In the following write up of the Holiday Hack Challenge 2018, you’ll find an enthralling take on a story we all know. Sure there is the mystery of , but there’s also the intrigue of , the thrill of unknown , and the allure of a 0day. You’ll also find an , the truth behind , and some of our own.

You’ll feel like you won a Golden Ticket with how easy it is to follow along. The sections along the side expand in an everlasting way, not unlike a Gobstopper, and what presents itself like a piece of gum; small and easily chewed through, but actually fills you up like a three course meal. We lay out the answers off the bat so you can chew into the Wonka Bar-like sweetness right away.

We then move into the pre hack we went through, as if we were watching Nakatomi Plaza before attacking the hack. had us waiting for our chance to arrive at the Holiday Party and make our presence known. From there, we work our way through the story like Samantha Coleman before we drop into the juicy part of the challenge.

You’ll see the come up next, with a detailed overview. Each one will give the goal and any necessary background needed to begin tackling it (including relevant hints and videos). Feel free to skip right to the Solution (including asciinema videos, that allow you to copy and paste) if you just want to know the answer. If you feel like learning more, we’ll then step you through our thought process in solving the problems, how the challenge was made, and sometimes, an alternate solution. The Summary for each challenge is also a good spot to skip to if you’re short on time as you’ll get a nice, brief idea of what we did. The following section works almost exactly the same, though leans more on pictures than gifs.

After that is the . We managed to escalate privileges on the Snort system, which allowed us to pivot to snortsensor1. There we discovered a 0day in rssh, and exploited a race condition which allowed us to read arbitrary files as root.

We also thought it might be useful to show our entire process, how we worked efficiently as a small , maybe our ideas will help others. You might also have better ideas and can share your techniques with us, we love to learn and improve!

Some artifacts will be left on our Github as they fit better there and we don’t want to overwhelm you any more than required. See how many easter eggs you can find between this site and the Github!

Happy reading,

The ESnet Security Team

–Dop, Sam and Vlad

Answers

  1. What phrase is revealed when you answer all of the KringleCon Holiday Hack History questions?
  2. Who submitted (First Last) the rejected talk titled Data Loss for Rainbow Teams: A Path in the Darkness?
  3. The KringleCon Speaker Unpreparedness room is protected by a door passcode. Upon entering the correct passcode, what message is presented to the speaker?
  4. Retrieve the encrypted ZIP file from the North Pole Git repository. What is the password to open this file?
  5. Using the data set contained in this SANS Slingshot Linux image, find a reliable path from a Kerberoastable user to the Domain Admins group. What’s the user’s logon name?
  6. What is the access control number revealed by the door authentication panel?
  7. Which terrorist organization is secretly supported by the job applicant whose name begins with "K"?
  8. What is the name of the song described in the document sent from Holly Evergreen to Alabaster Snowball?
  9. What is the success message displayed by the Snort terminal?
  10. What is the domain name the malware in the document downloads from?
  11. What is the full sentence text that appears on the domain registration success message (bottom sentence)?
  12. What is the password entered in the database for the Vault entry?
  13. What message do you get when you unlock the door?
  14. Who was the mastermind behind the whole KringleCon plan?

Reconnaisance

Any penetration test starts with reconnaisance on your target. In a typical Capture the Flag (CTF) or other hacking challenge, you're given all this information up-front. However, this step shouldn't be skipped, as it can make the challenge easier.

Goal

Identify domain names, hostnames, IP addresses, etc.

Reverse Whois

First, we'll try to identify the domain names being used. Last year, the domain was northpolechristmastown.com. Every domain name has some ownership information associated with it. We can query this information via a

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

96 lookup:

$ whois northpolechristmastown.com

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

northpolechristmastown.com was registered in October 2017, and the organization is listed as Counter Hack. Using this information, we can also do a "reverse whois" search, where we can see all domains that a given organization is listed as the registrant for:

An error occurred while uploading 2712 là gì năm 2024

Figure 1: A reverse whois search for Counter Hack

kringlecon.com was registered in May, and in July it was opened up for participants to begin signing up, and poking around (more on that below, in "LineCon").

erohetfanu.com and kringlecastle.com were registered in October. LineCon gave us a hint about the castle. erohetfanu.com seems obfuscated.

Domain Name System (DNS)

Armed with the 3 domain names, we'll see what additional information we can glean. DNS attempts to convert between hostnames and IP addresses.

dig +noall +answer ANY kringlecon.com

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

There's a lot of information returned, but we can learn thatkringlecon.com resolves to the IP address 104.196.14.143, that DNS services are provided by domaincontrol.com, and that e-mail services are provided through Google Mail. These are "indicators," and can be used to track how a certain actor likes to operate. Domains and IP addresses can change, but tactics often stay the same.

Whois also works on IP addresses, so we can see the ownership of the IP address returned:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

The IP address is owned by Google, and the name of the network implies that it's part of Google's Cloud offerings. Some more digging reveals that northpolechristmastown.com was set up the same way.

We can perform similar queries on the other two domains, and we find out the following information:

Domain Purpose Domain Registration Date Domain Registry DNS Provider Mail Provider IP Address IP Owner northpolechristmastown.com Last Year's Domain October 19th, 2017 GoDaddy.com domaincontrol.com Google n/a Hosts hosted on Google Cloud kringlecon.com The Kringle Conference May 25th, 2018 GoDaddy.com domaincontrol.com Google 104.196.14.143 Google Cloud kringlecastle.com Unknown: Kringle's Castle? October 12th, 2018 GoDaddy.com domaincontrol.com Google n/a Unknown erohetfanu.com Unknown: Something hidden? October 16th, 2018 GoDaddy.com domaincontrol.com Google 104.196.126.19 Google Cloud

Certificate Transparency Logs

After determining the domains for this year's Holiday Hack, we'd like to figure out what systems there are in those domains. A good way of doing this is via Certificate Transparency logs – public logs which serve as an audit mechanism for SSL certificates which are issued, in order to detect mistaken or malicious certificates.

There are several free services which allow you to query these logs. I like using VirusTotal.com:

An error occurred while uploading 2712 là gì năm 2024

Figure 2: Certificates for kringlecastle.com

An error occurred while uploading 2712 là gì năm 2024

Figure 3: Certificates for kringlecon.com

Monitoring

Since we found several hosts that use SSL certificates, it's a pretty safe bet that they'll be web servers. We can set up monitoring to poll some of these systems, so that we'll know as soon as the contest goes live.

An error occurred while uploading 2712 là gì năm 2024

Figure 4: Let the games begin…

Summary

IP Address Hostname 35.185.2.206 scanomatic.kringlecastle.com hohohodaddy.kringlecastle.com 35.185.76.157 docker2018-qa.kringlecon.com 35.185.89.85 git.kringlecastle.com 35.185.103.210 pianolockn.kringlecastle.com 35.185.104.53 docker.kringlecon.com 35.190.187.47 packalyzer.kringlecastle.com 35.196.29.176 doorpasscode.kringlecastle.com cfp.kringlecastle.com pianolock.kringlecastle.com 35.196.162.157 narrative.kringlecon.com 35.229.118.54 careers.kringlecastle.com 35.237.171.66 vents.kringlecastle.com 35.243.215.176 status.kringlecon.com 104.196.14.143 www.kringlecon.com kringlecon.com api.kringlecon.com rsvp.kringlecon.com 104.196.66.61 snortsensor1.kringlecastle.com

LineCon

Goal

Register for the conference, and look for any secrets

Finding a hidden path

While zooming out the browser window, something appeared off to the right:

An error occurred while uploading 2712 là gì năm 2024

Figure 5: A secret snow path

Upon visiting the secret path, we could see a castle in the distance.

An error occurred while uploading 2712 là gì năm 2024

Figure 6: Kringle Castle?

Client-side tricks to make secrets stand out

To make it easier to see hidden paths, we can use this JavaScript snippet in our browser's Javascript console. To access the console, visit

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

97 →

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

98 →

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

99 in Firefox, and

dig +noall +answer ANY kringlecon.com

00 →

dig +noall +answer ANY kringlecon.com

01 →

dig +noall +answer ANY kringlecon.com

02 in Chrome.

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
The game uses a special HTML class called "lava" for any element which is "walkable." Our snippet finds all elements which have that class, and then sets their background color to pink.

An error occurred while uploading 2712 là gì năm 2024

Figure 7: Making everything pink in the Console

An error occurred while uploading 2712 là gì năm 2024

Figure 8: Pink paths!

Game Internals: WebSocket Messages

Using the same Developer Tools, we can start reverse engineering how the game works. As we'll discover, the game relies on WebSocket messages. Firefox currently lacks the ability to view these messages, so it's recommended to use Chrome for this portion.

This time, we'll use the

dig +noall +answer ANY kringlecon.com

03 tab in the Developer Tools. Network traffic from your browser will be listed here. If this tab wasn't open when the traffic was initiated, nothing will show up, so it's best to have this tab open and then refresh the page, to ensure we see everything. Once we login go the game, we can filter on WebSocket connections by clicking on the

dig +noall +answer ANY kringlecon.com

04 filter, and then view the

dig +noall +answer ANY kringlecon.com

05 tab to see the individual messages:

An error occurred while uploading 2712 là gì năm 2024

Figure 9: WebSocket messages

Messages in green are messages that we sent to the server, and the other messages are the replies. By interacting with the game and observing which messages are sent/received, we can slowly learn how to interact with the game without a browser.

Using the new-found knowledge about WebSocket messages, we can create a simple client for the game:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

Game Internals: Avatar DNA

As we explored LineCon, one feature that drew our attention was that the appearance of each avatar was encoded as DNA. Using the standard DNA sequence letters (A, T, C, G), pairs of letters would encode the numbers 0-3:

dig +noall +answer ANY kringlecon.com

06. A neat detail is the fact that these pairs match DNA nucleic-acid pairs (i.e. in the double-helix, A is complementary to T, and C with G).

The avatar is encoded as a 120 character sequence, such as

dig +noall +answer ANY kringlecon.com

07. Once we convert the pairs back to numbers, we get a 60 digit sequence:

dig +noall +answer ANY kringlecon.com

08.

Inspecting the Javascript code, we can see how this sequence gets translated back to an avatar:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

Returning to our example, we can convert the sequence to these fields. A quick way to convert the numerical sequences is using Python's

dig +noall +answer ANY kringlecon.com

09 function with a base of 4:

dig +noall +answer ANY kringlecon.com

10.

Offset Size Sequence Name Value 0 4 0001 size 1 4 8 00000001 legs 1 12 8 00003123 hue 219 20 8 00000011 torso 5 28 8 00000012 head 6 36 4 0001 saturation 1 40 8 00000020 mouth 8 48 8 00000012 eyes 6 56 4 0003 brightness 3

We can verify our decoding by searching for the names of the color schemes in the Javascript. In the example sequence above, the avatar selection modal used "Flimsy Cappuccino," which we can find defined as:

dig +noall +answer ANY kringlecon.com

11. An exact match!

Another cool mini-feature is that if you open up the

dig +noall +answer ANY kringlecon.com

12 tab of your Developer Tools, you can see representations of the DNA sequence:

An error occurred while uploading 2712 là gì năm 2024

Figure 10: DNA Sequences in the Console tab

The color scheme is:

dig +noall +answer ANY kringlecon.com

13. So, in the example above, the top line starts

dig +noall +answer ANY kringlecon.com

14, and the bottom line is the complementary sequence

dig +noall +answer ANY kringlecon.com

15.

First Finding: Avatar vulnerability

In the

dig +noall +answer ANY kringlecon.com

03 tab of the Developer Tools, we can see other resources that are being loaded by the game. One of these is an image, called

dig +noall +answer ANY kringlecon.com

17:

An error occurred while uploading 2712 là gì năm 2024

Figure 11: egg.png

It seems like the game uses this when it can't load an image:

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
While investigating this mysterious image, it was discovered that we could use our WebSocket client to set an invalid avatar for ourselves.

Doing this caused an exception which would render our game completely black and inoperable.

Worse yet, our avatar was being loaded by other players in the game, and it would cause their screens to go black as well.

We quickly set our avatar back to its original state, and reported this issue to the SANS Counter Hack team. They quickly issued a fix for it.

Summary

LineCon was a great preview! We prepped some in-browser tricks for making paths or other interesting elements stand out. We wrote a simple Python script which allowed us to interact directly with the game. And we discovered and reported our first vulnerability.

KringleCon

Map

First, we walk around, familiarizing ourselves with the surroundings:

An error occurred while uploading 2712 là gì năm 2024

Story

As you walk through the gates, a familiar red-suited holiday figure warmly welcomes all of his special visitors to KringleCon.

Your narrative begins when you stop to chat with Santa and he shares the preceding.

Continuing into the castle, you begin to poke around. Once you complete the door passcode challenge and receive the

dig +noall +answer ANY kringlecon.com

18 token, you start to notice some suspicious behavior:

Suddenly, all elves in the castle start looking very nervous. You can overhear some of them talking with worry in their voices. The toy soldiers, who were always gruff, now seem especially determined as they lock all the exterior entrances to the building and barricade all the doors. No one can get out! And the toy soldiers' grunts take on an increasingly sinister tone.

You carry on and help out by finding some secrets in a git repository. This unlocks the

dig +noall +answer ANY kringlecon.com

19 token. While receiving that, you begin to see something disturbing, the toy soldiers act even more aggressively.

They are searching for something – something very special inside of Santa’s castle – and they will stop at NOTHING until they find it.

Hans seems to be directing their activities. What could they be after? In the main lobby on the bottom floor of Santa's castle, Hans calls everyone around to deliver a speech. Make sure you visit Hans to hear his speech." What could he have to say?

Ladies and Gentlemen…

Due to the North Pole’s legacy of providing coal as presents around the globe …

… they are about to be taught a lesson in the real use of POWER.

You will be witnesses.

Now, Santa… that’s a nice suit… John Philips, North Pole. I have two myself. Rumor has it Alabaster buys his there.

I have comrades in arms around the world who are languishing in prison.

The Elvin State Department enjoys rattling its saber for its own ends. Now it can rattle it for ME.

The following people are to be released from their captors.

In the Dungeon for Errant Reindeer, the seven members of the New Arietes Front.

In Whoville Prison, the imprisoned leader of ATNAS Corporation, Miss Cindy Lou Who.

In the Land of Oz, Glinda the Good Witch.

All of a sudden, all of the toy soldiers are similarly taken by Die Hard references:

Grunt!

Links.

Nein! Nein! Nein!

No one is coming to help you.

Get the over here!

Schnell!

As you keep digging for secrets trying to figure out just what’s going on here, you break into the domain and get the

dig +noall +answer ANY kringlecon.com

20 token. This reveals another, even more sinister sight:

The toy soldiers continue behaving very rudely, grunting orders to the guests and to each other in vaguely Germanic phrases. Suddenly, one of the toy soldiers appears wearing a grey sweatshirt that has written on it in red pen, "NOW I HAVE A ZERO-DAY. HO-HO-HO."

The elves are panicking:

Oh my! Santa’s castle… it’s under siege!

We’re trapped inside and can’t leave.

The toy soldiers are blocking all of the exits!

We are all prisoners!

That is worrisome, but even more so when you start to hear, "A rumor spreads among the elves that Alabaster has lost his badge. Several elves say, 'What do you think someone could do with that?'"

Quickly trying to help out and save the castle from attack, you find an example badge used to beat the qrcode Scan-O-Matic objective. Finding a way to trick your way through this badge reader to earn your

dig +noall +answer ANY kringlecon.com

21 token, you hear, "Congratulations! You have gained access to Santa's secret room." This is great, but then you quickly learn that, "Hans has started monologuing again. Please visit him in Santa's lobby for a status update."

Our captor tells us:

So, you’ve figured out my plan – it’s not about freeing those prisoners.

The toy soldiers and I are here to steal the contents of Santa’s vault!

You think that after all my posturing, all my little speeches, that I’m nothing but a common thief.

But, I tell you – I am an exceptional thief.

And since I've moved up to kidnapping all of you, you should be more polite!

As you go listen to Hans, you notice a vent cover that seems… not quite right. As you wonder where this maze of a vent system could take you, you eventually find your way out. This unlocks the

dig +noall +answer ANY kringlecon.com

22 token and you find yourself in a new room. "Great work! You have blocked access to Santa's treasure… for now. Please visit Hans in Santa's Secret Room for an update." As you approach Hans, "…suddenly, Hans slips and falls into a snowbank [editor’s note: that is strangely located inside this secret, third story room hidden in a castle]. His nefarious plan thwarted, he's now just cold and wet." Things are starting to look up, "But Santa still has more questions for you to solve!"

You need to find Santa to see if you can answer his questions. Your eye lands on a door you couldn’t have seen before. It won’t open and has some strange musical lock on it. After struggling with it, you finally defeat the lock and collect the

dig +noall +answer ANY kringlecon.com

23 token. With this, you are able to enter this final hidden room and talk to Santa.

Congrats! You have solved the hardest challenge! Please visit Santa and Hans inside Santa's Secret Room for an update on your amazing accomplishment!

The elves say "YAY! You won!", and Hans and the now hat-less toy soldiers join in on congratulating us. Santa explains:

You DID IT! You completed the hardest challenge. You see, Hans and the soldiers work for ME. I had to test you. And you passed the test!

You WON! Won what, you ask? Well, the jackpot, my dear! The grand and glorious jackpot!

You see, I finally found you!

I came up with the idea of KringleCon to find someone like you who could help me defend the North Pole against even the craftiest attackers.

That’s why we had so many different challenges this year.

We needed to find someone with skills all across the spectrum.

I asked my friend Hans to play the role of the bad guy to see if you could solve all those challenges and thwart the plot we devised.

And you did!

Oh, and those brutish toy soldiers? They are really just some of my elves in disguise.

See what happens when they take off those hats?

Based on your victory… next year, I’m going to ask for your help in defending my whole operation from evil bad guys.

And welcome to my vault room. Where's my treasure? Well, my treasure is Christmas joy and good will.

You did such a GREAT job! And remember what happened to the people who suddenly got everything they ever wanted?

They lived happily ever after.

Walking back out of these once secret rooms, as you leave the castle and hear Jason the plant's lament of psmitty, you realize that instead of snaking through the arduous, confusing maze of vents, you could have won the

dig +noall +answer ANY kringlecon.com

24 token and gotten the same access, and heard the same information. Oh well, you saved the day, and what action hero are you really if you don’t come out looking bloodied and dirtied like this at the end?

An error occurred while uploading 2712 là gì năm 2024

Bonus: Crawling through the Vents

Now I know what a TV dinner feels like. —John McClane

Solution 1: Manually Crafted Vent Maze

On the left side of the lobby in Santa's Castle is a large air vent that's large enough to crawl through, upon entering it's soon clear that this is a maze. This can be solved manually by carefully crafting a map during an hour long meeting (not that anyone would do that).

An error occurred while uploading 2712 là gì năm 2024

Solution 2: Recover Map from Git Repository

In , we manage to recover a map from the GitLab server.

Solution 3: Automated Maze Solver

Perhaps the most fun way to solve the maze is programmatically. To move, your browser sends a request like:

https://vents.kringlecastle.com/move?heading=w&mazex=23&mazey=19&mazef=1&playeraction=forward&locationkey=ba49a09644aa8fa7fb0082e935f46521&resourceid=inigomontoya

Breaking that out to be more clear:

Field Value Meaning

dig +noall +answer ANY kringlecon.com

25

dig +noall +answer ANY kringlecon.com

26 Current heading: n=north, w=west, s=south, e=east

dig +noall +answer ANY kringlecon.com

27

dig +noall +answer ANY kringlecon.com

28 Current X coordinate

dig +noall +answer ANY kringlecon.com

29

dig +noall +answer ANY kringlecon.com

30 Current Y coordinate

dig +noall +answer ANY kringlecon.com

31

dig +noall +answer ANY kringlecon.com

32 Current maze floor

dig +noall +answer ANY kringlecon.com

33

dig +noall +answer ANY kringlecon.com

34 Potentially valid options: forward, backward, up, down

dig +noall +answer ANY kringlecon.com

35

dig +noall +answer ANY kringlecon.com

36 The unique location id key for where you currently are

dig +noall +answer ANY kringlecon.com

37

dig +noall +answer ANY kringlecon.com

38 Never changes, clearly a reference to The Princess Bride

It's important to note that every location on the vent map has a unique locationkey. So we can't just sent a request for every possible x,y,f position without traversing the maze and learning the location keys. Assuming you send an action that moves you to a valid location, the server response will include a number of variables outlining your current state:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

The important parts here are the True/False value of the four walls, which gives us valid headings, and the locationkey for our new coordinates. The size of the response is generally within a few bytes (3509-3514) which can be used to help find locations that aren't like the others, like the shaft to the second floor and the exit. In these cases the response size changes as well as the arrow-up/arrow-down elements may be visible instead of hidden.

A Python script was written to automatically solve the maze by always going right. It generates a map with the following final output. 'S' is the starting location, 'U' and 'D' represent up and down possibilities, and 'X' marks the current location: the exit.

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

0

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

1

Exiting the vent maze you end up in Santa's Secret Room. The other way to get there is through the .

Cranberry Pi Terminals

Essential Editor

Goal

Background

  • Elf Chat Bushy Evergreen tells us the following:
    Hi, I'm Bushy Evergreen.

I'm glad you're here, I'm the target of a terrible trick.

Pepper says his editor is the best, but I don't understand why.

He's forcing me to learn vi.

He gave me a link, I'm supposed to learn the basics.

Can you assist me with one of the simple cases?

Badge Hint

Once Bushy tells us the above, we get the following hint: Indiana University Vi Tutorials

Relevant KringleCon Videos None

Intro

When we login, we're presented with the following screen:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

2

Solution

This can be easily solved with the hint from Bushy Evergreen. As the page says, to exit, hit

dig +noall +answer ANY kringlecon.com

39, then type

dig +noall +answer ANY kringlecon.com

40. Escape ensures that

dig +noall +answer ANY kringlecon.com

41 is in command mode,

dig +noall +answer ANY kringlecon.com

42 is the command for quit, and the exclamation point instructs it to not warn us about any unsaved changes.

Game Internals: How it was made

The Docker terminals drop us into a terminal with our Bash shell running. Normally when Bash is running, it will read some configuration files on startup, including

dig +noall +answer ANY kringlecon.com

43 in the user's home directory. Inspecting our

dig +noall +answer ANY kringlecon.com

43, we see the following two lines at the bottom:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

3

When Bash starts, it runs

dig +noall +answer ANY kringlecon.com

45, opening the file

dig +noall +answer ANY kringlecon.com

46. Whenever

dig +noall +answer ANY kringlecon.com

45 exits, it runs

dig +noall +answer ANY kringlecon.com

48.

Using to reverse engineer binaries, we can recover this script. The main logic of the script is:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

4

The

dig +noall +answer ANY kringlecon.com

49 function will actually make sure that no process named

dig +noall +answer ANY kringlecon.com

41 is running. So, even if you had called

dig +noall +answer ANY kringlecon.com

51 from within

dig +noall +answer ANY kringlecon.com

45, you would not receive credit.

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

5

The final noteworthy portion of this script is calculating the HMAC which is sent to the game server to receive credit for completion of this challenge. The HMAC algorithm is discussed in detail in However, the source code does reveal the HMAC key:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

6

Summary

We escaped

dig +noall +answer ANY kringlecon.com

45 by giving the quit command. We then showed how

dig +noall +answer ANY kringlecon.com

45 was being started upon login, and how we received credit for completing it. We successfully reverse-engineered the

dig +noall +answer ANY kringlecon.com

51 binary, and recoved the HMAC key, so now we can receive credit without ever solving the challenge at all.

Goal

To solve this challenge, determine the new worker's first name and submit to runtoanswer.

Background

  • Elf Chat Minty tells us:
    Can you help me? I'm in a bit of a fix.

I need to make a nametag for an employee, but I can't remember his first name.

Maybe you can figure it out using this Cranberry Pi terminal?

The Santa's Castle Onboarding System? I think it's written in PowerShell, if I'm not mistaken.

PowerShell itself can be tricky when handling user input. Special characters such as & and ; can be used to inject commands.

I think that system is one of Alabaster's creations.

He's a little … obsessed with SQLite database storage.

I don't know much about SQLite, just the .dump command.

Badge Hint Relevant KringleCon Videos None

Intro

When we launch the Cranberry Pi, we see:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

7

Solution

Given the hints, it sounds like our penultimate step is to dump the data from SQLite, and look for someone named Chan. The Powershell menu presents us with three options:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

8

Maybe we're on a quitting streak after the first terminal, but we start by trying to get to a command prompt directly, and hit

dig +noall +answer ANY kringlecon.com

42 to quit. Unfortunately, that hangs the terminal, and we can't type anything else.

Reloading, and trying again, we do the onboard process. Minty mentioned trying to give Powershell tricky characters, like

dig +noall +answer ANY kringlecon.com

57 and

dig +noall +answer ANY kringlecon.com

58:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

9

No luck. Once we hit enter, we're back in the main menu. We'll move on to the last unexplored option, verifying the system.

dig +noall +answer ANY kringlecon.com

0

So, the verification pings the server you give it, and then checks the

dig +noall +answer ANY kringlecon.com

59 file. Once again, let's try giving it some potentially troublesome characters:

dig +noall +answer ANY kringlecon.com

1

Submitting

dig +noall +answer ANY kringlecon.com

58 and

dig +noall +answer ANY kringlecon.com

57 behave the same – we see the usage information for ping. It's the same output we would see if we called ping without any arguments. One of the pages that Minty linked us to said that we can use the

dig +noall +answer ANY kringlecon.com

58 operator in Powershell to call other commands. Let's try it:

dig +noall +answer ANY kringlecon.com

2

It's a bit hard to see in the output, but we have a different line from the time before:

dig +noall +answer ANY kringlecon.com

63. This would be the output from our

dig +noall +answer ANY kringlecon.com

64 command.

At this point, we can exit the Powershell menu and run our own commands. Now we can dump the SQLite database, using the tips in the second link that Minty provided:

dig +noall +answer ANY kringlecon.com

3

Success! But it's hard to find Chan in all of that. Let's see if we can pass our output to the

dig +noall +answer ANY kringlecon.com

65 command, returning only lines that contain "Chan."

dig +noall +answer ANY kringlecon.com

4

Great. We now have one final hurdle – we need to call

dig +noall +answer ANY kringlecon.com

66 and answer the question. The same technique works there too:

dig +noall +answer ANY kringlecon.com

5

Answer:

Scott

This was classic command injection. There were a few other techniques that could've worked here, including using a semicolon instead of the ampersand (e.g.

dig +noall +answer ANY kringlecon.com

67).

We also discovered that the

dig +noall +answer ANY kringlecon.com

68 script had an unlisted option:

dig +noall +answer ANY kringlecon.com

6

Hitting option 9 drops us into a Powershell shell:

dig +noall +answer ANY kringlecon.com

7

Summary

The onboarding Powershell script was vulnerable to command injection. By running a command to dump the database, we found our guy, and were able to successfully call

dig +noall +answer ANY kringlecon.com

66. Furthermore, by inspecting the Powershell source code, we discovered a hidden backdoor in the menu.

Vim ForensicELFification

Goal

Find the first name of the elf of whom a love poem was written.

Background

  • Elf Chat Tangle Coalbox helps us by saying:
    Hi, I'm Tangle Coalbox.

Any chance you can help me with an investigation?

Elf Resources assigned me to look into a case, but it seems to require digital forensic skills.

Do you know anything about Linux terminal editors and digital traces they leave behind?

Apparently editors can leave traces of data behind, but where and how escapes me!

Badge Hint

Tangle also suggests the following site: Forensic Relevance of Vim Artifacts

Relevant KringleCon Videos None

Intro

When we open the terminal, we see:

dig +noall +answer ANY kringlecon.com

8

Solution

This one seems pretty straightforward. We have a single hint, and the hint only discusses the importance of the

dig +noall +answer ANY kringlecon.com

70 file. Let's take a look at that, but before we do anything, we want to do two things: Look at the metadata, and copy the file so that we don't accidentally modify it (by opening vim, say):

dig +noall +answer ANY kringlecon.com

9

To start, we need to figure out what love poem was written. The "Forensic Relevance of Vim Artifacts" web page has this to say:

File marks are among the last items in most .viminfo files and essentially consist of a list of files that have been opened with Vim. A ‘mark’ allows a user to record their location in a file they were editing, like a bookmark of sorts, which they can jump back to. On Linux systems, the “History of marks within files” section of .viminfo records the last 20 files that were opened using the Vim editor, along with their file path (relative to the user) and epoch timestamp.

As we view the

dig +noall +answer ANY kringlecon.com

71 file, it's fairly obvious that only one file was recently opened:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

0

Opening up

dig +noall +answer ANY kringlecon.com

72:

Once upon a sleigh so weary, Morcel scrubbed the grime so dreary, Shining many a beautiful sleighbell bearing cheer and sound so pure– There he cleaned them, nearly napping, suddenly there came a tapping, As of someone gently rapping, rapping at the sleigh house door. "'Tis some caroler," he muttered, "tapping at my sleigh house door– Only this and nothing more."

Then, continued with more vigor, came the sound he didn't figure, Could belong to one so lovely, walking 'bout the North Pole grounds. But the truth is, she WAS knocking, 'cause with him she would be talking, Off with fingers interlocking, strolling out with love newfound? Gazing into eyes so deeply, caring not who sees their rounds. Oh, 'twould make his heart resound!

Hurried, he, to greet the maiden, dropping rag and brush - unlaiden. Floating over, more than walking, moving toward the sound still knocking, Pausing at the elf-length mirror, checked himself to study clearer, Fixing hair and looking nearer, what a hunky elf - not shocking! Peering through the peephole smiling, reaching forward and unlocking: NEVERMORE in tinsel stocking!

Greeting her with smile dashing, pearly-white incisors flashing, Telling jokes to keep her laughing, soaring high upon the tidings, Of good fortune fates had borne him. Offered her his dexter forelimb, Never was his future less dim! Should he now consider gliding– No - they shouldn't but consider taking flight in sleigh and riding Up above the Pole abiding?

Smile, she did, when he suggested that their future surely rested, Up in flight above their cohort flying high like ne'er before! So he harnessed two young reindeer, bold and fresh and bearing no fear. In they jumped and seated so near, off they flew - broke through the door! Up and up climbed team and humor, Morcel being so adored, By his lovely NEVERMORE!

-Morcel Nougat

dig +noall +answer ANY kringlecon.com

73 seems like an odd name for an elf, and submitting this to

dig +noall +answer ANY kringlecon.com

66 yields:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

1

Returning to our

dig +noall +answer ANY kringlecon.com

70 file, we see:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

2

It seems like our elf did a find-and-replace on "Elinore," replacing all instances with "NEVERMORE."

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

3

Answer:

Elinore

We actually see a bit more history in the

dig +noall +answer ANY kringlecon.com

70 file:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

4

We can use

dig +noall +answer ANY kringlecon.com

77 to reverse some of these changes. Though, if we replace "tenor" with "sound," to undo the earliest change, we have no way of knowing which instances of "tenor" were there originally:

dig +noall +answer ANY kringlecon.com

78

And we recover the following poem:

Once upon a sleigh so weary, Morcel scrubbed the grime so dreary, Shining many a beautiful sleighbell bearing cheer and sound so pure– There he cleaned them, nearly napping, suddenly there came a tapping, As of someone gently rapping, rapping at the sleigh house door. "'Tis some caroler," he muttered, "tapping at my sleigh house door– Only this and nothing more."

Then, continued with more vigor, came the sound he didn't figure, Could belong to one so lovely, walking 'bout the North Pole grounds. But the truth is, she WAS knocking, 'cause with him she would be talking, Off with fingers interlocking, strolling out with love newfound? Gazing into eyes so deeply, caring not who sees their rounds. Oh, 'twould make his heart resound!

Hurried, he, to greet the maiden, dropping rag and brush - unlaiden. Floating over, more than walking, moving toward the sound still knocking, Pausing at the elf-length mirror, checked himself to study clearer, Fixing hair and studied nearer, what a hunky elf - not shocking! Peering through the peephole smiling, reaching forward and unlocking: Elinore in tinsel stocking!

Greeting her with smile dashing, pearly-white incisors flashing, Telling jokes to keep her laughing, soaring high upon the tidings, Of good fortune God had borne him. Offered her his dexter forelimb, Never was his future less dim! Should he now consider gliding– No - they shouldn't but consider taking flight in sleigh and riding Up above the Pole abiding?

Smile, she did, when he suggested that their future surely rested, Up in flight above their cohort flying high like ne'er before! So he harnessed two young reindeer, bold and fresh and bearing no fear. In they jumped and seated so near, off they flew - broke through the door! Up and up climbed team and humor, Morcel being so adored, By his lovely Elinore!

-Morcel Nougat

Summary

For this terminal, the hint was a big help. By looking at the

dig +noall +answer ANY kringlecon.com

70 file, we could reconstruct the changes made to the file, and learned that someone had replaced Elinore's name with NEVERMORE.

Samba Mucking Report

Goal

Complete this challenge by uploading the elf's report.txt file to the samba share at

dig +noall +answer ANY kringlecon.com

80.

Background

  • Elf Chat Wunorse tells us:
    What was that password?

Golly, passwords may be the end of all of us. Good guys can't remember them, and bad guess can guess them!

I've got to upload my chore report to my manager's inbox, but I can't remember my password.

Still, with all the automated tasks we use, I'll bet there's a way to find it in memory…

Badge Hint

Talking to Wunorse unlocks the following hint in our badge: Keeping Command Line Passwords Out of PS

Relevant KringleCon Videos None

Intro

Opening the terminal, we're greeted with:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

5

Solution

The hint links us to a page that discusses risks when passwords are passed on the command line, such as being able to view it with the process status command

dig +noall +answer ANY kringlecon.com

81. Let's try it:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

6

Not a whole lot of information. By default,

dig +noall +answer ANY kringlecon.com

81 only shows us a couple of fields, and only for processes we own (and our associated with our current terminal). We can read

dig +noall +answer ANY kringlecon.com

81's manual page with

dig +noall +answer ANY kringlecon.com

84, which has the following snippet:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

7

Let's try it:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

8

That looks better. We can see there's a

dig +noall +answer ANY kringlecon.com

85 process, and a

dig +noall +answer ANY kringlecon.com

86 process. The

dig +noall +answer ANY kringlecon.com

87 process is particularly interesting, as it seems to have a bunch of command-line arguments. However, by default,

dig +noall +answer ANY kringlecon.com

81 truncates them to the width of our terminal. Simple solution: zoom out our browser window.

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

9

The end of the command is

dig +noall +answer ANY kringlecon.com

89. A less hacky solution is to use more

dig +noall +answer ANY kringlecon.com

81 arguments to see the entire command:

OUTPUT MODIFIERS … –cols n Set screen width.

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

0

At this point, we suspect that "directreindeerflatterystable" is our password. Now we need to figure out how to copy it to the

dig +noall +answer ANY kringlecon.com

80 SMB share. Some Googling points us to the

dig +noall +answer ANY kringlecon.com

92 command:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

1

dig +noall +answer ANY kringlecon.com

92 has a lot of options, but as we parse the usage information, it seems like the snippet recoverd from the end of

dig +noall +answer ANY kringlecon.com

85 should just work:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

2

Uploading the report is as simple as:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

3

Once we do so, the following happens:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

4

Summary

We ran

dig +noall +answer ANY kringlecon.com

81, with some extra arguments to see all of the command-line arguments, and recovered the username and password for the SMB share. We then copied the report to the share with

dig +noall +answer ANY kringlecon.com

92.

HTTP2 CURLing Master

Goal

Complete this challenge by submitting the right HTTP request to the server at http://localhost:8080/ to get the candy striper started again.

Background

  • Elf Chat Holly has the following plight:
    Oh that Bushy!

Sorry to vent, but that brother of mine did something strange.

The trigger to restart the Candy Striper is apparently an arcane HTTP call or 2.

I sometimes wonder if all IT folk do strange things with their home networks…

Badge Hint

Holly links us to: HTTP/2.0 Basics

Relevant KringleCon Videos

Intro

Once we open the terminal, we see a curling stone and the following message:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

5

Solution

The terminal tells us to check out

dig +noall +answer ANY kringlecon.com

97, so we do that. The following comment catches our attention:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

6

The web server has HTTP2 enabled. We read the page that Holly linked us to, but what we're really looking for is how to use the

dig +noall +answer ANY kringlecon.com

98 command with HTTP2. Chris Elgee's video gives us the following command, which we've adapted for our server running on localhost, port 8080:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

7

Well, that didn't work. Let's try to find out more about the

dig +noall +answer ANY kringlecon.com

99 flag. We can run

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

00, and see:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

8

Let's try doing it without the HTTP/1.1 upgrade:

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

9

Ok! Now, instead of sending an empty GET, we need to send a POST with the right paramter. Once again, we'll return to the help output:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
0

Easy enough:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
1

Alternative solution

This system had some interesting commands in the bash history:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
2

Summary

We found a comment from Bushy in the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

01 config, which told us that HTTP2 was enabled on this system. Using a combination of Chris Elgee's talk and the curl help output, we figured out the correct parameters to have curl be able to send the request as HTTP2 (without trying to HTTP/1.1 and doing an upgrade to HTTP2 first). Then, the output from the page told us that we needed to submit a POST request, with

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

02.

Windows Yule Log Analysis

Goal

Submit the compromised webmail username to runtoanswer to complete this challenge.

Background

  • Elf Chat Pepper Minstix tells us:
    Have you heard of password spraying? It seems we've been victim.

We fear that they were successful in accessing one of our Elf Web Access accounts, but we don't know which one.

Parsing through .evtx files can be tricky, but there's a Python script that can help you convert it into XML for easier grep'ing.

Badge Hint

Pepper promptly points password penetration people to Password Spraying.

Relevant KringleCon Videos

Intro

When we start the Cranberry Pi, we get the following message:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
3

Checking our home directory, we see:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
4

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

03 must be the Python script Pepper was referring to, for converting

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

04 to XML.

Solution

First, we figure out how to run

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

03:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
5

Next, we'll save the XML version to a file, so we're not waiting on the Python script to re-parse the events each time.

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
6

At this point, we follow along in Beau's video. We learn that password spraying involves trying a single password across a large number of accounts. That way, account lockout polices don't trigger. He also mentions that a good way to try this is via e-mail servers like OWA, using his tool, MailSniper. Given that Pepper's hint is about MailSniper, we suspect that this is likely the vector being used.

Taking a closer look at our logs, we see events such as:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
7

Let's start by seeing which systems we have log data from. To do this, we'll use the

dig +noall +answer ANY kringlecon.com

65 command, to only return lines from the file which match our search term, and then we'll use the pipe (

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

  1. operator to pass those lines to

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

08. Finally, we'll pass the sorted lines to the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

09 ("unique") command, which will only print a line if it's different from the line above it.

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

08 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

09 are often used together in this way, since

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

09 only compares the line to the line above it when deciding whether or not to print it.

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
8

We only have logs from a single system, which we suspect to be an Exchange Server 2016 from its hostname. Let's see what events we have:

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
9

A bit of research gives us names to go with these EventIDs:

Event ID Event Name 4608 Windows is starting up 4624 An account was successfully logged on 4625 An account failed to log on 4647 User initiated logoff 4688 A new process has been created 4724 An attempt was made to reset an accounts password 4738 A user account was changed 4768 A Kerberos authentication ticket (TGT) was requested 4769 A Kerberos service ticket was requested 4776 The domain controller attempted to validate the credentials for an account 4799 A security-enabled local group membership was enumerated 4826 Boot Configuration Data loaded 4902 The Per-user audit policy table was created 4904 An attempt was made to register a security event source 5024 The Windows Firewall Service has started successfully 5033 The Windows Firewall Driver has started successfully 5059 Key migration operation

4624 and 4625 seem interesting. Let's update our previous command to include the number of occurences of each event by using

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

13:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

0

So, we've had 756 accounts successful logon attempts, and 212 failed ones.

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

1

At this point, there's a few ways we can proceed to analyze the logs. However, parsing XML data becomes tricky with the standard *NIX text-processing tools (

dig +noall +answer ANY kringlecon.com

65,

dig +noall +answer ANY kringlecon.com

77,

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

16, etc.). Instead, we'll write up a Python script:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

2

When we run the script, we get the authentication result, and the username. The last lines printed are along the lines of:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

3

We can use

dig +noall +answer ANY kringlecon.com

65 to ignore the mailbox. This time, we'll use the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

18 flag:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

19

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

4

This does look like a password spraying attack. We see a large number of failures, going alphabetically. Interestingly, it seems like SugarPlum Mary's account name is misspelled, leading more credence to the theory that the attacker is going off of a list of usernames.

After the failures, we see successful logins for Minty and Wunorse. To get a better sense of what's going on, we'll update our script to add the timestamp and IP address as well:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

5

It looks like the attack started at 12:54, with "test.user," then proceeded alphabetically, ending about 10 minutes later, at 13:05. All of those attempts came from the same IP address, 172.31.254.101.

As the attacker was trying passwords, they were able to successfully login as minty.candycane. After the attack ended, they logged in as minty.candycane again. Her account is the only account from that IP address that had a successful login.

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

6

Silly Minty, indeed. If only she had listened to Beau's talk…

Answer:

minty.candycane

Summary

Using the provided script, we converted the event logs to XML. Using basic \*NIX text-processing tools, we got an overview of the logs, then wrote a Python script to print out the relevant details. The password spraying attack was easy to spot, and all the attempts came from a single IP address. Only one user, minty.candycane, had a successful login from that IP.

Git Dev Ops Fail

Goal

Find Sparkle's password, then run the runtoanswer tool.

Background

  • Elf Chat Sparkle Redberry asks us to help her by saying:
    Ugh, can you believe that Elf Resources is poking around? Something about sensitive info in my git repo.

I mean, I may have uploaded something sensitive earlier, but it's no big deal. I overwrote it!

Care to check my Cranberry Pi terminal and prove me right?

Badge Hint

To help us, Sparkle provides two links: Finding Passwords in Git and Git Cheat Sheet.

Relevant KringleCon Videos Brian Hostetler, Buried Secrets: Digging Deep Through Cloud Repositories seems relevant, but it relies on using tools to search for secrets; something we can't easily do on the terminal.

Intro

Once we connect:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

7

Solution

First, we see what we're working with:

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

8

kcconfmgmt is a git repo, and we need to find some credentials in the history. The Git Cheat Sheet gives us the following command to search commits:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

20

#!/usr/bin/env python3 import asyncio import simplejson as json import time import websockets async def hello():

async with websockets.connect('wss://api.kringlecon.com/ws') as websocket:
    # The initial connect message
    await websocket.send('{"type":"WS_CONNECTED","session":null,"protocol":"43ae08fd-9cf2-4f54-a6a6-8454aef59581"}')
    # Wait for OHHIMARK
    while True:
        response = json.loads(await websocket.recv())
        if response['type'] == 'WS_OHHIMARK':
            break
    # Send the login info
    await websocket.send('{"type":"WS_LOGIN","usernameOrEmail":"VG","password":"3j6QMM3grTYYp7jWkie&f"}')
    # Print out everything we get back
    while True:
        response = json.loads(await websocket.recv())
        print(response)
asyncio.get_event_loop().run_until_complete(hello())

9

To view the changes, the cheat sheet suggests the following command:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

0

We see that in

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

21, the credentials were sredberry and "twinkletwinkletwinkle":

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

1

Answer:

twinkletwinkletwinkle

Summary

We got fairly lucky on this one. We searched commits for "password," and then viewed the details of an interesting commit.

Python Escape from LA

Goal

To complete this challenge, escape Python and run ./i_escaped

Background

  • Elf Chat SugarPlum Mary has a problem
    I'm glad you're here; my terminal is trapped inside a python! Or maybe my python is trapped inside a terminal?

Can you please help me by escaping from the Python interpreter?

Badge Hint

SugarPlum's advice is to check out Mark Baggett's talk upstairs.

Relevant KringleCon Videos

Intro

Launching this terminal, we see something a bit different:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

2

Solution

We need to run

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

22, either from Python, or after we've escaped. A simple way to exit Python is to call

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

23:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

3

Foiled. Watching Mark's talk, we see similarities with using

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

24 to filter prohibited words. Mark suggests checking to see if

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

25 is available:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

4

Next, let's try

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

26:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

5

That's promising. We try what Mark suggests using

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

27:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

6

Once we've escaped, we can see how this challenge was setup:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

7

Summary

We basically followed Mark's talk directly.

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

28 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

29 was blocked, but

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

27 was available. We called

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

22 directly from Python, without ever actually escaping.

The GDB Sleighbell Lottery

Goal

Complete this challenge by winning the sleighbell lottery for Shinny Upatree.

Background

  • Elf Chat Shinny is desperate to win the lottery:
    Hey! Mind giving ole' Shinny Upatree some help? There's a contest I HAVE to win.

As long as no one else wins first, I can just keep trying to win the Sleigh Bell Lotto, but this could take forever!

I'll bet the GNU Debugger can help us. With the PEDA modules installed, it can be prettier. I mean easier.

Badge Hint

Shinny recommends the SANS blog post Using gdb to Call Random Functions!

Relevant KringleCon Videos None

Intro

The terminal greets us with:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

8

Solution

We start by investigating our surroundings:

C = [ { name: "size", size: 4 }, { name: "legs", size: 8 }, { name: "hue", size: 8 }, { name: "torso", size: 8 }, { name: "head", size: 8 }, { name: "saturation", size: 4 }, { name: "mouth", size: 8 }, { name: "eyes", size: 8 }, { name: "brightness", size: 4 }];

9

We start following along with the blog post. We'll start with

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

32 (display name list), and as the post tells us to focus on symbol types 'T' (text section symbols):

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
0

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

33 looks promising. Let's see if we can use

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

34 to call that:

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
1

Summary

For this one, we followed the SANS blog post from our badge hint almost verbatim, and were able to directly call the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

33 function.

Objectives

Orientation Challenge

Goal

What phrase is revealed when you answer all of the questions at the KringleCon Holiday Hack History kiosk inside the castle?

Background

  • Terminal Challenge For hints on achieving this objective, please visit Bushy Evergreen and help him with the Essential Editor Skills Cranberry Pi terminal challenge.
  • Badge Hint Once we solve the Essential Editor Skills challenge, Bushy tells us to check out Past Holiday Hack Challenges.
  • Relevant KringleCon Videos

Solution

  1. START HERE

    To get into the Lobby, we have to, erm… get to talk to Santa, who is inside the gates. As we talk to him, he points us to a video we should start with:

    An error occurred while uploading 2712 là gì năm 2024
    Figure 15: Santa Says START HERE As we watch that video, Ed Skoudis tells us the following things, which answer our questions:

    1. In 2015, the Dosis siblings asked for help understanding what piece of their "Gnome in Your Home" toy? At 4 minutes, 29 seconds:
      …and they extracted THE FIRMWARE. They extracted the firmware from their Gnome in their Home and then they did some analysis on it.
    2. In 2015, the Dosis siblings disassembled the conspiracy dreamt up by which corporation? At 4:52: And it turns out that the company that sold the gnomes was called ATNAS Corporation, A-T-N-A-S.
    3. In 2016, participants were sent off on a problem-solving quest based on what artifact that Santa left? At 9:03: So that's Santa's Business Card. The whole thing starts with the BUSINESS CARD. Because that's all that's left among all of the needles that are dropped from the tree right next to Santa's bag. Is that Santa's business card.
    4. In 2016, Linux terminals at the North Pole could be accessed with what kind of computer? At 16:26: Another really big hint for you is that Santa's elves provide hints, but you first need to solve some terminal challenges. So, the concept here is you go up to a terminal challenge, it's just a simple little CRANBERRY PIterminal. Wherever you see a cranberry pi on a terminal, click on that thing.
    5. In 2017, the North Pole was being bombarded by giant objects. What were they? At 9:19: In 2017, the Holiday Hack Challenge opens up with GIANT SNOWBALLS pouring down the mountain of the North Pole.
    6. In 2017, Sam the snowman needed help reassembling pages torn from what? At 9:54: You see, THE GREAT BOOK is this wonderful book that was shredded by an inter-dimensional tornado, and you have to fetch different pages of this book. Once we enter the correct answers, the screen changes:
      An error occurred while uploading 2712 là gì năm 2024
      Figure 16: Kringle History Kiosk Answer Happy Trails
  2. Open-Source Intel

    One of the coolest things about the Holiday Hack is that old versions remain up! Using the link that Bushy gave us, we can try past challenges, and read the official solutions and other winning entries. Year Challenge Winning Entries 2017 Challenge Answers 2016 Challenge Answers 2015 Challenge Answers

    1. In 2015, the Dosis siblings asked for help understanding what piece of their "Gnome in Your Home" toy? From reading the 2015 Challenge, we see: Now, Dear Reader, please help Jessica unwrap the secrets of the Gnome’s firmware by returning once again to the Dosis neighborhood. Find Jessica and she will provide you a copy of the Gnome’s firmware. Answer: Firmware
    2. In 2015, the Dosis siblings disassembled the conspiracy dreamt up by which corporation? From the 2015 Answers: Through the fine investigative work of over 500 officers and detectives here in this room, I am proud to announce that we have apprehended the mastermind behind the co-called “Gnome in Your Home” conspiracy. Miss Cindy Lou Who, age sixty-two, CEO of ATNAS Corporation, had planned a worldwide crime spree to destroy Christmas joy. Answer: ATNAS
    3. In 2016, participants were sent off on a problem-solving quest based on what artifact that Santa left? 2016 was called "Santa's Business Card," so that's a good guess. Reading the 2016 challenge: And that, Dear Reader, is where you get involved. Take a close look at Santa's Business card. Answer: Business card
    4. In 2016, Linux terminals at the North Pole could be accessed with what kind of computer? Searching the 2016 challenge: Now, Dear Reader, scurry around the North Pole and retrieve all of the computer parts to build yourself a Cranberry Pi. Answer: Cranberry Pi
    5. In 2017, the North Pole was being bombarded by giant objects. What were they? The 2017 challenge starts: If I live to be a hundred, I'll never be able to forget the giant snowball disaster going on right now! The North Pole itself is under siege as boulder-sized snowballs cascade down our mountain, leaving destruction and mayhem in their wake. Answer: Snowballs
    6. In 2017, Sam the snowman needed help reassembling pages torn from what? Reading further: And if the snowballs aren't bad enough, the North Pole was hit last week with the worst Inter-Dimensional Tornado ever known, scrambling things up here pretty badly. Why, that blasted tornado even shredded The Great Book!
What's that? You haven't heard of The Great Book? Why, it's a wonderful tome that describes the epic history of the elves. I gotta tell you, they revere that book, but now its pages are scattered all over the place! We need your help to find the missing seven pages of The Great Book so we can stitch this priceless relic back together. Answer: The Great Book

Directory Browsing

Goal

Background

  • Terminal Challenge For hints on achieving this objective, please visit Minty Candycane and help her with the The Name Game Cranberry Pi terminal challenge.
  • Badge Hint Once we solve the Name Game challenge, Minty tells us:
    Finding Browsable Directories: On a website, finding browsable directories is sometimes as simple as removing characters from the end of a URL.
Website Directory Browsing: Website Directory Browsing

Solution

As we interact with the website, we're told that we missed the Call for Papers for the conference! We also see that there are two webpages we can access:

https://cfp.kringlecastle.com/ https://cfp.kringlecastle.com/cfp/cfp.html

The hints tell us to remove some characters from the end of the URL, as to view a directory listing. We discover that https://cfp.kringlecastle.com/cfp/ has directory listings enabled, and we see another file in that directory:

An error occurred while uploading 2712 là gì năm 2024

Figure 17: Directory Listing

At this point, we just need to find the line with the talk we're looking for:

An error occurred while uploading 2712 là gì năm 2024

Figure 18: A Path in the Darkness?

John McClane

de Bruijn Sequences

Goal

When you break into the speaker unpreparedness room, what does Morcel Nougat say?

Background

  • Terminal Challenge For hints on achieving this objective, please visit Tangle Coalbox and help him with Lethal ForensicELFication Cranberry Pi terminal challenge.
  • Elf Chat Once we solve the ForensicELFication challenge, Tangle gives us the following hints: #+BEGIN_QUOTE Hey, thanks for the help with the investigation, gumshoe. Have you been able to solve the lock with the funny shapes? It reminds me of something called "de Bruijn Sequences." You can optimize the guesses because there is no start and stop – each new value is added to the end and the first is removed.
  • Badge Hint Opening a Ford Lock Code: Opening a Ford with a Robot and the de Bruijn Sequence de Bruijn Sequence Generator: de Bruijn sequence generator #+END_QUOTE As an aside, one of the authors of this report finds this upsetting given they own a Ford vehicle with one of those keypads… The other two are fine with it.

Solution

  1. de Bruijn Sequences The key point from Tangle Coalbox is the bit about there being no start and stop. The door passcode is checked for each sequence of shapes as they are entered and shift from right to left. After the first four shapes are entered, a new passcode can be checked by entering just one more shape and for each shape after that. A de Bruijn algorithm generates a sequence of characters from a given "alphabet" (\(k\)) and "length" (\(n\)) where each sub-sequence only appears once. For this challenge, we simply convert each shape to a number 0-3, and run it through a de Bruijn algorithm. Doing so greatly speeds up the number of buttons we would need to press if we were entering this by hand. Brute-forcing this would mean that we would need to hit up to \(256 x 4 = 1024\) buttons. However, the de Bruijn sequence is only of length 259 (it wraps around, as the last digit could be followed by the first 3 digits of the sequence). Using the de Bruijn sequence generator provided in the hint from Tangle, we generate a sequence of 4 possibilities (\(k=4\)) and of length 4 (\(n=4\)). This generates the following sequence: render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))
      return du.a.createElement("div", { className: "a-wild-missingno-appears" },  
                                  du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));  
    
    2 We then simply try the possibilities, and quickly find our answer:
    An error occurred while uploading 2712 là gì năm 2024
    Figure 19: de Bruijn sequences on the Door Lock
  2. Brute Force By using the Developer Tools dig +noall +answer ANY kringlecon.com 03 tab, we can see what's going on behind the scenes as we try a few codes in our browser:
    An error occurred while uploading 2712 là gì năm 2024
    Figure 20: Door Lock HTTP GET requests Chrome's Developer Tools have a handy feature of copying the request as a curl command. After we press square, circle, triangle, square, our network request looks something like the following in curl: render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))
      return du.a.createElement("div", { className: "a-wild-missingno-appears" },  
                                  du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));  
    
    3 This command outputs: kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"
  3. We see that the first line includes the URL, and most of the other lines are headers that Chrome was setting. To figure out the right code, we can just replace the kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all" 38 parameter in the URL, and loop over all \(4^4 = 256\) options. There's no real benefit to calculating and using a de Bruijn sequence here, as each command will send a complete 4-character combination. render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))
      return du.a.createElement("div", { className: "a-wild-missingno-appears" },  
                                  du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));  
    
    4 After a few seconds, we get our solution: render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))
      return du.a.createElement("div", { className: "a-wild-missingno-appears" },  
                                  du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));  
    
    5 Interestingly and somewhat expected, the straight brute force code worked on the 25th try, which was slower than de Bruijn solution.

\(\triangle \square \bigcirc \triangle \)

Data Repo Analysis

Background

  • Terminal Challenge For hints on achieving this objective, please visit Wunorse Openslae and help him with Stall Mucking Report Cranberry Pi terminal challenge.
  • Badge Hint We visit Wunorse, who tells us:
    Brian Hostetler is giving a great Trufflehog talk upstairs.

Solution

When we pull up the Git repository, we find a project called "santas_castle_automation." Our first hurdle is retrieving the encrypted ZIP file. The GitLab site has a "Find File" button on the right side of the page. Searching for

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

39 yields:

An error occurred while uploading 2712 là gì năm 2024

Figure 21: zip paths in santas_castle_automation GitLab

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

40 catches our attention, so we download that from the website. Is this the encrypted ZIP file which we seek? Trying to open it prompts us for a password, so it seems likely that we've found it. Viewing the history and the commit where this file was added also reveals the following comment:

An error occurred while uploading 2712 là gì năm 2024

Figure 22: Shinny's comment on ventilation_diagram.zip

As we skim over the README that's displayed as we scroll down, we see the following message from Shinny:

We all get what we git, then we git what we've got. When we're full of old pulls, then we're holding a lot. Do you wonder what happens to things that we thought, Were too private then trampled with things that were not?

I assume that our secrets are gone from the cloud. They still sit here in local reposit'ries' shroud, But I heard that old Redberry was rather wowed, When she found out her keys were exposed - wasn't proud.

So when I found that I had thown creds with a push, Pretty sure I did stomp them with clean files - smoosh! If you find an old password 'neath folder or bush, Would you kindly play nice and say nothing - just shush?"

This, combined with the hint, strongly suggest that there are some secrets hidden in this repository. We've never tried Trufflehog before. Following along in Brian's video, we can try the command from the .

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
6

Interesting… some private SSH keys. The top commit catches our eye, as the message is "cleaning files." Could this be what Shinny was talking about, when he said "So when I found that I had thown creds with a push, Pretty sure I did stomp them with clean files - smoosh!?"

No passwords, though. The video continues to mention the second command from the README, so let's try that. The README states that the first command we ran cuts down on the noise, but as we haven't found the password yet, we'll expand the search:

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
7

This finds a lot of hits, but the second from the last commit catches our eye. The filepath is

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

41, and there's a line:

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
8

Trying to open the ZIP file again, we enter that password and discover maps of the ventilation system!

Yippee-ki-yay

AD Privilege Discovery

Goal

Using the data set contained in this SANS Slingshot Linux image, find a reliable path from a Kerberoastable user to the Domain Admins group. What’s the user’s logon name? Remember to avoid RDP as a control path as it depends on separate local privilege escalation flaws.

Background

  • Terminal Challenge For hints on achieving this objective, please visit Holly Evergreen and help her with the CURLing Master Cranberry Pi terminal challenge.
  • Badge Hint

Solution

To start, we download and run the VM.

On the social medias, we read reports of people having issue opening this VM. Some people suggested changing the architecture to 64-bit, or using VMware instead.

When the VM launches, we're in a Slingshot Linux instance. We notice a shortcut to Bloodhound on the desktop:

An error occurred while uploading 2712 là gì năm 2024

Figure 23: VM Launch Screen

When we launch Bloodhound, we open up a dataset for

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

42. Because Bloodhound is already installed, and the data is pre-imported for us, we can skip ahead in the video that Holly linked us to (around the 4:27 mark). We learn that the quickest way to get started is to explore the Queries tab. Our task is to find a path from a Kerberoastable user to the Domain Admins group. As we scroll down the Pre-Built Analytics Queries list, we see that there's a query for almost exactly that:

An error occurred while uploading 2712 là gì năm 2024

Figure 24: Shortest Paths to Domain Admins from Kerberoastable Users

We see a few options, and a few paths. Our objective tells us one further thing: "Remember to avoid RDP as a control path as it depends on separate local privilege escalation flaws."

As we explore Bloodhound's interface, we find an Edge Filter option, and we can disable "CanRDP."

An error occurred while uploading 2712 là gì năm 2024

Figure 25: Edge Filtering in Bloodhound

This provides us with the following graph:

An error occurred while uploading 2712 là gì năm 2024

Figure 26: Bloodhound Result

It looks like our answer is Leanne Dubej's user:

[email protected]

But what does this graph mean?

  1. Leanne (LDUBEJ00320) is a member of the IT_00332 Active Directory group.
  2. That group has Administrator privileges on the COMP00185 system.
  3. Jena (JETAK00084) has an active session on the COMP00185 system.
  4. Jena is a Domain Administrator.

Administrators have unfettered access to a system. One of their superpowers is to be able to steal access tokens from other users on that system, and impersonate them. Because Jena has an active session on a system that Leanne is an admin on, Leanne could steal Jena's token, and use it to perform actions as a domain admin.

The other remaining question is what exactly is meant by a "Kerberoastable" user? Kerberoast is "a series of tools for attacking MS Kerberos implementations." If an account has a Service Principal Name (SPN) associated with it, it's vulnerable to offline cracking attacks. Kerberoastable users are simply users that have SPNs associated with their accounts. In our case, Leanne has an SPN, and if we use Kerberoast to access her account, Bloodhound has found a path for us to elevate all the way to Domain Admin.

Badge Manipulation

Goal

Bypass the authentication mechanism associated with the room near Pepper Minstix. A sample employee badge is available. What is the access control number revealed by the door authentication panel?

Background

  • Terminal Challenge For hints on achieving this objective, please visit Pepper Minstix and help her with the Yule Log Analysis Cranberry Pi terminal challenge.
  • Elf Chat After we identify the targeted account in the Yule Log Analysis terminal, Pepper points us to the following resources:
    All of the Kringle Castle employees have these cool cards with QR codes on them that give us access to restricted areas.

Unfortunately, the badge-scan-o-matic said my account was disabled when I tried scanning my badge.

I really needed access so I tried scanning several QR codes I made from my phone but the scanner kept saying "User Not Found".

I researched a SQL database error from scanning a QR code with special characters in it and found it may contain an injection vulnerability.

I was going to try some variations I found on but decided to stop so I don't tick-off Alabaster.

  • Badge Hint

Solution

Clicking on the Scan-O-Matic brings up the following interface:

An error occurred while uploading 2712 là gì năm 2024

Figure 27: Scan-O-Matic in action

As we interact with the scanner, we see there are two things we can do: scan our fingerprint, or plug in a USB 3.0 drive. Scanning our fingerprint processes the still from the video camera, while the USB drive brings up a file selection window for a file upload.

The objective also gave us a sample employee badge:

An error occurred while uploading 2712 là gì năm 2024

Figure 28: If found, please return to Alabaster

First thing we try is uploading the badge via the file upload functionality. No dice:

An error occurred while uploading 2712 là gì năm 2024

Figure 29: Error 1: PNG files only

That's fine. We can do some file conversion, either by "Save As…" or from the command line:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

43. Now we're uploading the right format:

An error occurred while uploading 2712 là gì năm 2024

Figure 30: Error 2: Authorized User Account Has Been Disabled!

Perhaps Alabaster's access was revoked when he reported his badge as stolen. These elves are really on top of security…

Pepper's hints are pointing us towards SQL injection via the QR code, so let's start by taking a closer look at the QR code on Alabaster's badge. The Creating QR barcodes website she provided also has a scan function (as do many cellphone camera apps). We ended up using a different site, as we can just link to Alabaster's badge URL, and we don't have to use our webcam. The results are fairly cryptic, but they do seem to be plain text:

render() { const {dna: e, version: t} = this.props; if (au.a.validateSequence(e))

  return du.a.createElement("div", { className: "a-wild-missingno-appears" }, 
                              du.a.createElement("img", { src: "images/egg.png", alt: ":)" }));
9

As we turn our attention to the link she mentioned, we see this interesting looking snippet:

An error occurred while uploading 2712 là gì năm 2024

Figure 31: Auth Bypass

We can use the Creating QR barcodes website to create a new QR code, with the snippet provided

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

44, and then save it (making sure to save it as a PNG). Now we can upload our new code to the Scan-O-Matic:

An error occurred while uploading 2712 là gì năm 2024

Figure 32: Error 2a: Authorized User Account Has Been Disabled!

Same error. But, this wasn't a total failure. We've confirmed that we can send arbitrary text as a QR code. Let's take a step back, and simplify our injection attempt. The OWASP webpage has several good examples, but let's just send the simplest case:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

45.

An error occurred while uploading 2712 là gì năm 2024

Figure 33: Error 3: Exception at line 96

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

0

The error is hard to read as it scrolls across, but we can use the

dig +noall +answer ANY kringlecon.com

03 Developer Tools tab to view the whole thing. Still, it's hard to parse, so we'll take a closer look. It's an error from the MariaDB (née MySQL) database server. We also see a code snippet from Scan-O-Matic:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

1

From this, we can figure out the database query was something like:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

2

The QR code seems to supply the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47 parameter (this is the only variable on that line; everything else is hard-coded). When we submitted a

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47 of just a single-quote, the SQL database server complained of a syntax error. Let's play around with this a little bit, to better understand what's going on. A good tool for this is sqltest.net. From the query, we know that we're searching the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

49 table. The query is requesting the fields

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

50,

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

51,

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

52 be returned, and it's filtering on the fields

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

53 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47. So we can mock up a simple example (in fact the example when we load sqltest.net already is pretty close, as it has

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

55,

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

50, and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

51).

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

3

We decided to make the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

53 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

52 fields integers because the query has

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

60. The lack of quotes tells us it's not a string.

We'll start by trying our query with the UID from Alabaster's badge:

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

61:

An error occurred while uploading 2712 là gì năm 2024

Figure 34: Sending Alabaster's badge to sqltest.net

We got our expected result, but Alabaster's not enabled. Now let's try sending a single quote, and see if we can duplicate the error message:

An error occurred while uploading 2712 là gì năm 2024

Figure 35: Sending a single quote to sqltest.net

We get the following error message, which matches almost exactly the error message we got from Scan-O-Matic: =You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' LIMIT 1' at line 2=. The cause of the error is that we've created a query with a string that doesn't close (there's no closing single-quote).

We've discovered a SQL injection! Now we need to exploit it to gain access to the door. We start by trying the following query:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

4

We're looking for an authorized user, whose uid is either empty or not empty. In other words, this should match everyone.

An error occurred while uploading 2712 là gì năm 2024

Figure 36: Matching anyone on sqltest.net

Well, no more error, but we still only get Alabaster's user. Even though our search should match everyone, the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

62 clause will only return one result, and just our luck, that one result is not enabled. No problem – we can just also require that the user be enabled:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

5

This query seems a bit repetitive, and it is, because we're limited in what queries we can build. What we're searching on is that a user must have an empty

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47 OR be enabled OR have an empty

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47. We're not sure if anyone has an empty

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47, but the user that's returned matches the other criteria: their account is enabled.

An error occurred while uploading 2712 là gì năm 2024

Figure 37: Requiring an enabled user on sqltest.net

We found a query which works in our little sandbox, but how do we make it work on Scan-O-Matic? We start by comparing the queries:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

6

The UID from the QR code gets put in between single quotes, which is why our query was rather odd. We needed to construct it in such a way so that it would both start and end with a string.

So, if we just set the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

47 parameter to

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

67, we should be able to run this query on Scan-O-Matic:

An error occurred while uploading 2712 là gì năm 2024

Figure 38: Access Granted!

User Access Granted - Control number 19880715

Careers

Goal

Santa uses an Elf Resources website to look for talented information security professionals. Gain access to the website and fetch the document

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

68. Which terrorist organization is secretly supported by the job applicant whose name begins with "K."

Background

  • Terminal Challenge For hints on achieving this objective, please visit Sparkle Redberry and help her with the Dev Ops Fail Cranberry Pi terminal challenge.
  • Elf Chat Sparkle helpfully points out that her OpSec isn't as bad as Tangle's, by saying:
    I wonder if Tangle Coalbox has taken a good look at his own employee import system.

It takes CSV files as imports. That certainly can expedite a process, but there's danger to be had.

I'll bet, with the right malicious input, some naughty actor could exploit a vulnerability there.

I'm sure the danger can be mitigated. OWASP has guidance on what not to allow with such uploads.

Badge Hint

Sparkle also points us to the OWASP CSV Injection Page, and tells us: Somehow Brian Hostetler is giving a talk on CSV injection WHILE he's giving a talk on Trufflehog. Whatta' guy!

Relevant KringleCon Videos

Solution

Bringing up the webpage, we're presented with a simple form:

An error occurred while uploading 2712 là gì năm 2024

Figure 39: Elf Resources website home

Filling in the form, the page forces us to attach a file before submitting. If we do that, we receive the following message:

An error occurred while uploading 2712 là gì năm 2024

Figure 40: Elf Resources submission message

Both the objective and the submission message told us the file we need to retrieve,

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

68. We next simply tried https://careers.kringlecastle.com/candidate_evaluation.docx, and got the following:

An error occurred while uploading 2712 là gì năm 2024

Figure 41: Elf Resources 404

What a helpful error message! Unfortunately, trying https://careers.kringlecastle.com/public/candidate_evaluation.docx similarly doesn't work. But now, we know two critical pieces of information:

  1. We're trying to access kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all" 68
  2. Files in kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all" 71 are publicly accessible via the web server.

Time to turn our attention to the hints, and see how we can get our target file into the public directory. Brian's talk gives some guidance on how to build a CSV to execute an arbitrary command. We choose a name designed to not conflict with other KringleCon attendees.

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

7

Uploading this file, we then try to access https://careers.kringlecastle.com/public/ZXNuZXRfc2VjdXJpdHkK.docx. After ~10-15 seconds, we download a Word Doc. The download evaluates 4 elves, including Krampus:

An error occurred while uploading 2712 là gì năm 2024

Figure 42: Krampus Evaluation

The document reveals that Krampus is connected to cyber terrorist organization Fancy Beaver (a play on the Fancy Bear APT group).

Answer:

Fancy Beaver

PCAPalyzer

Goal

Santa has introduced a web-based packet capture and analysis tool at https://packalyzer.kringlecastle.com to support the elves and their information security work. Using the system, access and decrypt HTTP/2 network activity. What is the name of the song described in the document sent from Holly Evergreen to Alabaster Snowball?

Background

  • Terminal Challenge For hints on achieving this objective, please visit SugarPlum Mary and help her with the Python Escape from LA Cranberry Pi terminal challenge.
  • Elf Chat After we help SugarPlum escape, she tells us:
    Yay, you did it! You escaped from the Python!

As a token of my gratitude, I would like to share a rumor I had heard about Santa's new web-based packet analyzer - Packalyzer.

Another elf told me that Packalyzer was rushed and deployed with development code sitting in the web root.

Apparently, he found this out by looking at HTML comments left behind and was able to grab the server-side source code.

There was suspicious-looking development code using environment variables to store SSL keys and open up directories.

This elf then told me that manipulating values in the URL gave back weird and descriptive errors.

I'm hoping these errors can't be used to compromise SSL on the website and steal logins.

On a tooootally unrelated note, have you seen the HTTP2 talk at at KringleCon by the Chrises? I never knew HTTP2 was so different!

  • Relevant KringleCon Videos

Solution Part 1: Downloading the SSL Key Logfile

A lot of hints on this one. We start by loading up Packalyzer, and trying to find the HTML comments. We have access to two pages initially, the home page, and the new user registration page. We can't find any hidden comments in either one, so we go ahead and register a new user, and then sign in with our new account.

At this point, the Packalyzer allows us to sniff 20 seconds of traffic, and then download the PCAP.

Once we're authenticated, we can find the following comment in the page source:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

8

https://packalyzer.kringlecastle.com/app.js doesn't work, but we also noticed some resources being loaded from https://packalyzer.kringlecastle.com/pub/, and we can recover the server-side source code of

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

72 from https://packalyzer.kringlecastle.com/pub/app.js

Folllowing SugarPlum's hints, we found the comment, and grabbed the server-side source code sitting in the web root. Now we need to identify the environment variables used to store SSL keys:

window.onload = function() { document.getElementById("top").style.visibility="hidden"; document.getElementById("bottom").style.visibility="hidden"; document.getElementById("arrow-up").style.visibility="hidden"; document.getElementById("arrow-down").style.visibility="hidden"; //next section depends on player state document.getElementById("mazeform").elements.namedItem("heading").value = "w"; document.getElementById("mazeform").elements.namedItem("mazex").value = "22"; document.getElementById("mazeform").elements.namedItem("mazey").value = "19"; document.getElementById("mazeform").elements.namedItem("mazef").value = "1"; document.getElementById("mazeform").elements.namedItem("locationkey").value = "07edf09b26a307b9fe4f40bedffe76ed"; document.getElementById("mazeform").elements.namedItem("resourceid").value = "inigomontoya"; document.getElementById("wallform").elements.namedItem("northwall").value = "True"; document.getElementById("wallform").elements.namedItem("southwall").value = "True"; document.getElementById("wallform").elements.namedItem("eastwall").value = "False"; document.getElementById("wallform").elements.namedItem("westwall").value = "False"; wallcheck(); //render correct walls once state is known };

9

Let's take this line by line. In the development copy we have,

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

73 is set to true.

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

74 uses some short-hand syntax, which could also be written as:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

00

Finally, once

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

74 is set, the comment tells us that it's used to view traffic. Our hints seem to point us to recovering this file, and then using it to decrypt the traffic. Perhaps the file was left over from development. We need to figure out what the environment variables

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

76 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

77 were set to.

The main logic of the file is the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

78 function. An annotated version is:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

01

Going through this, especially with an example, we can understand the logic. Sometimes it's useful to try running a command, and seeing what the output is. In cases like this, we pull up the Javascript console of our browser's developer tools again:

An error occurred while uploading 2712 là gì năm 2024

Figure 43: Testing JS code in our console

Our attention is drawn to how the code builds the filename:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

02

Again, we'll expand this logic out a bit:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

03

So, the first part of our path is upper-cased, and if an environment variable exists with that name, it attempts to use that as part of the path to our file. Let's try it. Searching for

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

79 pulls up some Node.js documentation:

An error occurred while uploading 2712 là gì năm 2024

Figure 44: process.env documentation

Let's try accessing the

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

80 environment variable:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

04

We received an error message, but one which discloses some information. Let's try to unpack this, given that we have the source for how the filename was built. First, let's identify exactly which part is our

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

80. We can check this on a Cranberry Pi terminal, as a point of comparison:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

05

Reading our error message carefully, we can identify all three variables that combined to form the filename:

Value Variable

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

82

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

83

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

84

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

85

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

86

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

87

At this point, we need to recover the environment variables

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

76 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

77, which are referenced in

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

90:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

06

From this, we can deduce that

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

76 is

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

92 and

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

77 is

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

94. We've already figured out

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

83, so our

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

74 would've been

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

97. We just need to figure out how to access that via the webserver. We've already noted that we can access files from https://packalyzer.kringlecastle.com/pub/, so let's get the full path of that by generating an error message for a non-existant file:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

07

Great! The files we're accessing are from

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

98, so

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

99 should be just as easy to access:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

08

Great! We've successfully downloaded the file.

Solution Part 2: Decrypting the Traffic

We've run through most of SugarPlum's hints in order to recover the SSL Key Logfile. As a reminder, she also told us:

I'm hoping these errors can't be used to compromise SSL on the website and steal logins. On a tooootally unrelated note, have you seen the HTTP2 talk at at KringleCon by the Chrises? I never knew HTTP2 was so different!

We already used Chris Elgee's video for the CURLing Master terminal, and it made no mention of using HTTP2 to compromise SSL. The other video is Chris Davis, HTTP/2: Decryption and Analysis in Wireshark, which sounds perfect.

The first part of the talk discusses how to create the SSL Key Logfile using curl and Chrome. This seems like what we just recovered from the system, only that it was generated server-side instead of client-side. The talk also mentions how we can use this file to decrypt the SSL traffic in Wireshark. In order to do that, we need a PCAP, though. Perhaps a new PCAP from the Packalyzer web interface?

The comment in the server-side source code warned us that the key log only stores a few minutes worth at a time. The server can't log keys ahead of time, so our workflow should be:

  1. Sniff traffic on Packalyzer, to generate a new PCAP.
  2. Download the SSL key logfile
  3. Download the capture
  4. Attempt to decrypt the SSL traffic in the capture with the key logfile.

For step 4, we just continue following along with Chris's video. First, we configure the Wireshark SSL protocol analyzer to use our freshly downloaded key logfile:

An error occurred while uploading 2712 là gì năm 2024

Figure 45: Configuring Wireshark SSL protocol analyzer

It worked! We can now see some HTTP2 traffic:

An error occurred while uploading 2712 là gì năm 2024

Figure 46: Wireshark HTTP2 overview

As a reminder, our goal is to steal logins, and ultimately access a document sent from Holly to Alabaster. To start, we'll filter out just HTTP2 traffic, using the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

00 display filter:

An error occurred while uploading 2712 là gì năm 2024

Figure 47: Wireshark with http2 filter

We immediately see a HTTP

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

01 request to

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

02, which seems promising. Chris's video has a very similar request, and he points out that to get the actual username and password, we need to look at a different frame in the packet capture. We'll combine two of Chris's example filters into

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

03, and then we can find some credentials:

An error occurred while uploading 2712 là gì năm 2024

Figure 48: Wireshark with http2 POST filter

We've found Pepper's credentials. Can we find anyone else's? To speed up this analysis a bit, we're going to add some custom fields to the Wireshark display. Either by right-clicking on the column headers and going to

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

04 or by going to

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

05 →

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

06 →

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

07. We'll add two custom columns for JSON keys and values:

An error occurred while uploading 2712 là gì năm 2024

Figure 49: Wireshark custom columns

Finally, we'll filter our PCAP to display frames which have a JSON key of "password":

An error occurred while uploading 2712 là gì năm 2024

Figure 50: Wireshark with json filter

Bingo!

Username Password pepper Shiz-Bamer_wabl182 alabaster Packer-p@re-turntable192

We've followed all the hints, but ultimately, we're looking for a document. The HTTP2 traffic we're seeing in this PCAP looks like the Packalyzer website itself, so we're presuming the credentials are for that. Since we know the document was sent to Alabaster, let's start with his credentials, and try logging into Packalyzer:

An error occurred while uploading 2712 là gì năm 2024

Figure 51: Successful login as Alabaster

Opening up the captures associated with Alabaster's account, we find the tantalizingly named

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

08. We'll grab it and open it up in Wireshark again. A good way to get a quick overview of a PCAP in Wireshark is to use

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

09 →

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

10:

An error occurred while uploading 2712 là gì năm 2024

Figure 52: Super secret protocol hierarchy

It looks like the only thing Wireshark found in this PCAP is SMTP (e-mail) traffic. Note that it's not listed as 100%, since some packets are simply TCP control packets. We'll filter on

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

11:

An error occurred while uploading 2712 là gì năm 2024

Figure 53: Super secret SMTP

We immediately see an e-mail from Holly to Alabaster. Looks like we're on the right track… Now we just need to find and extract the document. To get a better look at the data, we can right click on one of the frames, and select

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

12 →

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

13. A new window pops up:

An error occurred while uploading 2712 là gì năm 2024

Figure 54: Super secret e-mail

Holly says:

Hey alabaster, Santa said you needed help understanding musical notes for accessing the vault. He said your favorite key was D. Anyways, the following attachment should give you all the information you need about transposing music.

What follows is the attachment:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

09

We can see that the attachment is encoded as base64, so we can copy and paste the data, and then decode it with:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

10

The attachment is a PDF, so we'll rename it accordingly. Opening the document gives us our answer:

An error occurred while uploading 2712 là gì năm 2024

Figure 55: Super secret song

Answer:

Mary Had a Little Lamb

We also note that this document walks us through how to transcribe a song from one key to another.

Ransomware Recovery

Goal

Alabaster Snowball is in dire need of your help. Santa's file server has been hit with malware. Help Alabaster Snowball deal with the malware on Santa's server by completing several tasks.

Background

  • Location To access these challenges, you need to have gotten access to Santa's Secret Room, either by bypassing the QR code Scan-O-Matic, or by crawling through the vents.
  • Terminal Challenge For hints on achieving this objective, please visit Shinny Upatree and help him with the Sleigh Bell Lottery Cranberry Pi terminal challenge.
  • Badge Hint Once we help Shinny win the Sleigh Bell Lottery, he gives us several hints. As this grand challenge is really a multi-part exercise, we'll break it down by question.

Phase 1: Catch the Malware

  • Goal Assist Alabaster by building a Snort filter to identify the malware plaguing Santa's Castle.
  • Background In Santa's secret room, we find a few terminals and Alabaster Snowball. Alabaster asks us for help:
    Help, all of our computers have been encrypted by ransomware!

I came here to help but got locked in 'cause I dropped my "Alabaster Snowball" badge in a rush.

I started analyzing the ransomware on my host operating system, ran it by accident, and now my files are encrypted!

Unfortunately, the password database I keep on my computer was encrypted, so now I don't have access to any of our systems.

If only there were some way I could create some kind of traffic filter that could alert anytime ransomware was found! We launch the Snort Challenge terminal. Opening it up, we see the following message: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 11 Looking at ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 14, we see: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 12 To summarize, we need to edit ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 15 and add a rule to detect the malware, but not alert on legitimate traffic. To test our rule, we can run ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 16.

Solution

Let's start by taking a look at ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 17: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 13 No rules in there yet. Let's check out the DNS traffic and determine what we need to alert on. We're told that we also have a PCAP file with 30 seconds of traffic. For digging into the PCAP, we can get some hints from Mike Poor's KringleCon talk. One of the tools mentioned is ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 18, which we're told is on this system. The Snort system doesn't have manual pages installed, but if we run ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 19, we see some useful help output: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 14 Let's just try reading the PCAP, and see what we're working with: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 15 The output of the command is rather verbose, and looks like an intimidating wall of text. We see a number of DNS TXT queries ( ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

  1. and responses ( ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 21). At this point, we could use standard Linux tools (e.g. dig +noall +answer ANY kringlecon.com 65, ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 23, kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"
  2. to start analyzing the queries, but ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 18 can do some advanced analysis itself. The output format isn't the most helpful, so by consulting the tshark man page, we can create a command which only shows the DNS query name, and doesn't print DNS responses (which would cause each query to be printed twice): ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 16 To make it easier to see what's going on, we can take the above command and pipe it to sort, by appending ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 26. Some of the results are: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 17 It seems like we have two types of queries: HEX_DIGITS.suspicious_domain_name and RANDOM_WORDS.well_known_domain_name. Taking it a step further, we notice that the suspicious queries are of the form: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 18 A closer look at the domain names reveals something interesting… ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 27 is an anagram for ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 28 and ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 29 is an anagram for ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...
  3. What about the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 31 sequence? We tried decoding it as base64, but that didn't work. It turns out it's just hex-encoded: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 19 It seems something is querying ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 32. Certainly looks suspicious… We'll start by editing ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 17 with the following rule: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 20 Our task is to alert on the traffic, so we'll use the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 34 keyword. The traffic in the PCAP is destined to a DNS server on UDP port 53. However, the source IP, source port, and destination IP all seem random. So we'll use "any any" for the source IP and port, and "any 53" for the destination IP and port. The ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 35 characters configure our rule to alert on both the request and response. There are some trade-offs for alerting on the response (increased false-positive rate, but also an increased chance to detect compromised hosts). Finally, we're looking for our hex-encoded "wannacookie.min.ps1" string. Once we add this rule, we get the following message: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 21 ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 14 did give us a command line to test our rules, so we can try that: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 22 Oops. It seems like sids of at least 1,000,000 are reserved for local rules, so we'll use that. The Snort manual also tells us to use a revision number in our rule. ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 23 With this rule in place, we're told: ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 37 Answer: Snort is alerting on all ransomware and only the ransomware

    Refining the Snort rule

    Our rule works, but is not a great rule. Any UDP content that has that string anywhere in the packet will trigger the rule. DNS uses a special method to encode the query name on the wire. Each portion of the DNS name (the "labels"), are prefixed with the length of that label, with an empty label at the end. So, "www.es.net" would be encoded as ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

    1. We can rewrite a better rule as: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 24 We're also adding the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 39 option, to make our match case-insensitive.

Phase 2: Identify the Domain

  • Goal Using the Word docm file, identify the domain name that the malware communicates with.
  • Background
    • Elf Chat Checking back in with Alabster, he says:
      Thank you so much! Snort IDS is alerting on each new ransomware infection in our network.

Hey, you're pretty good at this security stuff. Could you help me further with what I suspect is a malicious Word document?

All the elves were emailed a cookie recipe right before all the infections. Take this document with a password of elves and find the domain it communicates with. Also, Shinny tells us: Have you heard that Kringle Castle was hit by a new ransomware called Wannacookie?

Several elves reported receiving a cookie recipe Word doc. When opened, a PowerShell screen flashed by and their files were encrypted.

Many elves were affected, so Alabaster went to go see if he could help out.

I hope Alabaster watched the PowerShell Malware talk at KringleCon before he tried analyzing Wannacookie on his computer.

Badge Hint

We have the following hints from Shinny and Alabaster: Whoa, Chris Davis' talk on PowerShell malware is crazy pants! You should check it out!

Word docm macros can be extracted using olevba. Perhaps we can use this to grab the ransomware source.

Relevant KringleCon Videos
  • Solution Downloading the document, we hit a snag in extracting it. It seems like ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 40 and Apple's Archive Viewer don't support the format. We end up using p7zip, which can successfully extract it with the password provided, and we find a Word docm file. This seems to be a macro-enabled document file. Learning from Alabaster's mistake, we're going to watch Chris's video first, and follow along. Chris's following tip seems especially relevant for Alabaster, in hindsight: Never run or analyze malware from your host or host environment After covering some basic Operational Security best practices, Chris starts talking about a malicious Word document, just like the one we were given. The first tool he uses is ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 41. Following along: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 25 ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 41 has identified some suspicious macros in our file. We can see that it's trying to run some commands with Powershell, but the commands are obfuscated. Following along in Chris's video, we see many similarities with his example and our chocolate chip cookie recipe. To deobfuscate this command, we'll remove the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 43 call (Invoke-Expression), and save the output to ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 44. We'll write this as a script, to make it a bit easier to read: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 26 Now we can run it, and verify that we have our file: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 27 Great! Now let's examine ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 44: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 28 Even after some cleanup, the code is hard to read, but we clearly see the domain: Answer: erohetfanu.com Why… that's one of the domains we found in our pre-conference recon! But what does it mean? ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 29 Well, if it isn't "hansgruber" backwards, and ROT-13 encoded! That solves one mystery that's been bugging us since before the conference even started!

Phase 3: Stop the Malware

  • Goal Identify a way to stop the malware in its tracks!
  • Background
    • Elf Chat Shinny told us:
      An elf I follow online said he analyzed Wannacookie and that it communicates over DNS. Alabaster says: Erohetfanu.com, I wonder what that means? Unfortunately, Snort alerts show multiple domains, so blocking that one won't be effective.

I remember another ransomware in recent history had a killswitch domain that, when registered, would prevent any further infections.

Perhaps there is a mechanism like that in this ransomware? Do some more analysis and see if you can find a fatal flaw and activate it!

Badge Hint

We have a couple of hints from Alabaster: I think I remember reading an article recently about Ransomware Kill Switchs. Wouldn't it be nice if our ransomware had one!

wannacookie.min.ps1? I wonder if there is a non-minified version? If so, it may be easier to read and give us more information and maybe source comments? The article tells us: By relying on a static, discoverable address, whoever found it—in this case MalwareTech—could just register the domain and trigger WannaCry's shutdown defense.

Solution

At the end of Phase 2, we recovered a snippet that does something over DNS: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 30 We see that the first DNS query is actually in the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 46 line itself: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 31 We expect this to return a number, as it's being convert to a 32-bit integer, as base 10. We recognize ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 47 from the PCAPs on the Snort system, and we already found that it's a hex-encoded "wannacookie.min.ps1". Let's see what's being sent over DNS: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 32 As expected, the first top-level query returned a number. Next, the script would start to loop over queries for ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 48, ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 49, up to the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 50. Let's see what those look like: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 33 Looks like more encoded content. We notice that the script was passing this output to a function, ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 51: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 34 It would stand to reason that this is once again hex-encoded, and ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 51 is short for "hex to ASCII." ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 35 We decoded it, and recovered Powershell code. This was expected, as ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 53 ( ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

  1. executes Powershell code. It seems as if the 64 queries are simply chunks of the same file. Let's see if we can recover it all: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 36 Inspecting the file, it looks like we've managed to download the entire file, just over DNS. Hans seems to have setup his DNS server to make life a bit harder for security researchers, as by default, the queries only work from Windows clients. Chris suggests modifying the attacker's code whenever possible, and not following his advice bit us. Many Linux DNS query tools default to using Extended DNS options (EDNS), which is needed to support DNSSEC. When querying from a tool such as ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 55, we needed to add the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 56 option in order to get a reply. Alabaster hints at there being a non-minified version of the file. ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 37 We successfully recovered a file, which is larger than the minified version. Let's start investigating it. There's a lot going on here, with several functions. We can infer a lot just from the function names, and what system calls the functions make: Function Name Purpose Notes Enc_Dec-File Encrypt/Decrypt file? H2B Hex to something ? A2H ASCII to Hex H2A Hex to ASCII Matches the dropper H2A B2H Something to Hex ? (Inverse of H2B?) ti_rox XOR This is "xor_it" backwards! B2G GZIP compress Calls GzipStream with Compress G2B GZIP decompress Calls GzipStream with Decompress Sha1 SHA1 Hash Calls SHA1 ComputeHash Pub_Key_Enc Encrypt with X509 Public Key Calls PublicKey Encrypt get_over_dns Download a file over DNS Matches code in the dropper wannacookie Main function? Calls most other functions Again, Chris suggests just adapting this code to investigate it, rather than trying to replicate it ourselves. Before we make any changes, though, we'll make sure to backup the original file. At the very bottom of the file, we see that the file calls ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 57. We can comment out that line, and now we can load the file without anything executing. We're also working in an isolated virtual machine, just in case we pull an Alabaster. Once the file is loaded, we'll start going through the logic of the ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 57 function, slowly enough so as to understand what each component does: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 38 However, very quickly we reach a line that's difficult to understand. It looks like it's doing a DNS query, but what it's actually querying is very difficult to parse. Tracing these parentheses is almost as difficult as in Lisp! Reading the line carefully, we see that it's doing two DNS TXT queries. One is trivial to rerun: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 39 Still obfuscated. But what is the domain it's trying? ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 40 We're on the right track! We can now continue untangling this line, as we work our way out: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 41 Our line now looks like: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 42 So, this code tries to lookup "yippeekiyaa.aaay" via Google's 8.8.8.8 DNS server. If it gets a result, it just returns. We seem to have found our kill switch. The WannaCry article discussed how a researcher registered the killswitch domain in order to stop it in its tracks. We've also noticed the "HoHoHoDaddy" terminal, which brings up a domain registration page. If we enter our domain, we get:
    An error occurred while uploading 2712 là gì năm 2024
    Figure 56: Killswitch registered Answer: yippeekiyaa.aaay

Phase 4: Recover Alabaster's Password

  • Goal Recover Alabaster's password as found in the the encrypted password vault.
  • Background
    • Elf Chat Alabaster says:
      Yippee-Ki-Yay! Now, I have a ma… kill-switch!

Now that we don't have to worry about new infections, I could sure use your L337 security skills for one last thing.

As I mentioned, I made the mistake of analyzing the malware on my host computer and the ransomware encrypted my password database.

Take this zip with a memory dump and my encrypted password database, and see if you can recover my passwords.

One of the passwords will unlock our access to the vault so we can get in before the hackers. We also have the following hints from Shinny: He also said that Wannacookie transfers files over DNS and that it looks like it grabs a public key this way.

Another recent ransomware made it possible to retrieve crypto keys from memory. Hopefully the same is true for Wannacookie!

Of course, this all depends how the key was encrypted and managed in memory. Proper public key encryption requires a private key to decrypt.

Perhaps there is a flaw in the wannacookie author's DNS server that we can manipulate to retrieve what we need.

If so, we can retrieve our keys from memory, decrypt the key, and then decrypt our ransomed files.

Badge Hint

We have a hint that we haven't used yet: Pulling strings from a memory dump using the linux strings command requires you specify the -e option with the specific format required by the OS and processor. Of course, you could also use powerdump.

Solution

Opening the zip reveals two files: ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 59 and ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 60. To solve this, we really need to understand the Powershell script better. After some analysis, we can trace the main code flow:

An error occurred while uploading 2712 là gì năm 2024
Figure 57: WannaCookie Flowchart At this point, Shinny's hints make more sense. We observe the malware grabbing a public key over DNS ( ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 61). The files are then encrypted with a different, random encryption key ( ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 62 and ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 63). Unfortunately, ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 62 and ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 63 are cleared from memory, so we likely won't be able to find them in the memory dump. We notice that ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 62 is encrypted with ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 61 and uploaded over DNS. Shinny's hint tells us that to decrypt the encrypted ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 62, we need the private key. The public key was downloaded over DNS with the filename "server.crt". The Packalyzer also had a "server.crt" key, and its private key was stored in "server.key." Let's see if the malware author left that key sitting around: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 43 Now that we have the private key, we need to recover the encrypted ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 62. Before we can find it, we need to know the format it's in. Once again, we'll just execute some of the malware's code: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 44 So, we're looking for a 512-character long hex string. Our hint points us to powerdump, so let's give that a shot, continuing to follow along in Chris's video. Once we load and process the file, we can search for a string: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 45 Well, that was easy. We didn't even need a regular expression for the hex-encoding, as there was only one variable of length 512. ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 46 Looks like we found it! Let's also recover the SHA1 hash of the key, so that we can verify it's correct once we decrypt it. A hex-encoded SHA1 hash will be 40 characters long: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 47 Now we can use the private key to decrypt it. At this point, we ran into some issues doing this in Powershell, as loading private key is a bit different from how the malware loads the public key. We'll switch to Python for the rest of this challenge: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 48 Once we run that, we're greeted with ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

  1. Last step. Now we can use that key to decrypt the encrypted wannacookie file. Once again, we turn to Python: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 49 End result: ... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ... 71. We've done this before! ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 50 Answer: ED

    ED

    EED

    EF

    G

    F

    G

    ABA

    BA

    B

    :CUSTOM_ID: obj9

Who Is Behind It All?

Goal

Use what you have learned from previous challenges to open the door to Santa's vault. What message do you get when you unlock the door?

Background

  • Elf Chat Alabaster rewards us by saying:
    I'm seriously impressed by your security skills.

How could I forget that I used Rachmaninoff as my musical password?

  • Badge Hint But wait! Checking our badge reveals… Really, it's Mozart. And it should be in the key of D, not E.

Solution

We take the notes recovered from Alabaster's decrypted password vault, and try it on the piano lock. The document we recovered from Packalyzer helpfully shows us the notes on the piano keys.

An error occurred while uploading 2712 là gì năm 2024

Figure 58: Wrong key

The hint tells us that it should be in the key of D, not E. The Packalyzer document also told us how to transcribe music from one key to another. Let's try:

Note in key of E Note in key of D E D D# C# E D D# C# E D E D D# C# E D F# E G# F# F# E G# F# A G B A A# G# B A A# G# B A

Trying that sequence (

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

  1. reveals:

An error occurred while uploading 2712 là gì năm 2024

Figure 59: Right key!

Once we enter the vault, Alabaster tells us:

Of course I transposed it it before I entered it into my database for extra security.

Hans offers us a congratulations, and Santa explains the whole thing, finishing:

You did such a GREAT job! And remember what happened to the people who suddenly got everything they ever wanted? They lived happily ever after.

So, who was behind it all?

Answer:

Santa

de Bruijn Piano Lock?

After learning about sequences, we were curious if that would work here. The lock seemed to operate in the same way, as it would try unlocking after each note was pressed. We noticed that the tune in question had a similar note pattern at the end (

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

  1. as at the beginning (

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

74). We whipped up a quick Python program that verified that in fact we could generate a de Bruijn sequence.

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

51

The result was:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

52

What's even cooler is that the sequence goes through all of the keys before it repeats!

An error occurred while uploading 2712 là gì năm 2024

Figure 60: de Bruijn key sequence for Marriage of Figaro

Rachmaninoff?

As we walk around the castle, everyone congratulates us on winning. However, we don't feel complete, as we're left with the nagging question of what in the world Alabaster was talking about with his Rachmaninoff-no-really-Mozart song. We have the notes, but not the tune. Can we figure out the song?

This one we solved two ways:

Musipedia.org allows you to search by melodic contour (Parsons code). By simply saying if each note progression goes up, down, or repeats, it can find the closest matches:

An error occurred while uploading 2712 là gì năm 2024

Figure 61: Musipedia Parsons search

The Wedding of Figaro seems to match perfectly:

An error occurred while uploading 2712 là gì năm 2024

Figure 62: Wedding of Figaro, by Mozart

But still… why Rachmaninoff, then? The answer is found in the second method we used to figure this out:

An error occurred while uploading 2712 là gì năm 2024

Figure 63: Asking on Facebook…

Your browser does not support the video tag.

And with that, Santa's parting words make a lot more sense too:

Your browser does not support the video tag.

Going Further: Escalations and 0days

At this point, we've solved it all! However, our curiousity is unabated, and we'd like to know what else we can find…

Note

We managed to escalate to root on the snort terminal, pivot to snortsensor1, where we got command execution and were able to read files with root privileges. Finally, we got a shell on careers.

Scan-O-Matic

We managed to get through the , but we were curious to see who had access.

We wrote which allowed us to use

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

75 to enumerate the rest of the data in the table:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

53

We note that only has access.

Escalating to root on snort

We've solved the Snort challenge, but what else can we do on that system?

Checking

dig +noall +answer ANY kringlecon.com

81, we see:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

54

So, root is running a number of processes. Let's see if we can figure out what's happening behind the scenes to test our rule. It seems as if something happens whenever we modify the local.rules file, so we can simulate that with

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

77:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

55

Here we see that root actually runs

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

78 to check our rules. Perhaps we can modify the Snort configuration in such a way to run some commands as root? We can't modify

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

79, but let's see how the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

17 file is being loaded:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

56

Ah! It seems as if it's being included into the config. A generic

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

81 statement would imply that we could modify arbitrary configuration settings, and we're not simply limited to adding rules. Looking over the Snort documentation, we found a very intriguing option:

...

NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

82

Tells snort to load the dynamic preprocessor shared library (if file is used) or all dynamic preprocessor shared libraries (if directory is used).

Time to create a malicious shared library:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

57

The above command uses Metasploit's

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

83 to create a shared library which will execute a command when it's loaded. Because Snort's running as root, the command will run as root as well. The command grants our

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

84 user the ability to run any command with superuser privileges, without prompting for a password.

The Snort system is the only Docker container which has networking enabled. We can transfer our new shared library by simply using

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

85. Then, we add it to the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

17 file:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

58

Pivoting to snortsensor1

Now that we have root access on the Snort docker container, we can extract the HMAC key from the script. We also see the following interesting snippet from the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

87 script (snort spelled backwards):

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

59

Sure enough, using the private key, we can also login to snortsensor1 as elf. However, we run into an issue:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

60

Command execution on snortsensor1

We need to figure out a way past

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88. We can copy files off of the system, and we can copy

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

89, which mainly has:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

61

To start, let's see what actually happens when we run

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90. We'll run it with the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

91 (

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

  1. flag:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

62

So,

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 is simply calling

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

94 with a fixed command. We can run this ourselves to verify:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

63

So, the program hangs, and once we type some input, we get some text back. So, it certainly seems as if

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88 allowed us to run our

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 command. Can we run other commands this way?

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

64

That's a negative.

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88 must be filtering the commands we can run. Time to dive into the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 and

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

94 documentation, and see if there's a way we can craft an

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 invocation that will cause it to execute commands. Quickly, we identify a promising candidate:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

65

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

66

They're on to us… Reading further, we see that we can also pass

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

94 options to

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

67

Reading through the

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
03 man page, we find another intriguing option:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

68

From the snort system, we already know the fun we can have with a shared library. First, we'll build a library which executes a command when it's loaded:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

69

Now, will

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 load this? We test on our system first:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

70

No, the same behavior. Of course! The man page said that this option is passed to the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

94 call, and by just listening for data,

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 is never calling

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

94. To make it do this, we'll try using

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 to send a file from our system to another:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

71

Success! Now the question is, will

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88 allow this new

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

90 command? First, we'll copy our shared library over to the system. We'll add another

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

94 option to ignore the "New host key, Are you sure you want to continue?" prompt:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

72

Success!

We reported this issue to the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88 author, who replied saying that:

RSSH is no longer maintained.

We've applied for a CVE and will update our report when that's assigned.

So… we discovered a 0day! And perhaps it's time for people to switch off of

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88.

At this point, it's trivial to escalate this to a meterpreter shell:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

73

Bingo!

Privilege Escalation on snortsensor1

Now that we have a comfortable foothold, we can see how the holiday magic of snortsensor1 was created. Looking at processes running, we identify

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
14, and we notice that it's running as root. The main logic of that script is:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

74

This script has a vulnerability in this section:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

75

Let's assume that an attacker wants to access a file on the system that the elf user isn't authorized to read. Because

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
15 is running as root, the attacker knows that the script can read that file. Furthermore, the script is placing files in the publicly accessible web server root.

Linux uses symbolic links (symlinks), almost as a pointer from one location to another on the filesystem. If an attacker times their attack just right, they can do something like:

An error occurred while uploading 2712 là gì năm 2024

Figure 64: packet_generator race condition

An interesting note is that this attack was possible without the

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

88 vulnerability, as

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
17 was allowed, and

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
17 can create symlinks.

However, this race is very hard to win. And, if we don't time it right, the following happens:

An error occurred while uploading 2712 là gì năm 2024

Figure 65: packet_generator oops condition

Let's see if we can't improve our odds. Another special Linux file is a FIFO, or named pipe. These are designed so that one side will write to it, and another will read to it. All data is passed internally, without being written to the filesystem. One side-effect of using a FIFO is that, when you write to it, your program will hang until something reads from it. We can use this to cause

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
19 to pause at the right time, giving us a much better chance to win the race.

An error occurred while uploading 2712 là gì năm 2024

Figure 66: packet_generator FIFO

We've successfully moved the race up a step, where now we need to get

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
19 writing to our FIFO just after it deletes

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
21, but before it starts writing to it. However, this approach has two advantages: the

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
22 function takes a bit of time to run, and the risk of accidentally overwriting our target file is greatly reduced.

We weaponized this as a bash script, which has the following logic:

An error occurred while uploading 2712 là gì năm 2024

Figure 67: race.sh logic

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

76

When running, this looks like:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

77

We see that there's a new file, with the same size as our target. Now we can download it, and we've got some hashes!

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

78

At this point, if we can crack root's password, we have completely compromised this system.

Popping a shell on careers

The final system we turned our attention to was careers.kringlecastle.com. We already got our file off of this system, but we'd like to see what else we can do.

We first tried to get a meterpreter session running, but quickly found that Windows Defender was blocking it. We were able to bypass Defender with this method: https://rastamouse.me/2018/12/amsiscanbuffer-bypass-part-4/

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

79

To create our actual payload, we use

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

83 once again. For the reasons listed in the article above, we're careful to use a 64-bit payload, so as to not spawn a non-bypassed 32-bit Powershell instance.

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

80

We fire up meterpreter (

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
24), and soon see:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

81

Unfortunately, our shell will get killed off after about 30 seconds. So, we'll migrate to another process. We see that Sparkle is running the Non-Sucking Service Manager, so we'll try to migrate to that process:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

82

At this point, we tried a few things (and were able to recover Sparkle's password hash through an SMB relay attack), but the escalation paths we saw risked the stability of the game, and we didn't pursue the matter.

Working as a Team

While working on this challenge, we used three main techniques to get things done and stay organized. We were mostly working in the same room that happened to have a couple of big whiteboards. Those came in handy as we slowly drew out the map of the game and location of all things in it. We also originally tracked our progress using this. The whiteboards also came in handy as a way to quickly iterate through ideas on specific challenges we faced.

An error occurred while uploading 2712 là gì năm 2024

Figure 68: Map Whiteboard

The use of a private Slack channel was also very helpful. It existed as a place to both dump answers, clues, and interesting artifacts, as well as a good place for discussion for when we weren’t in the same room.

An error occurred while uploading 2712 là gì năm 2024

Figure 69: Progress Whiteboard

Our final method for working was using a private GitHub repo. We didn’t want to have a public one because we didn’t want to spoil things for others, nor did we want to give away any advantage we had or secrets we found. GitHub was very useful for a place for more well defined to do list. We used GitHub issues to track what we still needed to do and chat about who was doing what. Labelling issues helped us to prioritize this to do list so we could make sure to finish up the challenge with the most impactful parts done.

All in all, using these collaboration techniques allowed us to be as comprehensive as we could with both the challenge and the end report.

Easter Eggs

A quick list of easter eggs that we found as we were going through the game.

Egg Location Reference Notes OHHIMARK LineCon/KringleCon The Room WebSocket Message "Wake up, we're at Grandma's" LineCon/KringleCon MST3k WebSocket Message egg.png LineCon/KringleCon Twitter Egg Logo a-wild-missingno-appears LineCon/KringleCon Pokemon Lethal ForensicELFification Terminal Lethal Forensicator Lethal ForensicELFification Terminal The Raven

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
25 Stall Mucking Argument Hitchhiker's Guide smbwrapper command argument

var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )

{ 
lava[i].style.background = "pink";
};
26 Stall Mucking Argument Star Wars Holiday Special & 2016 HHC smbwrapper command argument directreindeerflatterystable Stall Mucking Password XKCD KONAMI CODE Yule Log Analysis Konami Code and 2015 HHC In reverse-engineered code Escape from LA Python Terminal Escape from LA movie ("Snake is Back!") Candy Striper CURLing Terminal 2017 HHC EE2 (CranPi Logo) GitLab Old HHCs, Raspberry Pi EE3 (Drawing of Hans) GitLab Die Hard Theo Authorized User Scan-O-Matic Database Die Hard (he was the hacker) Only authorized and enabled user Bill Clay Wannacookie HTML Source Die Hard (Hans' alias) InigoMontoya Vents Code Princess Bride Happy Trails Answer 1 Die Hard John McClane Answer 2 Die Hard Yippee-ki-yay Answer 4 Die Hard 19880715 Answer 5 Die Hard Movie release date Fancy Beaver Answer 7 Fancy Bear APT Group erohetfanu.com Answer 10 Die Hard hansgruber ROT-13 and backwards yippeekiyaa.aaay Answer 11 Die Hard Piano Lock & Rachmaninoff Answer 12 Willy Wonka Many Hans quotes KringleCon Die Hard Toy Soldier quotes KringleCon Die Hard From Hans' German-speaking associates Dungeon for Errant Reindeer Hans Quote 2016 HHC ATNAS Corporation, Miss Cindy Lou Who Hans Quote 2015 HHC Glinda the Good Witch Hans Quote 2017 HHC The Plant Front Door Previous HHCs, psmitty First person to get all challenge coins!

Thank Yous

As proud as we are to have completed this Holiday Hack Challenge, we would be remiss to not publicly acknowledge a few people outside of this team who helped us during the challenge.

Justin Azoff (Corelight): Helped greatly on the as well as some other thoughts and ideas throughout

Michael Sinatra (ESnet): Helped us figure out why we were unable to query from Linux/macOS at first (search for noedns for more info)

Nick Buraglio (ESnet): Thanks to his time pretending to be Randall from the movie “Clerks” he immediately thought of the musical lock in Charlie and the Chocolate Factory when we were first stuck on that

We're also very grateful to SANS for this event, recognizing all the hard work that went into it.

But, most of all, we also need to thank our significant others for putting up with our efforts leading to some late nights and busy weekends. We all may need to stop at the florist on the way home today.

Appendix 1: Reverse Engineering PyInstaller Binaries

On some of the terminals, we would need to invoke a command, such as

dig +noall +answer ANY kringlecon.com

66 and provide the correct answer in order to receive credit for that terminal. Other terminals would automatically invoke a command once a certain condition has been met. Inspecting these files, we discovered that they were standalone Linux ELF binaries, which had been packaged by PyInstaller from a standalone Python script. We wanted to recover the original Python script, and were able to do just that.

  1. Extracting the code object PyInstaller provides a tool, var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    28, for inspecting archives and binaries created with it. First, we install pyinstaller: var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    29. Now we can use var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    28 to inspect our file: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 83 An ELF binary can have arbitrary data at the end of the file, and in our case, PyInstaller appends an archive with scripts, modules, and even shared objects that it needs to run the script. In this instance, we want the script var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    31, which is at offset 15,455 relative to the start of the archive (note: not from the beginning of the ELF binary). The script has a length of 2,182 bytes compressed, and 18,185 uncompressed. The type denotes that it's a script, and its original name was var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
  2. We can create a one-liner to generate the name of the script we want to extract: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 84 We're grabbing the line which comes after bootstrap, and then we're grabbing the 4th field, as delimited by single-quotes. Now we can use var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    28 to extract and uncompress our file: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 85
  3. Converting the code object to a .pyc file After some investigation, it turned out that what we've extracted is just a Python code object. We can import it into Python and view a disassembly, but in order to use some decompiling tools to try to recover source code, we need to have a byte-compiled Python file. To convert it, we just need to add a few bytes of header values. The easiest way to do this is just to extract another file, which is a valid pyc file, and copy the bytes from its header. We use var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    28 to extract var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    35, and we can verify that it has the right header: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 86 The pyc file format calls for a 12-byte header, so we can grab the first 12 bytes using var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    36 and save it to a file: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 87 Next we simply concatenate the two files: var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    37.
  4. Decompiling the .pyc file Now that we have a valid .pyc file, we can use var i; var lava = document.getElementsByClassName('lava'); for ( i = 0; i < lava.length; i++ )
    {  
    lava[i].style.background = "pink";  
    };  
    
    38 to convert it back to a Python script: ... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ... 88

Appendix 2: Game Internals: HMACs and Hidden Terminal Messages

In order to receive credit for successfully completing a game objective, such as a Cranberry Pi terminal challenge, or an objective, HMACs are used. In this section, we'll discuss how they're used, and how we were able to forge these after stealing the keys for some of the challenges.

Recovering the HMAC keys

After one of the

dig +noall +answer ANY kringlecon.com

66 binaries on a Cranberry Pi system, we can see how the scripts generate the HMAC:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

89

Each in-game element (terminal, objective, etc.) has a unique resource ID, and each user receives different resource IDs. These IDs are passed to the terminal via a GET parameter.

The terminals print a special message, which is hidden by the JavaScript TTY terminal.

We can create a bash one-liner to just give ourselves credit for this challenge, without actually solving it:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

90

This duplicates the logic in the Python script. It uses OpenSSL to calculate the HMAC, and then it prints the hidden message, which causes the game to give us credit.

Challenge Keys

Terminal Direct URL HMAC Key Essential Editor Skills viescape 2bb6b9c702834095a9c3284e053da124 The Name Game pwshmenu 78871929eec84c94806623a086b376f0 Lethal ForensicELFification viminfo 48e41d5cc5e041c0869395bb8cab791e Stall Mucking Report plaintext-creds CURLing Master http2 Yule Log Analysis spray-detect 81013803273d4c58b0e2e5ed869c3677 Dev Ops Fail gitpasshist 32f7f08dbb014bb3a288ecc9ecce1486 Python Escape from LA python_docker_challenge 09f90c21d59845a7b0c972b8e871e8fe The Sleighbell Lottery unlinked-function a6ec0e49731b4c29907422c23794b9a6 Snort snort 4069e612c5d44c69b9ba302ce63968d7

The Sleighbell Lottery key was recovered with

kringlecon.com. 599 IN A 104.196.14.143 kringlecon.com. 3599 IN NS ns45.domaincontrol.com. kringlecon.com. 3599 IN NS ns46.domaincontrol.com. kringlecon.com. 3599 IN SOA ns45.domaincontrol.com. dns.jomax.net. 2018121800 28800 7200 604800 600 kringlecon.com. 3599 IN MX 10 aspmx.l.google.com. kringlecon.com. 3599 IN MX 20 alt1.aspmx.l.google.com. kringlecon.com. 3599 IN MX 30 alt2.aspmx.l.google.com. kringlecon.com. 3599 IN MX 40 aspmx2.googlemail.com. kringlecon.com. 3599 IN MX 50 aspmx3.googlemail.com. kringlecon.com. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"

34.

As part of this report, we're releasing our scripts and tools at: https://github.com/esnet/sans-holiday-hack-2018

Some select tools, which were mentioned in this report are listed below:

Scan-O-Matic

We wrote this simple script to create and upload a QR code:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

91

We wanted to used tools that can automatically map SQL databases, such as

... NetRange: 104.196.0.0 - 104.199.255.255 CIDR: 104.196.0.0/14 NetName: GOOGLE-CLOUD ...

75, but they all use URLs, and not QR codes. So we hacked together this script, which calls the badge shell script, and just acts as a go-between:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

92

Careers

Uploading a CSV file by hand became old fast, so we wrote this:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

93

It takes a command as an argument, will upload it, and then poll the server to get the result.

Malware

We used the following script to search for other files the malware author may have left on the system:

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

94

Maze Solver

... Domain Name: northpolechristmastown.com Registry Domain ID: 2176618950_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.godaddy.com Registrar URL: http://www.godaddy.com Updated Date: 2017-10-19T19:29:00Z Creation Date: 2017-10-19T19:29:00Z ... Registrant Organization: Counter Hack ...

95

Postscript: Police Report

Case No: 951-262-3062 (Note to filing clerk: make sure to put this in the case number line, NOT the phone number line, this is also Santa Claus’ phone number and it’s easy to confuse)

Date: 12/21/2018

Reporting Officer: Sgt. Al Powell

Prepared By: ESnet Security

Incident: On the day of the 18th, ESnet Security was told of hostages being taken at Kringlecon.

POLICE REPORT

Summary: After speaking to Santa’s Elves, we were warned that all was not as it seemed at Kringlecon. The Toy Soldiers appeared to be up to something. We were able to ascertain many clues throughout the castle using many different digital forensic techniques. These clues pointed us to our belief that the Toy Soldiers were actually working for Hans Gruber. Hans was in turn, working for none other than Santa Claus himself. It seems Santa Claus had a feeling he could use some investigative help at some point in the future, so he set up this test to see if we were the people he should call on in the future.

An error occurred while uploading 2712 là gì năm 2024

Figure 70: Hans Gruber, person of interest

1988: Kidnapping, Murder, Attempted Grand Larceny - Took hostages at Nakatomi Plaza in an attempt to steal $640 million dollars in bearer bonds

An error occurred while uploading 2712 là gì năm 2024

Figure 71: Santa Claus, interesting person

~280 AD - 2018: Breaking and entering into homes around the world every winter. Estimates suggest 640 million per year (coincidentally the same amount Hans attempted to steal)