Series · 5 partsTesting the Ransomware PlaybookPart 3 · You are here
- 1They Do Not Break In. They Log In.
- 2Enumeration Cannot Be Prevented. Ask Whether It Was Seen.
- 3Affiliates Do Not Find Novel Paths. They Find Yours.You are here
- 4The Blast Radius Is One Number. Almost Nobody Has Measured It.
- 5The Last Two Steps Are Not in Scope. What Makes Them Survivable Is.
Privilege escalation in 60 seconds
The domain is mapped. Something authenticated is sitting inside it with the rights of whoever’s credential got reused, and the next objective is the only one that matters: become something that can write to everything.
This is the part of the playbook people expect to be sophisticated. It is not. The set of paths in regular use is small, well documented, and years old — and every one of them has already been covered on this site, because they are the same paths an assessment reports.
What is worth writing about is not the techniques. It is the selection criterion.
They optimise for reliability, not for cleverness
An affiliate is working against a clock and cannot afford a path that fails halfway. That constraint filters the option set hard, and it filters it differently than a tester’s curiosity does.
Three properties decide it:
Does it need a human? Anything that depends on an administrator logging in somewhere is a waiting game. Anything that depends only on directory state is available immediately.
Does it survive a reboot? A path built on a token or a live session evaporates. A path built on a permission does not.
How loud is it? Not zero — they accept noise. But they prefer noise that resembles administration to noise that resembles an attack.
Ranked by those criteria, the list collapses to a handful, and it looks exactly like the findings section of a competent internal report.
The inversion that matters for reporting
Look at that ordering against how findings usually get triaged.
Credential dumping from memory is the one everybody has controls for. It is in the EDR product, it is in the detection engineering backlog, it is the thing the tabletop exercise was about. It is also the last thing an affiliate wants to do, because it needs a privileged session to already exist on a box they already control.
The top row — a group that can write to a computer object, a service account with a crackable password, an over-permissioned OU — has no product watching it. It is a state, not an event. Nothing fires when a permission is used as designed.
So the estate is instrumented against the technique of last resort and blind to the ones that get used first.
The three you will actually find
Each of these has its own note on this site; this part is about how they sit together.
Service account passwords. Any user can request a service ticket for any SPN, so the only control is the password behind the account. See Kerberoasting triage for the part that matters — which tickets are worth the GPU time and which are a week wasted.
Write access to computer objects. The most reliable escalation in a modern domain, and
it is not a setting anybody misconfigured — it is a consequence of who holds GenericWrite.
Delegation triage covers why RBCD is the one you find and the
other two are the ones you were taught.
Coerced authentication relayed somewhere unsigned. Requires more of the environment to line up, but when it lines up it is fast. SMB signing is on covers why “signing is enforced” does not close it.
The connection worth stating plainly: the relay path and the delegation path are the same finding. A relay to LDAP writes an RBCD attribute. The prerequisite for the delegation attack is write access to a computer object. One produces the other. Reporting them as two unrelated items is how both end up half-fixed.
Testing it as a chain, not as a list
The single most useful change to how this gets tested is to stop reporting escalation findings individually and start reporting the shortest reliable chain from the starting position.
# What does the position I have actually reach, using only durable edges?
MATCH (u {owned: true})
MATCH p = shortestPath(
(u)-[:MemberOf|AdminTo|GenericAll|GenericWrite|WriteDacl|WriteOwner|
AddAllowedToAct|AllowedToAct|ReadLAPSPassword|ReadGMSAPassword*1..]->
(g:Group {name: 'DOMAIN [email protected]'})
)
RETURN p
Note what is missing from that edge list: HasSession. A chain that depends on somebody
being logged in is a chain that may not exist tomorrow — the same argument as in
the note on edge shelf life, applied to the report rather
than to the collection.
Run it from the position an affiliate would plausibly hold — a standard user, not your domain admin test account — and the output is the finding.
Evidence matrix
| Signal | What it proves | Negative control | Defender verification |
|---|---|---|---|
| Durable ACL, delegation, or service-account edge exists from the foothold | A deterministic escalation route is already encoded in configuration | Remove the earliest edge in a lab copy and recompute the path | Re-collect DACLs, delegation, and service ownership with nested membership expanded |
| Relay prerequisites compose from a coercible source to a writable target | The conditional route is operational, not a list of weak settings | Harden either source or destination and expect the chain to break | Track protocol-pair prerequisites instead of treating signing as one global control |
| Privileged credential appears only while a specific admin session exists | The route is transient and depends on timing | Log the administrator off and confirm the credential path disappears | Enforce tiered logon and correlate privileged sessions with endpoint exposure |
| Chain starts from the same standard-user position used in initial access | Severity reflects a plausible attacker starting point | Repeat from a principal without the required group/host access | Reproduce the full path under the least-privileged assumed foothold |
The pattern I keep seeing
The permissions that make the top row work were granted for a reason that made sense and then outlived it. A group given rights over an OU so somebody could join machines. A service account created during a deployment with a password typed into a config file. An exemption for an integration that could not do modern auth.
None of them were mistakes when they were made. All of them are load-bearing for an escalation path now, and none of them will be found by scanning for vulnerabilities, because none of them are vulnerabilities. They are decisions nobody revisited.
What to hand the defenders
The chain, with the weakest link named. Not six findings — one path, and the single permission whose removal breaks it. That is the thing that fits in a sprint.
Say which controls do not apply. If the chain never touches memory, say so explicitly. Otherwise the response will be to tune the EDR policy, which changes nothing about the path you just walked.
Separate the state findings from the event findings. Permissions and service account passwords are state: they are fixed by changing configuration, and they stay fixed. Credential exposure is an event: it is managed by detection. They belong to different teams and different timelines, and merging them into one “privilege escalation” section guarantees the slower half never happens.
Next in this series: credential access and lateral movement — and what detection actually catches once the affiliate stops needing new privileges.
How current is this note?
The latest source-review, content-update, or publication date is shown.
The author completed a technical review. This does not, by itself, claim lab reproduction.
