Detection Engineering

Sixteen steps to Domain Admin. Here is where the chain breaks.

A red team took a large enterprise from one compromised laptop to full domain control in sixteen sequential steps. Eight were detected. The domain fell anyway.

SR
Setu Research
August 22, 2026·13 min read

Sixteen steps to Domain Admin. Here is where the chain breaks.

A red team took a large enterprise from one compromised laptop to full domain control in sixteen sequential steps. Eight of them were detected. The domain fell anyway. The failure was sequencing, not sensing, and that is a solvable problem.

A red team recently published a one-page teardown of how they took a large enterprise from a single compromised laptop to full Domain Admin. Sixteen sequential steps, five phases, and a footer that reads: 15 control failures. Entire chain executable in hours.

The interesting part isn't the failures. It's the successes.

Eight of the sixteen steps were detected — seven of them marked "Detected & Incident Raised." The EDR saw the shell pop. It saw the Active Directory enumeration. It saw the SSH tunnel to the red team's C2. It saw the password spray. It saw the WMI remote execution. It saw a Domain Admin account being used interactively on a member server.

Eight detections. Seven incidents raised. The domain fell anyway, in hours.

That is the fact every SOC roadmap has to survive. The instinct after an exercise like this is to go build the seven missing detections — an RMM use case for the TeamViewer install, a port rule for the RDP-over-443 backdoor, something for the shadow copy. Close the gaps. Get to sixteen for sixteen.

It wouldn't have helped. The team that ignored eight detections would have ignored sixteen.

The failure was sequencing, not sensing

Look at what those eight detections looked like on a console. Each arrived as an independent row, with its own timestamp, its own host, its own severity, and no relationship to the row above it. "Suspicious executable detected" on a laptop at 14:02. "LDAP enumeration" from that laptop at 14:40. "Anomalous authentication" against thirty hosts at 16:15. "WinRM remote execution" at 17:30.

To a human triaging a queue, those are four tickets. To the attacker, they were four rungs of one ladder, and the ladder had a top.

This is the structural problem with detection-first operations: severity is assigned to the event, not to the position. An alert about a laptop is a low-severity alert about a laptop, forever — no matter that the laptop just acquired a two-hop path to the domain's crown jewels. Nothing in the pipeline recomputes what an alert means after the graph changes underneath it.

Setu is built the other way round. Every entity in the estate carries a live answer to one question: how far is this from something that matters, and who is standing on it right now? An event doesn't just raise an alert — it moves a node in a graph, and the graph recomputes reach. When reach to a crown jewel changes, that is the signal, and that is what gets escalated, paged, ticketed, and contained.

Here is what a fully deployed Setu does to each of the sixteen steps.

Phase 1 — Initial landing zone

Step 0. Initial access on an employee laptop. This is the endpoint control's job, and we don't claim it. What Setu does the instant that laptop is touched is different: the host becomes a scored node. Its blast radius, its reachability to every crown-jewel target, and its EDR coverage state are already computed — because they were computed before the attacker arrived, and they get recomputed as the attacker moves. Nothing about the response to step 0 has to wait for triage.

Step 1. TeamViewer, AnyDesk and VNC installed for persistence. The teardown marks this "Low Alert — need to build custom use case," which is the honest state of most estates: remote-access tooling is legitimate somewhere, so nobody writes the rule.

Setu's endpoint agent inventories this as posture, not as an alert. The inventory and process modules enumerate installed software and running processes across every managed host on a fixed interval; unsanctioned remote-access tooling on a host that can reach a crown jewel is a finding with an owner, not a low-severity event in a queue. Where it is an event — a fresh install, on a host that shouldn't have one — the SOAR playbook is short: notify to the SOC channel, create_ticket to the asset owner, and agent_response with kill-process-tree plus host-deny against the RMM rendezvous destination.

Step 2. PowerShell and CMD unrestricted; interpreters installed. Detected by the EDR, and it should be. Setu's contribution is that the detection lands on a node, not in a list: the execution binds to the laptop entity, joins the campaign object with everything else that host has done, and inherits the campaign's crown-jewel distance as its priority. A "suspicious executable" on a host two hops from a Domain Admin is a different object than the same alert on an isolated kiosk, and only the graph knows the difference.

