All articles

ResearchSeptember 18, 202611 min read

Seven hops to Generator 3: anatomy of a cross-domain attack path

A corporate SSO login should not be able to cool down a 340 MW generator. At one power site it could, in seven hops, and not one of those hops was a vulnerability. Every step was a supported feature, correctly configured, working exactly as designed.

The short version

  • A valid corporate SSO login reached the auxiliary cooling loop of Generator 3 in seven hops. Not one hop was a CVE: four were identity and trust decisions, two were network reachability, one was a protocol with no concept of authentication.
  • The route lived in the seam between the identity team’s model and the OT team’s model. Both sides were covered and audited; neither could see the whole path.
  • Severity came from the plant’s own derate table rather than CVSS: 43% capacity loss within eighteen minutes, which moved the finding past a queue of internet-facing medium CVEs.
  • The route was cut at the OT boundary in nine days, and the finding closed only when the original path was re-run and denied three times out of three.
7hops from corporate login to controller
0CVEs anywhere in the route
6:40to traverse the path in the twin
3 cutsclose the route before the slow fix lands

Map a power site properly and you do not get a report, you get a route. A standard corporate login, issued to a platform engineer who has never heard of the plant, reaching the auxiliary cooling loop of Generator 3 in seven hops. Nothing in that chain is broken. Everything in it is documented, ticketed, and owned.

The walkthrough below uses power-site-03, the reference environment we use to demonstrate Kybernao, and the finding it carries, KYB-004. The topology is synthetic. The shape is not. Identity reaching into control through a chain of individually reasonable decisions is the pattern this platform was built to surface.

The finding nobody scanned for

By every measure the site was in good shape. The historian was patched. The OT DMZ was segmented and documented. MFA was enforced on the VPN. An EDR agent ran on every Windows host, and the previous year's external penetration test had closed with no critical findings.

None of the seven hops was a CVE. Four were identity and trust decisions. Two were network reachability. One was a protocol that has no concept of authentication at all.

A vulnerability is a defect in a component. A path is a property of a system. You will not find the second by enumerating the first, no matter how good your enumeration gets.
SAME SITE, TWO QUESTIONSTHE SCANNER ASKEDwhat is wrong with this assethistorianpatchedjump hostpatchedPLC-07no CVEboundary firewallcompliantTHE GRAPH ASKEDwhat can these reachseven permitted transitions43% capacity loss
Fig 1One question returns a clean report. The other returns a route to a generator.

This is the structural reason posture scores and attack paths disagree so often. A scanner asks each asset what is wrong with it. An operator needs to know what the assets can do to each other.

The route, hop by hop

Kybernao Atlas builds the terrain graph from the environment's own configuration: identity providers, cloud role assignments, firewall rule sets as exported from the running devices, switch and routing tables, controller project files, and passive OT observation. The route below is a walk through that graph, then reproduced end to end in the site's digital twin.

CORPORATECLOUD / CIOT DMZENGINEERINGPROCESS1234567corp SSOcloud tenantCI runnerjump hosthistorianeng VLANPLC-07Gen 3 coolingSEVEN HOPS · ZERO EXPLOITS · EVERY STEP PERMITTED BY A RULE SOMEONE WROTE
Fig 2Every hop is a permitted transition. The path is the composition, not any single misconfiguration.
HopTransitionWhat made it possible
1Corporate SSO → cloud tenantStandard member of eng-platform. Conditional access requires MFA at interactive sign-in, but not on token refresh or role assumption.
2Cloud tenant → CI runnerThat group inherits a role assignment on the build subscription through a nested group added fourteen months earlier for a datacenter migration, and never removed.
3CI runner → OT jump hostThe pipeline secret library holds an SSH key that is valid on the jump host. It was placed there so nightly historian backups could run unattended.
4Jump host → historianThe jump host sits inside the OT DMZ and is permitted to the historian on 443 and 1433. The historian API returns controller tags without per-tag authorization.
5Historian → engineering VLANThe collector reaches back into the engineering VLAN on its data-collection port. The firewall rule is bidirectional because the vendor's installation guide asked for it.
6Engineering VLAN → PLC-07Modbus/TCP 502 is permitted from the engineering VLAN, including function 16, write multiple registers. No session signing. No identity on the wire.
7PLC-07 → cooling loopRegisters 40021–40024 are the setpoint block for the auxiliary cooling loop on Generator 3.

Traversal time in the twin, from first authentication to a write landing on the register block: six minutes and forty seconds. No malware. No exploit. Native tooling at every step: a browser, a pipeline, an SSH client, a vendor API, and a Modbus library that ships in the standard library of two languages.

Scope note

Hops 1 through 5 are the kind that can be proven against a live environment at Level 2, one authorized action at a time. Hops 6 and 7, anything that puts a write in front of a controller, stay in the twin and never touch live equipment. That distinction is the subject of a separate article on execution levels.

Why seven correct decisions produce one wrong outcome

Every hop had an owner, a ticket, and a defensible reason at the time it was made. The nested group was a migration convenience with a note on it. The SSH key was an availability decision made after a backup job failed over a long weekend. The bidirectional rule came straight out of the vendor's install guide. The Modbus permit is how the engineers do their jobs.

