Every domain compromise follows a pattern. Not the same one every time - but close enough that you can predict the next move if you understand what came before. This post walks through a sanitized real-world intrusion - credential theft, lateral movement, Kerberoasting, DCSync, the full chain - from the IR side. I'll keep the attacker's actions at the level of what they achieved and why it worked, and focus on where the defense broke and where it should have caught them.
Initial Access: The Phishing Email That Worked
The story starts like most do - a well-crafted phishing email to the marketing department with a fake invoice attachment. It was an Excel file with embedded macros.
The user enabled macros, and a macro launched an encoded PowerShell command that pulled down a second-stage payload and established a command-and-control channel back to attacker infrastructure.
The First Mistake
The payload ran as the user's standard domain account - not admin. And that is an important detail, because it constrains what came next.
The initial access doesn't need to be privileged. It just needs a foot in the door and an account that's alive on the network.
Why the Attacker Couldn't Dump Credentials Yet
Here's the logic that a lot of intrusion write-ups skip: a payload running as a standard user cannot read LSASS. Dumping credentials from memory requires local administrator rights (specifically the debug privilege that comes with them). So at this moment the attacker had code execution, but no credentials beyond the phished user's own.
What unlocked the rest was two local misconfigurations lining up:
- The phished user was a local administrator on their own workstation - left over from a one-time software install that never got walked back. That gave the attacker the local admin rights needed to access LSASS on that machine.
- An IT administrator had recently logged on interactively to that same workstation to troubleshoot something, and that admin's credentials were still cached in memory.
With local admin on the workstation, the attacker read LSASS and recovered the IT admin's credential material. Standard user to privileged credentials, in one hop, because a privileged account had touched an under-protected machine.
Lateral Movement: Finding the Path
With a privileged hash in hand, the attacker used pass-the-hash to authenticate as the IT admin - reusing the stolen NTLM hash directly, no password needed. (Pass-the-hash reuses a stolen hash to authenticate; it is not the same as an NTLM relay, which forwards a live authentication attempt. This was the former.)
They mapped the environment and found a short path to privilege: the IT admin account had access to IT-01, a management server that had an active session for svc_backup - a service account that, years earlier, had been granted directory replication rights. Replication rights mean DCSync. That was the prize.
The Missing Control
This is where the defense failed structurally: privileged credentials were exposed on machines that weren't treated as privileged. The IT admin logging into an ordinary workstation, and svc_backup holding replication rights it no longer needed, are the same class of mistake - Tier 0 access leaking into Tier 1 and Tier 2 systems.
Kerberoasting: The Shortcut They Didn't Need (But Took Anyway)
With svc_backup's access the attacker already had a route to DCSync, so they didn't need to Kerberoast. But attackers aren't always optimal, and this one roasted every service account they could find - cheap insurance and a backup way back in.
What they found: 12 accounts with SPNs, three of them in privileged groups, and passwords weak enough to crack offline.
Why this matters for IR: even after they held domain-level control, those cracked service-account passwords were a persistence vector. If they lost their primary foothold, they could log straight back in through the cracked service account passwords - which is exactly why remediation has to include every roastable account, not just the obviously privileged ones.
DCSync: Getting the Hashes
This is when the real damage started. Using svc_backup's replication rights, the attacker performed a DCSync - asking a domain controller to replicate account secrets to them, exactly as a legitimate DC would during normal replication. That's what replication rights allow, and it's why granting them to a service account is so dangerous.
What DCSync Gives You
- Every password hash in the domain - including the KRBTGT hash, which forges Kerberos TGTs.
- Golden ticket capability - with the KRBTGT hash, the attacker can forge tickets for any principal in the domain.
- Persistent access - resetting a user's password doesn't invalidate an already-forged ticket.
One correction to a claim I hear constantly: the KRBTGT hash is per domain, not per forest. In a multi-domain forest each domain has its own KRBTGT. But don't read that as containment: the forest, not the domain, is the security boundary in Active Directory. An attacker who fully controls one domain can usually escalate to the rest of the forest, so if you run multiple domains, scope your investigation and recovery forest-wide.
At this point the domain was effectively owned. The attacker held the KRBTGT hash, replication rights, and multiple cracked service accounts as fallback.
What the Logs Showed (And What They Missed)
The events were all there. They just didn't get triaged.
Day -2: The Phishing Email
- Email gateway flagged the attachment as malicious - flagged, not blocked.
- No ticket created; logged as medium severity.
Day -1: Macro Execution
- EDR logged powershell.exe with an encoded command making an outbound connection.
- Alert raised at medium severity and auto-closed.
Day 0: Escalation and Replication
- 4624: IT admin account logon to IT-01 originating from a marketing workstation - anomalous, flagged, not investigated.
- 4769: RC4 service-ticket requests for 12 SPNs from a single account within seconds - Kerberoasting shows up here, in service-ticket requests, not in 4768. Below the volume threshold, so it didn't alert.
- 4662: a replication (DCSync) operation from a non-DC account - logged, not alerted as critical.
None of these fired a response on their own. In aggregate they tell a clear story. By the time anyone read them together, the domain was already gone.
Recovery: What Actually Worked
The organization recovered. Here's what it took:
- Reset every password - not just privileged accounts. Service accounts, admin accounts, standard users, all of them.
- Reset KRBTGT twice - KRBTGT keeps a current and a previous key, so a single reset leaves the old key valid. Two resets, with enough time between them for the first to replicate to every DC, invalidate stolen key material. A third reset adds nothing but risk - it does not make the domain "more reset." Two, done correctly, is the answer. This is also what invalidates outstanding Kerberos tickets - there is no separate "revoke all tickets" step to perform; forcing re-authentication is a consequence of the double KRBTGT reset.
- Purge cached credentials - every workstation and server; forced logoff where possible.
- Rebuild compromised systems - IT-01 and the phished workstation were reimaged from known-good media.
What didn't work: changing the admin's password once. With golden ticket capability, a single password change doesn't invalidate a forged TGT.
The Fixes That Came After
- Local admin cleanup - removed local admin from anything that didn't need it; deployed LAPS so local admin passwords are unique per machine.
- Privileged access tiering - stopped IT admins from logging interactively into ordinary workstations; the credential-in-memory exposure that started this chain simply shouldn't be possible.
- Replication-rights audit - found and removed the stale rights on svc_backup and reviewed every non-DC principal holding them.
- DCSync alerting - alert on 4662 replication requests from non-DC accounts.
- Kerberoasting visibility - tuned 4769 detection for RC4 bursts across many SPNs from one account.
- Phishing response - macro-enabled attachments from external senders are blocked outright, not flagged.
The domain wasn't compromised because the attacker was sophisticated. It was compromised because the environment had the same gaps every environment has - local admin sprawl, privileged accounts touching unprivileged machines, under-monitored service accounts, and alerts that didn't tell a story until it was too late.