Holiday Hack 2024: Frosty Keypad
Introduction
Up towards the castle off to the right is Morcel Nougat standing next to the Frosty Keypad:
He is stuck and needs help:
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:
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:
There’s a note taped to the top left with some numbers. If I have the UV flashlight, it shows up as well:
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:
By that, S –> 7, A –> 2, N –> 6, T –> 8, and A –> 2.
Entering this solves the silver level:
Gold
Challenge
Morcel has more info:
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:
The other keys, such as 1, don’t:
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:
Outro
Bow is impressed:
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:
This will be useful for the hardware challenges.