5 Active Directory Attack Paths Every Defender Should Know
Active Directory is where most internal pentests end, and it’s where most real incidents end too. Every organisation with more than a few hundred Windows endpoints has an AD forest, and every forest we’ve tested has had at least one path to domain admin. Usually several.
This post walks through five attack paths we see in almost every engagement, what the tooling looks like, what defenders can expect to see in logs, and what actually fixes each one. If you run a Windows estate, these should all be on your radar — and if they’re not, your adversary’s already ahead.
1. Kerberoasting
Any user with an SPN set on their account can be Kerberoasted. The attacker asks a domain controller for a service ticket, which is encrypted with the target account’s NTLM hash derived from its password. That ticket is crackable offline with Hashcat. If the service account password is weak — and service account passwords are almost always weak because nobody rotates them — the attacker gets plaintext creds without ever authenticating as the target.
Tooling is simple. From a domain-joined machine with any valid user:
Rubeus.exe kerberoast /outfile:hashes.txt
# or from Linux
GetUserSPNs.py -dc-ip 10.0.0.1 DOMAIN/user:password -request
Defenders: watch for Event ID 4769 with encryption type 0x17 (RC4). Modern accounts should be issuing AES tickets; a flood of RC4 requests from one user in a short window is a strong signal. Fix: rotate all service account passwords to 25+ characters, enable AES-only ticket encryption where supported, and move to Group Managed Service Accounts (gMSA) where you can. Audit the list of accounts with SPNs quarterly — most orgs have several that could be retired.
2. DACL abuse — GenericWrite and WriteDacl
Every AD object has an ACL. Over the years, helpdesk scripts, old migrations, and one-off delegations leave user and group objects with DACLs that grant unexpected write rights. An attacker who controls a user with GenericWrite on another user can reset their password, set an SPN for Kerberoasting, or enable shadow credentials. WriteDacl is even worse — it lets the attacker modify the ACL itself and grant full control.
BloodHound is how you find these paths:
SharpHound.exe -c All
# then in BloodHound, query:
# "Shortest Paths to Domain Admins from Owned Principals"
BloodHound maps every DACL edge in the forest and shows you the cheapest path to DA. Defenders rarely see DACL abuse in logs because the events look legitimate — a password reset, a group membership change, a DACL modification. Event IDs 4738 (user changed), 4728/4756 (group membership), and 5136 (directory object modified) need to be monitored centrally with alerting on sensitive objects. Fix: run BloodHound yourself, prune every unexpected edge, and lock down who can modify Tier 0 objects. Treat BloodHound as a quarterly audit tool, not just an attacker tool.
3. ADCS ESC1 and ESC8
Active Directory Certificate Services is the most dangerous thing in most forests because administrators don’t realise what it is. A misconfigured certificate template can be used to mint an authentication certificate for any user — including domain admins — directly from a low-privilege account.
ESC1 means a template allows client authentication, lets the enrollee supply the subject (SAN), and is enrollable by low-privilege users. ESC8 is an NTLM relay against the Web Enrollment endpoint, letting an attacker coerce a domain controller to authenticate and then mint a cert for it. Either one is game over in minutes.
Certipy is the tool:
certipy find -u user@domain.local -p 'password' -dc-ip 10.0.0.1 -vulnerable -stdout
# then for ESC1:
certipy req -u user@domain.local -p 'password' -ca 'DOMAIN-CA'
-template 'VulnTemplate' -upn 'administrator@domain.local'
Defenders: monitor certificate enrolments (Event ID 4886/4887 on the CA) and look for UPN values in issued certs that don’t match the requester. Fix: run certipy find -vulnerable yourself, remediate every template it flags, disable NTLM on the Web Enrollment endpoint or enable EPA, and restrict template enrolment to groups that actually need it. The fix is template-by-template; don’t let the CA admin tell you it’s complicated — that’s the point.
4. Unconstrained delegation
Unconstrained delegation is a Kerberos feature from the NT4 era that nobody should still be using but almost everyone is. When a user authenticates to a service with unconstrained delegation enabled, the service receives the user’s TGT and can impersonate them to any other service in the forest.
If an attacker compromises any server with unconstrained delegation, they can wait for (or coerce) a domain controller’s computer account to authenticate, capture the DC’s TGT, and use it to perform DCSync. Coercion is easy — PetitPotam, PrinterBug, and similar MS-RPC tricks force a DC to auth to an attacker-chosen host.
# enumerate unconstrained delegation hosts
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation
# from attacker host with unconstrained delegation, monitor for incoming tickets
Rubeus.exe monitor /interval:5 /nowrap
Defenders: audit the list quarterly. No computer object other than domain controllers should have TRUSTED_FOR_DELEGATION set. Mark all sensitive accounts “Account is sensitive and cannot be delegated”. Patch the coercion primitives (MS-EFSR, MS-RPRN, MS-DFSNM). Fix: move to constrained delegation with protocol transition only where absolutely needed, and delete unconstrained delegation entirely wherever you can.
5. DCSync
DCSync is the endgame. Any principal with the DS-Replication-Get-Changes and DS-Replication-Get-Changes-All extended rights on the domain object can ask a domain controller to replicate secrets — meaning the krbtgt hash, every user’s NTLM hash, and everything else needed to forge golden tickets and own the forest for as long as you like.
The rights are granted to Domain Admins and Enterprise Admins by default, but over time they get delegated to service accounts for Azure AD Connect, backup solutions, and third-party sync tools. Any compromise of one of those service accounts is a full domain compromise.
secretsdump.py -just-dc DOMAIN/user:password@dc01.domain.local
# or with mimikatz on a compromised admin host:
# lsadump::dcsync /domain:domain.local /user:krbtgt
Defenders: Event ID 4662 with the replication GUIDs (1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 and 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2) is the signal. Any 4662 with those GUIDs from a non-DC account is DCSync. Fix: enumerate everyone who currently has replication rights, remove any account that doesn’t need them, protect the ones that do with hardened service-account policies, and alert on any 4662 event for replication rights outside a known allow-list. Rotate krbtgt twice (24 hours apart) if you have any reason to suspect past compromise — legacy golden tickets stop working instantly.
Layered defence and the tiered admin model
None of these attacks are one-bug problems. They’re symptoms of the same underlying issue: flat privilege models. A helpdesk tech logs into a workstation that also gets a visit from a domain admin, the admin’s credentials get cached or their TGT gets stolen, and the path to DA opens up. The fix is tiering.
Tier 0 is domain controllers and anything that controls them — AD FS, PKI, Entra Connect. Tier 1 is servers. Tier 2 is workstations. Admin accounts at each tier can only log in to assets at that tier, and credentials never cross tier boundaries. Combined with Protected Users, LAPS for local admin passwords, gMSA for service accounts, and quarterly BloodHound audits, you eliminate the vast majority of paths to DA that real attackers use.
None of this is cheap or quick. But every week you leave it unaddressed, somebody with a Kali VM and a lunch hour can walk your forest. That’s the threat model — plan accordingly.