- Generated screenshots for all 33 challenges (ESP, Hardware, IoT, OT, Misc, Web3) - Replaced all 123 placeholder lines with actual PNG image references - Cleaned duplicate images from previously partial updates - All write-ups now have full illustrated solutions |
||
|---|---|---|
| .. | ||
| README.md | ||
Anesthesia Gateway
| Field | Value |
|---|---|
| Category | IoT |
| Difficulty | Medium-Hard |
| Points | 500 |
| Author | Eun0us |
| CTF | Espilon 2026 |
Description
The anesthesia monitoring gateway in Operating Room 13 at Clinique Sainte-Mika is broadcasting live data over MQTT.
Something unusual is being transmitted on the network. The contractor left a debug channel open.
Connect to the MQTT broker and investigate.
- MQTT Broker:
tcp/<host>:1883
Format: ESPILON{flag}
TL;DR
Subscribe to the MQTT wildcard topic sainte-mika/#. Find the debug firmware topic
publishing a base64-encoded blob every 45 seconds. Reverse the encoding chain
(base64 → XOR with key WIRED → zlib decompress → JSON) to extract the maintenance key
N4V1-C4R3-0R13-L41N. Publish it to the unlock topic to receive the flag.
Tools
| Tool | Purpose |
|---|---|
mosquitto_sub / mosquitto_pub |
MQTT client |
| Python 3 | Decode base64, XOR, zlib, JSON |
Solution
Step 1 — Connect and discover topics
mosquitto_sub -h <HOST> -t "sainte-mika/#" -v
Topics discovered:
| Topic | Content |
|---|---|
sainte-mika/or13/vitals |
Patient vital signs (JSON) |
sainte-mika/or13/sevoflurane |
Anesthetic gas data |
sainte-mika/or13/propofol |
Infusion pump data |
sainte-mika/or13/ventilator |
Ventilator data |
sainte-mika/or13/alarms |
Alarm status — note "network": "WIRED-MED" |
sainte-mika/or13/debug/firmware |
Base64 blob, published every 45s |
Step 2 — Capture the firmware blob
Wait for a message on debug/firmware (up to 45 seconds). Save the base64 string.
Note the "network": "WIRED-MED" in the alarms topic — this is the XOR key hint.
Step 3 — Reverse the encoding chain
The chain is: base64 → XOR("WIRED") → zlib → JSON
import base64, zlib, json
blob = "<base64 string from debug/firmware>"
# Step 1: base64 decode
raw = base64.b64decode(blob)
# Step 2: XOR with key "WIRED"
key = b"WIRED"
xored = bytes(b ^ key[i % len(key)] for i, b in enumerate(raw))
# Verify: first two bytes after XOR should be 0x78 0x9C (zlib magic)
assert xored[:2] == b'\x78\x9C', "Key is wrong — magic bytes don't match"
# Step 3: zlib decompress
decompressed = zlib.decompress(xored)
# Step 4: parse JSON
config = json.loads(decompressed.decode())
print(config)
Step 4 — Extract the maintenance key
The decoded JSON contains:
{
"maintenance_key": "N4V1-C4R3-0R13-L41N"
}
The key is a leetspeak encoding of "Navi Care OR13 Lain".
Step 5 — Publish the key and get the flag
mosquitto_pub -h <HOST> -t "sainte-mika/or13/maintenance/unlock" -m "N4V1-C4R3-0R13-L41N"
Subscribe to the flag topic:
mosquitto_sub -h <HOST> -t "sainte-mika/or13/maintenance/flag"
Key insights
- The XOR key
WIREDis derivable from the alarms topic which includes"network": "WIRED-MED" - After XOR decryption, the zlib magic bytes
0x78 0x9Cconfirm the correct key - MQTT wildcard subscription
#enumerates all topics in one command - An open MQTT broker with no authentication is a real-world IoT misconfiguration
Flag
ESPILON{mQtt_g4tw4y_4n3sth3s14}



