Series · 5 partsTesting the Ransomware PlaybookPart 2 · You are here
- 1They Do Not Break In. They Log In.
- 2Enumeration Cannot Be Prevented. Ask Whether It Was Seen.You are here
- 3Affiliates Do Not Find Novel Paths. They Find Yours.
- 4The Blast Radius Is One Number. Almost Nobody Has Measured It.
- 5The Last Two Steps Are Not in Scope. What Makes Them Survivable Is.
The first authenticated hour in 60 seconds
A credential worked. Something is now authenticated inside the domain, and the next hour is spent finding out where it landed and what it can reach.
That hour is not exotic either. It is a directory collection — the same one you run, often with the same tool. Which creates an awkward problem for the report, because directory enumeration is not a vulnerability. Any authenticated principal can read the directory. That is not a misconfiguration; it is what a directory is for.
So there is no finding to write about the enumeration itself. The finding is about whether anybody noticed.
The question the engagement usually destroys on day one
Almost every internal assessment starts with the tester’s source address being allowlisted, so the SOC does not spend a week chasing an authorised activity. It is a reasonable operational decision and it is made almost reflexively.
It also throws away the single most valuable measurement available: would this have been caught?
The enumeration is going to happen either way. The affiliate will do it, you will do it, and neither of you can be stopped from doing it. The only thing that separates the two events is that one of them gets investigated. Whether that investigation would actually start is a testable property — and allowlisting is the one decision that guarantees it goes untested.
Loud and quiet are a choice, and the difference is enormous
Collection is not one behaviour. It is a set of them with wildly different detection surfaces, and the affiliate picks the same way you do.
A DC-only collection is one authenticated session reading LDAP. Everything an attack graph needs structurally — objects, memberships, ACLs, delegation, trusts — comes from there. It is quiet because nothing else is touched.
Session collection is the opposite. To learn who is logged in where, the collector has to ask every host, which means an authentication event and a share access on all of them, from one source, in a very short window. That shape — one account, hundreds of destinations, minutes apart — does not occur in normal operation.
Worth connecting to the earlier note on edge shelf life: the loud half of collection is the half that produces the perishable edges. The affiliate pays a large detection cost for the data that expires fastest.
Testing it properly
Run it twice, and treat the difference as the deliverable.
# Quiet pass — structural data only, one host touched.
$ bloodhound-python -d lab.local -u svc-audit -p '...' -c DCOnly -ns 10.0.0.10
# Loud pass — session data, fans out across the estate.
$ bloodhound-python -d lab.local -u svc-audit -p '...' -c Session,LoggedOn -ns 10.0.0.10
Then ask for the other side of it. Not “did you block this” — nothing blocked it — but what was recorded and what, if anything, fired:
Event 4662 directory object access — the LDAP reads, if object auditing is on at all
Event 4624 logon type 3 — one account, on every host, within minutes
Event 5145 network share object checked — IPC$ on each of those hosts
The gap between “these events exist in the log” and “somebody was told” is the entire finding. In most estates the events are there. Nothing consumes them.
The cheapest detection nobody has deployed
A canary object costs nothing and catches exactly this behaviour.
Create a user that looks worth having — a plausible name, an SPN, membership that suggests privilege — and that no legitimate process has any reason to touch. It is not a defence; it cannot stop anything. It is a tripwire, and its value is that it has essentially no false positive rate. Nothing in normal operation queries an object nobody uses.
Any collection sweeps it up. Any Kerberoast requests a ticket for it. The alert is unambiguous in a way that volume-based detection on legitimate directory reads never is.
Evidence matrix
| Signal | What it proves | Negative control | Defender verification |
|---|---|---|---|
| DC-only collection completes with LDAP telemetry confined to domain controllers | A quiet graph can be built without touching every endpoint | Compare with session collection from the same host and time window | Baseline query volume and object classes on domain controllers |
| Session collection produces authentication/share events across many hosts | The noisy profile creates a distributed, correlatable footprint | Run DC-only collection and confirm the endpoint fan-out disappears | Correlate one source reaching an unusual percentage of workstations in minutes |
| Canary SPN or directory object is queried during collection | A near-zero-noise tripwire detects enumeration intent | Confirm ordinary administrative workflows never touch the canary | Alert on reads or ticket requests involving the canary and periodically test delivery |
| Collection from a standard-user foothold yields a usable path | The exposure is reachable from a plausible first-hour position | Run the same query from a deliberately restricted segment/account | Validate directory read restrictions, network tiering, and telemetry from the starting zone |
The pattern I keep seeing
Directory enumeration sits in a gap between two teams. It is not a vulnerability, so it does not appear in a pentest report. It is not malware, so it does not trigger the endpoint product. The telemetry exists and goes to a platform where nobody has written a rule for it, because writing that rule requires knowing what normal directory access looks like in that specific estate — and that is a project, not a ticket.
So it stays unwatched, and the loudest hour of the entire intrusion passes unremarked.
What to hand the defenders
Push back on the allowlist, at least once. Ask for one unannounced collection window before the address goes on the list. It costs the SOC an hour and it answers a question no other part of the engagement will.
Report the detection gap as its own finding. “Directory enumeration generated 4624 and 5145 on every host in the estate and produced no alert” is a finding. It has a specific, achievable remediation, and it is more actionable than most of the vulnerabilities in the same report.
Recommend the canary. It is a single object, it needs no product, and it converts an undetectable-by-default behaviour into a high-confidence alert.
The affiliate cannot be stopped from mapping the domain. They can be watched doing it, and the difference between those two facts is most of the response timeline.
Next in this series: privilege escalation — the specific paths that get used, and why they are the ones already written up in this blog.
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.