Phase 2 — Recon and tunnel

Step 3. Wide-open AD enumeration. LDAP reachable from every endpoint; the whole directory — users, servers, groups, misconfigurations — enumerated in one pass.

Two things happen. First, this is a reachability-changing event: the attacker has just converted a laptop into a map of the estate, and Setu treats directory enumeration from a non-administrative endpoint as an escalation trigger, not an informational one. Second, and more important, Setu already ran that enumeration itself. The AD exposure engine reads the directory on a schedule and emits findings independent of any attacker — AD-KERBEROAST, AD-PRIV-SPRAWL, AD-STALE-ADMIN, AD-DISABLED-PRIV, AD-UNCONSTRAINED-DELEG, AD-PWD-NEVER-EXPIRES, AD-PWD-NOT-REQUIRED, AD-ASREP-ROAST — each stamped by the reachability pass with whether the exposed account can reach a crown jewel. Everything the red team learned in step 3, the defender was already holding, ranked, with fixes attached.

Step 4. Outbound SSH tunnel to the red team's C2. Setu's threat-match layer runs every outbound observable through a two-stage Bloom-and-exact matcher against tenant threat indicators, in the ingest path, at line rate. A known-bad destination matches on the first event. An unknown one still lights up as a new external edge from a host that has never had one.

Playbook: notify at high severity, enrich the destination, and block_ip — pushed through the firewall or proxy integration, or firewall-drop on the endpoint agent itself when the network control isn't reachable. Cutting egress here ends the exercise at step 4, because every subsequent step in the teardown ran through that tunnel.

Phase 3 — Privilege escalation

This is the phase that turns a foothold into an empire, and it is the phase where Setu's argument is strongest — because every rung in it was pre-existing and observable weeks before the exercise started. None of it required an attacker to be present.

Step 5. LAPS abused — Everyone can read local admin passwords. A directory permission, sitting there, readable by any authenticated user. The moment those passwords are used, the outcome is an identity valid where it has no business being — and that is exactly the shape Setu's identity layer is built to see. Peer-cohort analysis groups identities by organizational position and flags the ones whose blast radius deviates from their peers; a local-admin credential suddenly authenticating far outside its cohort is an anomaly by construction, not by rule.

Step 6. Password spray — one hundred local admin accounts sharing one weak password; one local-admin identity valid on thirty-plus systems. This is the rung that mattered most, and it is the clearest illustration of the whole thesis.

As an event, a password spray is a burst of failed authentications — noisy, common, and easy to tune out. As structure, it is one identity with an edge to thirty-plus hosts, which is an identity fan-out no legitimate local admin account should ever have. Setu's blast-radius model computes that fan-out continuously, weights it by HRIS status (a terminated or transferring employee's residual access is amplified, because that access outlives the lifecycle event), and scores it against the identity's peer cohort.

An account like that is a critical finding before the spray, purely from how many machines it can touch. During the spray it is a critical alert with a containment action already bound to it: notify critical, create_ticket, and disable-account plus force-logoff through the endpoint agent — the two verbs that end the credential's usefulness in the same minute it's proven.

Step 7. WMI remote execution; RDP enabled remotely. Here the graph moves. A foothold that could previously only talk to endpoints can now execute on servers, and the crown-jewel distance for that campaign drops. This is precisely the delta Setu escalates on: not "WinRM was used" (thousands of times a day, legitimately) but "WinRM was used by a host whose reach just extended to a crown-jewel-adjacent server." Page, critical, with network-isolate on the source host attached and reversible via network-restore.

Fix steps 5, 6 and 15 and there is no Phase 3. Without Phase 3, the laptop stays a laptop.

Phase 4 — Credential harvest

Step 8. Servers reached through segmentation gaps, including the OT network. This is the question Setu exists to answer, and it answers it before anyone asks.

Crown-jewel reachability computes, for a declared crown-jewel set, every host with a path to it, the hop count, and — critically — the bridge set: the hop-1 cut candidates. On a live customer estate, a single privileged account showed 231 hosts with a path to it, a large fraction of them with no EDR coverage at all. The engine turns that into ranked recommendations, worst case first: this host is a choke point on a path to this crown jewel and has no EDR coverage — deploy coverage and isolate its path; cutting this bridge removes the most reach and closes the biggest blind spot.

