# 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/: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 ![MQTT subscribe capturing all topics including admin/config](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/mqtt_sub.png) ### Step 1 — Connect and discover topics ```bash mosquitto_sub -h -t "sainte-mika/#" -v ``` > 📸 `[screenshot: mosquitto_sub output listing all discovered topics and their messages]` 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. > 📸 `[screenshot: debug/firmware topic publishing the base64-encoded blob]` ### Step 3 — Reverse the encoding chain The chain is: `base64 → XOR("WIRED") → zlib → JSON` ```python import base64, zlib, json blob = "" # 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) ``` > 📸 `[screenshot: Python script printing the decoded JSON configuration]` ### Step 4 — Extract the maintenance key The decoded JSON contains: ```json { "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 ```bash mosquitto_pub -h -t "sainte-mika/or13/maintenance/unlock" -m "N4V1-C4R3-0R13-L41N" ``` Subscribe to the flag topic: ```bash mosquitto_sub -h -t "sainte-mika/or13/maintenance/flag" ``` > 📸 `[screenshot: flag topic publishing the ESPILON flag after unlock]` ### Key insights - The XOR key `WIRED` is derivable from the alarms topic which includes `"network": "WIRED-MED"` - After XOR decryption, the zlib magic bytes `0x78 0x9C` confirm 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}`