write-up: OT/Schumann_Resonance/README.md

This commit is contained in:
Eun0us 2026-03-26 17:33:48 +00:00
parent 4700da57d4
commit aca070d230

View File

@ -1,74 +1,137 @@
# Schumann Resonance -- Solution # Schumann Resonance
## Overview | Field | Value |
Raw BACnet/IP server simulating an environmental monitoring station at |-------|-------|
Tachibana General Laboratories, Sub-basement 7. The device contains hidden | Category | OT |
flag fragments XOR-encoded in object descriptions. Writing the Schumann | Difficulty | Medium |
resonance frequency (7.83 Hz) to the tuning register reveals the flag. | Points | 400 |
| Author | Eun0us |
| CTF | Espilon 2026 |
## Steps ---
### 1. Device Discovery ## Description
Send a BACnet WhoIs broadcast to UDP port 47808. The device responds
with IAm: device instance **783** (reference to 7.83 Hz). 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:
```python ```python
# Using BAC0:
import BAC0 import BAC0
bacnet = BAC0.lite(ip="YOUR_IP/24")
bacnet = BAC0.lite(ip="<YOUR_IP>/24")
bacnet.whois() bacnet.whois()
# -> Device:783 "Tachibana-ENV-SB7" # Device:783 "Tachibana-ENV-SB7"
``` ```
### 2. Enumerate Objects Device instance **783** → 7.83 Hz → **Schumann Resonance**.
Read the object-list property from Device:783:
- AnalogInput:0-3 -- normal environmental sensors (temp, humidity, pressure, CO2)
- **AnalogInput:4** -- EMF_Resonance = 7.83, description = **"PROTOCOL_SEVEN_CARRIER"**
- AnalogValue:10 -- Freq_Multiplier = 0.0 (writable!)
- AnalogValue:11-17 -- Fragment_0 through Fragment_6 (descriptions are hex strings)
- BinaryValue:100 -- Resonance_Lock = inactive
- CharStringValue:200 -- Research_Log = "Access Denied"
### 3. Identify Key > 📸 `[screenshot: BACnet WhoIs response showing Device:783]`
Device instance 783 → 7.83 Hz → Schumann Resonance.
XOR key = `0x0783` (2-byte big-endian from device instance).
### 4. Decode Fragments ### Step 2 — Enumerate objects
Each Fragment_N has a description containing a hex-encoded XOR'd string.
XOR each byte with the alternating key bytes (0x07, 0x83): 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:
```python ```python
key = (0x07, 0x83) fragments = []
for frag in fragments: for i in range(7):
enc = bytes.fromhex(frag) desc = bacnet.read(f"783 analogValue {11+i} description")
dec = bytes(b ^ key[i % 2] for i, b in enumerate(enc)) enc = bytes.fromhex(desc)
print(dec.decode()) key = (0x07, 0x83)
dec = bytes(b ^ key[j % 2] for j, b in enumerate(enc))
fragments.append(dec.decode())
flag = "".join(fragments)
print(flag)
``` ```
Concatenate all decoded fragments → the flag. > 📸 `[screenshot: decoded fragment strings concatenating into the flag]`
### 5. Activate (Alternative Path) ### Step 5 — Activate (alternative path)
Write `7.83` to AnalogValue:10 (Freq_Multiplier):
Write the Schumann frequency to AnalogValue:10:
```python ```python
# WriteProperty: object=AnalogValue:10, property=presentValue, value=7.83 bacnet.write(f"783 analogValue 10 presentValue 7.83")
``` ```
This sets BinaryValue:100 (Resonance_Lock) to active and writes the This sets BinaryValue:100 (Resonance_Lock) to active and writes the flag to
flag to CharStringValue:200 (Research_Log). CharStringValue:200 (Research_Log).
### 6. Read Flag Read the flag:
Read the presentValue of CharStringValue:200 (Research_Log).
## Key Insights ```python
- Device instance 783 is the key derivation hint (7.83 Hz) flag = bacnet.read(f"783 characterstringValue 200 presentValue")
- AnalogInput:4 description "PROTOCOL_SEVEN_CARRIER" confirms the Schumann connection print(flag)
- Freq_Multiplier description says "set to Schumann harmonic to activate" ```
- Two solve paths: decode fragments manually OR activate and read Research_Log
- No authentication on BACnet -- a real-world building automation vulnerability > 📸 `[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 ## Flag
`ESPILON{sch0m4nn_r3s0n4nc3_783}`
## Author `ESPILON{sch0m4nn_r3s0n4nc3_783}`
Eun0us