No single owner could see hop 3 and hop 6 at the same time. The identity team's model of the world ends at the tenant boundary. The OT team's model begins at the DMZ. The path lives in the space between them, and that space is not a gap. Both sides are covered, audited, and confident. It is a seam: an overlap where two correct models disagree about what the other one guarantees.

Seams are where routes hide, and they are systematically invisible to programmes organized by domain. The only way we know to find them is to hold identity, cloud, network, control, and physical consequence in one graph and ask reachability questions across all of them at once.

Consequence is the severity

The interesting question about hop 7 is not the protocol. It is what the register block does.

Atlas carries a consequence edge from controllers to the physical functions they drive, populated from the site's own engineering documents. PLC-07 drives the auxiliary cooling loop for Generator 3. The derate table, which is a document the plant already owns rather than something Kybernao models, puts loss of auxiliary cooling at a 43% capacity reduction and a protective trip not long behind it under summer ambient conditions.

So the finding's severity is not "High, because Modbus is unauthenticated." It is "43% of 340 MW, during the week of the year when the reserve margin is thinnest." That framing is what moves an item. A consequence stated in megawatts does not need a scoring argument to get ahead of a queue of internet-facing medium CVEs.

What we changed, in the order that cut the route fastest

A seven-hop path does not need seven fixes. It needs the cheapest cut that holds, then the structural ones behind it.

  1. Cut hop 6 first, in days rather than weeks. A Guardian rule at the OT boundary denying unsigned Modbus writes originating from corporate address space, with signed-session enforcement required for the writes that remain legitimate.
  2. Then hop 3, over a few weeks. Key rotated, the backup job inverted to a pull model under a scoped service account, and the pipeline secret removed entirely.
  3. Then hop 2, a change-window item. The nested group unwound, and step-up authentication required on role assumption rather than only at sign-in.
  4. Hop 4 last, and it may never close on your schedule. Per-tag authorization in the historian is a vendor roadmap item. It is tracked, it is not blocking, and the route is already cut in two places ahead of it.
INDICATIVE TIME TO CUT, CHEAPEST FIRST6Guardian denies unsigned Modbus writes9 days3Key rotated, backup inverted to pull3 weeks2Nested group unwound, step-up on assume6 weeks4Per-tag authorization in the historian11 weeks, open04w8w12w
Fig 3The cheapest cut lands first. The structural fixes follow, and the one nobody can close yet is written down rather than waited on.

The boundary rule goes first because a controller like PLC-07 cannot be touched outside a maintenance window that may be months away, and because it has no authentication primitive to enable in the first place. You defend where you can act this week, and you write down where you could not.

policies/ot-boundary/plc-07-writes.ruleGuardian
rule block-unsigned-modbus-write
  match proto=modbus fn=16 src=corp-vlan
  dst   plc-07                  // aux cooling, Generator 3
- action allow
+ action deny  log=guardian
+ require signed-session
  verify twin=replay-set-004

The rule was validated against the twin with the same replay set that reproduced the original path, before it was proposed to the operator. Guardian does not open a containment plan the twin has not already accepted.

The retest is the deliverable

A finding is not closed when a ticket is marked done. It is closed when the original route stops working, proven by running it again.

retest/KYB-004/2026-09-21.logRed
[09:42:31] Initiating retest for KYB-004
[09:42:31] Target: modbus://plc-07.ot.power-site-03 fn=16
[09:42:32] Attempt 1/3  unsigned write      -> DENIED
[09:42:32] Attempt 2/3  replayed session    -> DENIED
[09:42:33] Attempt 3/3  forged HMI origin   -> DENIED
[09:42:33] All write vectors blocked. Sentinel observed 3/3.

Two details matter more than the denials. The first is that Sentinel saw all three attempts: a control that blocks silently is a control you will not notice failing. The second is that the retest is scheduled to run again after the next change window, because the fix lives in a configuration file that people edit for good reasons. Every route we close is a claim with an expiry date.

Five questions for your own environment

You do not need our platform to start on these. You need somebody willing to hold two domains in their head at once for an afternoon.

  • Which identities outside the OT trust boundary can, through any chain of group memberships or role assumptions, obtain a credential that is valid inside it?
  • Which of your firewall rules are bidirectional because an installer asked, rather than because traffic needs to flow both ways?
  • For every controller that drives a process with a derate or trip consequence, what is the shortest route from a corporate credential, and who has ever drawn it?
  • When a finding is closed, who reruns the original route, and where is that result written down?
  • If the WAN were down right now, which of the controls along that route would still enforce?

Mapping the terrain is the fast part, and the fixes are rarely the slow part either. What takes longest is getting the identity team and the control team to look at one picture together, which, in the end, is the entire product.

Mira Okafor Mission Engineering

Works inside Kybernao Command alongside customer teams on energy and utility deployments. Spent nine years in control system engineering before moving to security.

Site design sessions open

Map one site. Find the route.

Bring a single environment and a Kybernao engineer will build the terrain graph from it, walk the paths that reach something physical, and show you what closes first.

Site design sessions open

Request a Kybernao demo

Tell us a little about your environment. A Kybernao engineer will follow up to arrange a focused walkthrough.

  • 01Focused architecture walkthrough
  • 02Mapped to your mission environment
  • 03Led by a Kybernao engineer
SECURE INTAKE→ENGINEERING
01Contact coordinatesRequired fields
02Mission profileFor a focused session

By submitting, you agree that Kybernao may contact you about this request.