That is not an alert. It is a list of the specific edges you cut to make step 8 impossible, ranked by how much reach each cut removes, available on day one of deployment with no attacker involved.

Step 9. New local admin accounts created for persistence. Account creation on a crown-jewel-adjacent server is one of the highest-signal events in the entire chain, because it has almost no legitimate emergency use. Setu binds the new principal into the identity graph immediately, which means its blast radius is known within one cycle rather than discovered during the next incident. Playbook: page critical, disable-account, and open the ticket against the server's owner from CMDB.

The value here is durability. Campaign objects carry a stable operation key across days, so a persistence account created on a Friday is still attached to the same narrative on Monday — it does not age out of a console as an unrelated stale ticket.

Step 10. Backdoor RDP tunnelled over TCP 443 via PortProxy. The technique is designed to defeat port-based controls, and it does. What it cannot defeat is the graph: whatever port it rides on, an RDP session from the foothold to a server is a lateral-movement edge, and that edge changes reachability. Setu escalates the movement, not the transport — which is why the tunnel's cleverness buys the attacker nothing.

Step 11. Shadow copy and SAM/Security hive exfiltration. The credential-theft step. Setu's answer is the outbound side and the consequence side: the exfiltration destination runs through the same threat-match and egress path as step 4, and every credential recovered from those hives belongs to an identity whose blast radius is already computed — so "which accounts were in that hive, and what can each of them reach" is a query, answered in seconds, rather than a week of forensic reconstruction. That is the difference between scoping an incident and guessing at it.

Phase 5 — Domain Admin

Step 12. EDR disabled on the database server. The teardown marks this NO ALERT, and correctly: a disabled agent does not send an alert announcing it has been disabled.

Setu's coverage model treats this as a first-class question rather than a byproduct. Every host in the crown-jewel reachability set carries its coverage state, and an EDR-blind host that can reach a crown jewel is the single worst cell in the matrix — it is exactly the case the recommendation engine ranks first. Whether the agent was never installed, was uninstalled, or was switched off, the host lands in the same bucket: reachable, and unwatched. On the estate above, that combination was the top-ranked recommendation before any exercise was run.

Step 13. A server nobody knew existed — not in the CMDB, security team unaware. You cannot protect what you have not enumerated, and an inventory built only from what hosts report will never contain a host that reports nothing.

Setu's answer is discovery that does not require the target's cooperation: passive discovery builds asset records from the traffic a host's neighbours generate — the sessions to it, the authentications against it, the name resolutions for it. Asset unification then folds those records into the canonical inventory by serial, FQDN, IP, MAC and hostname, and CMDB sync reconciles what is there against what the CMDB claims. A shadow server that talks to anything at all becomes an asset with an owner gap, which is a finding.

Step 14. Domain Admin used interactively, without MFA or conditional access. A posture finding in the purest sense, and one the AD exposure engine reports without any attacker: privileged accounts in routine use, privileged accounts without the controls their privilege demands, privileged sprawl beyond what the org chart justifies. Each stamped with crown-jewel reachability so the remediation queue is ordered by consequence rather than by count.

Step 15. Kerberoasting — Domain Admin accounts carrying service principal names. The teardown marks this NO ALERT, and it is right: requesting a service ticket is a legitimate protocol operation, the cracking happens offline on the attacker's own hardware, and there is nothing to detect. Detection-first security has no answer to step 15. It never will.

Setu's AD-KERBEROAST rule fires at critical when the SPN-bearing account is privileged, and the reachability pass stamps it reachable-to-crown-jewel. The last step of the chain — the undetectable one — becomes a pre-breach finding with an owner, a ticket, and a two-line fix: rotate to a group-managed service account, or strip the SPN.

You do not detect kerberoasting. You delete it. That sentence is the whole product.

Where the chain actually breaks

Five places, and they are not evenly spaced:

