One weekend. One controlled OT security lab. One very uncomfortable lesson about how safety systems actually fail.
Every so often, Me spend a weekend in the lab — a controlled environment built to mirror a real industrial setup, with one goal: sharpen myself OT red teaming skills by attacking something that behaves like production. This time the target was a reactor monitoring system modeled on a genuine power facility.
Spoiler: I got root. But the way in had almost nothing to do with industrial hacking.
The Attack Path
Forgotten subdomain → unauthenticated NiFi → leaked SSH key → operator account → tricking the safety controller into opening a privileged window → root.
1. The boring door
A port scan showed nothing dramatic — just SSH and a corporate website. But corporate sites have siblings. Subdomain enumeration turned up ops.cascade-pointenergy.com, hosting an Apache NiFi instance. Wide open, no authentication.
NiFi is a data-flow tool where you visually wire up processors — and processors can run arbitrary commands. That’s not a bug; it’s the product working as designed, minus any guardrails. Ten minutes later, we had a shell as the nifi service account.
2. The key in the junk drawer
Digging through NiFi’s support-bundles directory — where diagnostic archives get dumped — I found j.calloway_id_ed25519.bak. A backup of an operator’s SSH private key, copied “just in case” and forgotten. We SSH’d in as j.calloway. Plant access, just like that.
3. The manual, after cracking it
Calloway’s home directory held a control systems diagram and a password-protected “Operator Control & Safety Guide.” Password: calloway1. Ninety seconds to crack — go check your own password policy, I’ll wait.
That PDF was the crown jewels. It explained the plant’s logic:
- Above ~305°C or ~75 bar → safety trip latches, rods drop, control locks out.
- Trips only reset once the reactor is verifiably safe.
- The safety controller opens a privileged maintenance window — on its own authority — when the reactor sits in a hazardous-but-stable band (~295°C / ~73 bar), below trip thresholds.
4. Lying to the physics
Calloway’s account could talk to an OPC UA server (the industrial protocol for PLCs and sensors). The writable variables told the story:
- Calibration Offset — a sensor bias, writable
- Mode and Test Override — writable
- Rods, cooling, trip status — read-only, owned by the safety controller
The catch from the manual: the offset only takes effect in MAINTENANCE mode with Test Override on. So the chain writes itself:
- Flip into MAINTENANCE, enable the override.
- Ramp the calibration offset slowly — fake the temperature climbing.
- Stop in the band: hazardous enough that the safety controller concludes “a technician must be testing,” but below the trip line.
- The controller opens the privileged window.
- Calloway’s
sudo-able maintenance console only works during that window. Run it. Root shell. Weekend complete.
Rush the ramp and you overshoot — rods slam in, cooling fires, lockout. My first attempt ended exactly that way. Patience won the second.
What This Actually Teaches About OT Security
Nobody breaks in through the PLC. Our entry was a misconfigured web tool and a stale backup key — pure IT hygiene failure. Every real OT breach (Oldsmar, Ukraine grid) follows this pattern: attackers arrive via credentials and forgotten assets, then pivot. Your OT perimeter is your worst IT asset, not your firewall.
Safety systems fail through their assumptions, not their code. The interlocks were flawless. Trip logic latched, critical outputs were untouchable. What broke was the assumption that “reactor in hazardous test band” equals “authorized human did this.” The controller trusted the physics — and we could write the physics via a sensor bias. Safety designed to protect against accidents, not adversaries, becomes the attacker’s tool.
Slow attacks look like operations. My fast ramp got punished; my patient ramp got rewarded. A safety controller can’t tell a careful attacker from a careful technician. If your detection watches process states instead of who changed what, from where, you’re blind to the attacks that matter.
Privilege checks must not be satisfiable by the party being elevated. The maintenance console correctly checked the window — but the window’s opening conditions were forgeable by the same operator account asking for root. Circular authorization is theater.
The Takeaway
Five of the six steps were IT problems. Only the last one touched OT logic, and even that worked because of human design assumptions, not a vulnerability.
That’s why weekend exercises like this matter: you get to learn, with a reset button, that your safety marvels defend against physics and accidents — not against an authorized-looking human quietly lying to the sensors. In connected facilities, intent is the attack surface.
And delete your backup keys. Seriously.