Break pointMechanismAttacker's cost
Before step 0AD exposure findings fixed — no kerberoastable DAs, no privileged sprawl, no unconstrained delegationPhase 3 does not exist
Before step 0Crown-jewel bridge cuts + EDR coverage on the blind reachable hostsPhase 4 has no route
Step 4Threat-match on the C2 destination → block_ip / firewall-dropEvery later step ran through this tunnel
Step 6Identity fan-out → disable-account + force-logoffNo credential, no lateral movement
Step 7Reachability delta → network-isolate the sourceFoothold contained one hop before the servers

The first two are the ones that matter most, because they cost the attacker the entire middle of the chain and they require no attacker to be present. The last three are the fallback, and they run in seconds because no human sits between the signal and the action.

The notification design

Not sixteen pages. Three or four, at the rungs where crown-jewel distance changes — each with a playbook already bound to it.

Setu's delivery plane is built for exactly that shape. notify posts to Slack, Teams or a signed webhook. create_ticket opens in Jira or ServiceNow with duplicate detection by grouping key, so a sixteen-step campaign produces one ticket that grows rather than sixteen that get closed individually. Scheduled reports carry executive and alert summaries by email on a daily or weekly cadence, and a weekly campaign digest goes to named recipients. And evidence packs produce a signed, reproducible bundle for any campaign or finding — Ed25519 over a canonical manifest, verifiable offline against a published public key, so when you hand a campaign to a red team, an auditor or a regulator, it verifies without them holding a Setu secret.

Containment is a deliberately narrow vocabulary: isolate, block_ip, kill_process, quarantine_file, enforcement pushed through the EDR, firewall and DLP controls you already own, and agent_response driving the Setu endpoint agent with network-isolate, kill-process-tree, disable-account, force-logoff, firewall-drop, host-deny, quarantine-file and disable-usb. Every verb that can be reversed has its reverse defined — network-isolatenetwork-restore, disable-usbenable-usb.

And every enforcement action is bound to an authority stage per tenant, per provider, per verb: advisory, approval-bounded, policy-bounded, proven, defaulting fail-safe. Day one is advisory — the playbook runs, the recommendation lands, nothing is enforced. Approval-bounded parks the execution and waits for an explicit approve or deny. You promote a verb to enforcing when that playbook has earned it on your estate. Nobody sensible hands automated host isolation to a platform on day one, and a vendor who offers it on day one is selling you an outage.

What it takes

Everything above is what a fully deployed Setu delivers. Fully deployed means four connections, and they are worth naming because the value curve is steep and front-loaded:

  1. A directory read. An AD/LDAP export unlocks the entire exposure engine — the eight rules, the identity graph, and the kerberoasting finding that turns the undetectable last step into a pre-breach critical. This is the single highest-value connection and usually the fastest.
  2. Your existing detection feed. Setu is not an EDR and does not ask you to replace one. Point your existing EDR or SIEM alerts at it and they stop being a queue and start being a campaign, scored by position.
  3. The endpoint agent where you want response. Inventory, process visibility and the containment verbs — including on hosts your EDR does not cover, which is where the reachable blind spots invariably are.
  4. A crown-jewel declaration. Ten minutes of work with the people who know which systems the business cannot lose. Everything reachability-based is measured against that set, and it is the one input no platform can infer for you.

What we'd tell the team that ran this exercise

Not "buy a better detector." They already had one; it fired eight times.

  1. Delete the escalation primitives. Kerberoastable Domain Admins, readable LAPS secrets, one password across a hundred local admins, DAs doing routine work without MFA. All pre-breach, all queryable, no attacker required.
  2. Make severity a function of position, not of rule. The eight alerts that fired were correct and useless because none carried "this host is now two hops from a Domain Admin." Reachability is the field that turns a queue into a priority.
  3. Bind containment to the reachability delta. Three or four pages, at the rungs where distance to the crown jewel actually changes, each with a playbook attached and promoted from advisory to enforcing once it has earned it.

The footer on that teardown said the entire chain was executable in hours. That constraint is not going to loosen. A response loop with a human correlation step in the middle has never once closed inside hours — and it isn't going to start.

The two things that work at that tempo are removing the rungs before anyone arrives, and cutting automatically at the rung that matters. Everything else is a very well-documented account of how you lost the domain.


Written from a real red-team exercise, anonymized.

SR

Setu Research

Setu Security Research