Last reviewed

Reconnaissance

Active Directory Enumeration

Active Directory enumeration reveals the domain structure, user accounts, group memberships, and trust relationships essential for planning attack paths.

Domain Information

Basic Domain Info

powershell
# From Windows (domain-joined)
echo %USERDOMAIN%
echo %USERDNSDOMAIN%
echo %LOGONSERVER%
nltest /dclist:%USERDOMAIN%
nltest /domain_trusts

# PowerShell
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
Get-ADDomain
Get-ADForest
# From Windows (domain-joined)
echo %USERDOMAIN%
echo %USERDNSDOMAIN%
echo %LOGONSERVER%
nltest /dclist:%USERDOMAIN%
nltest /domain_trusts

# PowerShell
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
Get-ADDomain
Get-ADForest

LDAP Enumeration

bash
# Get domain info via LDAP
ldapsearch -x -H ldap://DC_IP -b "" -s base defaultNamingContext
ldapsearch -x -H ldap://DC_IP -b "" -s base namingContexts

# Get domain functional level
ldapsearch -x -H ldap://DC_IP -b "DC=corp,DC=local" -s base domainFunctionality

# Password policy
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=domain)" \
  minPwdLength maxPwdAge minPwdAge pwdHistoryLength lockoutThreshold lockoutDuration
# Get domain info via LDAP
ldapsearch -x -H ldap://DC_IP -b "" -s base defaultNamingContext
ldapsearch -x -H ldap://DC_IP -b "" -s base namingContexts

# Get domain functional level
ldapsearch -x -H ldap://DC_IP -b "DC=corp,DC=local" -s base domainFunctionality

# Password policy
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=domain)" \
  minPwdLength maxPwdAge minPwdAge pwdHistoryLength lockoutThreshold lockoutDuration

User Enumeration

LDAP User Queries

bash
# All users
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName

# Users with descriptions (often contain hints)
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(&(objectClass=user)(description=*))" \
  sAMAccountName description

# Find disabled accounts
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))"

# Users who haven't changed password recently
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName pwdLastSet
# All users
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName

# Users with descriptions (often contain hints)
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(&(objectClass=user)(description=*))" \
  sAMAccountName description

# Find disabled accounts
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))"

# Users who haven't changed password recently
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName pwdLastSet

PowerView User Enumeration

powershell
# Import PowerView
Import-Module .\PowerView.ps1

# All domain users
Get-DomainUser | Select-Object samaccountname, description, memberof

# Specific user details
Get-DomainUser -Identity administrator

# Users with SPNs (Kerberoasting targets)
Get-DomainUser -SPN

# Users with "Do not require Kerberos preauthentication" (AS-REP roast)
Get-DomainUser -PreauthNotRequired

# Users with "Password never expires"
Get-DomainUser -PasswordNeverExpires

# Recently logged on users
Get-DomainUser -Properties lastlogon | Sort-Object lastlogon -Descending | Select-Object -First 20
# Import PowerView
Import-Module .\PowerView.ps1

# All domain users
Get-DomainUser | Select-Object samaccountname, description, memberof

# Specific user details
Get-DomainUser -Identity administrator

# Users with SPNs (Kerberoasting targets)
Get-DomainUser -SPN

# Users with "Do not require Kerberos preauthentication" (AS-REP roast)
Get-DomainUser -PreauthNotRequired

# Users with "Password never expires"
Get-DomainUser -PasswordNeverExpires

# Recently logged on users
Get-DomainUser -Properties lastlogon | Sort-Object lastlogon -Descending | Select-Object -First 20

Group Enumeration

bash
# LDAP - All groups
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=group)" cn

# Domain Admins members
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "CN=Domain Admins,CN=Users,DC=corp,DC=local" member

# PowerView - Privileged groups
Get-DomainGroup -Identity "Domain Admins" | Select-Object -ExpandProperty member
Get-DomainGroup -Identity "Enterprise Admins" | Select-Object -ExpandProperty member
Get-DomainGroup -Identity "Administrators" | Select-Object -ExpandProperty member

# All groups for a user
Get-DomainGroup -UserName "targetuser"

# Nested group membership
Get-DomainGroupMember -Identity "Domain Admins" -Recurse
# LDAP - All groups
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=group)" cn

# Domain Admins members
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "CN=Domain Admins,CN=Users,DC=corp,DC=local" member

# PowerView - Privileged groups
Get-DomainGroup -Identity "Domain Admins" | Select-Object -ExpandProperty member
Get-DomainGroup -Identity "Enterprise Admins" | Select-Object -ExpandProperty member
Get-DomainGroup -Identity "Administrators" | Select-Object -ExpandProperty member

# All groups for a user
Get-DomainGroup -UserName "targetuser"

# Nested group membership
Get-DomainGroupMember -Identity "Domain Admins" -Recurse

High-Value Groups

Group Risk Level Privileges
Domain Admins Critical Full domain control
Enterprise Admins Critical Forest-wide control
Backup Operators High Can backup DC, extract NTDS.dit
Account Operators High Create/modify accounts
Server Operators Medium Manage DC services
DNSAdmins Medium DLL injection on DC

Computer Enumeration

bash
# LDAP - All computers
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=computer)" \
  name operatingSystem operatingSystemVersion

# PowerView - Computers
Get-DomainComputer | Select-Object name, operatingsystem, dnshostname

# Find servers
Get-DomainComputer -OperatingSystem "*Server*"

# Find workstations
Get-DomainComputer -OperatingSystem "*Windows 10*"

# Find old/vulnerable systems
Get-DomainComputer | Where-Object {$_.operatingsystem -like "*2008*" -or $_.operatingsystem -like "*2003*" -or $_.operatingsystem -like "*Windows 7*"}

# Computers with unconstrained delegation
Get-DomainComputer -Unconstrained
# LDAP - All computers
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "DC=corp,DC=local" "(objectClass=computer)" \
  name operatingSystem operatingSystemVersion

# PowerView - Computers
Get-DomainComputer | Select-Object name, operatingsystem, dnshostname

# Find servers
Get-DomainComputer -OperatingSystem "*Server*"

# Find workstations
Get-DomainComputer -OperatingSystem "*Windows 10*"

# Find old/vulnerable systems
Get-DomainComputer | Where-Object {$_.operatingsystem -like "*2008*" -or $_.operatingsystem -like "*2003*" -or $_.operatingsystem -like "*Windows 7*"}

# Computers with unconstrained delegation
Get-DomainComputer -Unconstrained

GPO Enumeration

powershell
# PowerView - List GPOs
Get-DomainGPO | Select-Object displayname, gpcfilesyspath

# GPOs applied to specific computer
Get-DomainGPO -ComputerName "DC01.corp.local"

# Find GPOs with interesting settings
# GPOs that modify local admins
Get-DomainGPOLocalGroup

# GPOs with scheduled tasks
Get-DomainGPO | ForEach-Object {
    $gpoPath = $_.gpcfilesyspath
    if (Test-Path "$gpoPath\Machine\Preferences\ScheduledTasks") {
        Write-Host "Scheduled tasks in: $($_.displayname)"
    }
}

# GPO permission abuse
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=corp,DC=local" -ResolveGUIDs | \
  Where-Object {$_.ActiveDirectoryRights -match "WriteProperty|GenericAll"}
# PowerView - List GPOs
Get-DomainGPO | Select-Object displayname, gpcfilesyspath

# GPOs applied to specific computer
Get-DomainGPO -ComputerName "DC01.corp.local"

# Find GPOs with interesting settings
# GPOs that modify local admins
Get-DomainGPOLocalGroup

# GPOs with scheduled tasks
Get-DomainGPO | ForEach-Object {
    $gpoPath = $_.gpcfilesyspath
    if (Test-Path "$gpoPath\Machine\Preferences\ScheduledTasks") {
        Write-Host "Scheduled tasks in: $($_.displayname)"
    }
}

# GPO permission abuse
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=corp,DC=local" -ResolveGUIDs | \
  Where-Object {$_.ActiveDirectoryRights -match "WriteProperty|GenericAll"}

Trust Enumeration

bash
# PowerView - Domain trusts
Get-DomainTrust
Get-ForestTrust

# nltest
nltest /domain_trusts /all_trusts

# LDAP - Trust relationships
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "CN=System,DC=corp,DC=local" "(objectClass=trustedDomain)"

# Trust direction:
# Bidirectional - Can authenticate both ways
# Inbound - External domain trusts this domain
# Outbound - This domain trusts external domain
# PowerView - Domain trusts
Get-DomainTrust
Get-ForestTrust

# nltest
nltest /domain_trusts /all_trusts

# LDAP - Trust relationships
ldapsearch -x -H ldap://DC_IP -D "user@corp.local" -W \
  -b "CN=System,DC=corp,DC=local" "(objectClass=trustedDomain)"

# Trust direction:
# Bidirectional - Can authenticate both ways
# Inbound - External domain trusts this domain
# Outbound - This domain trusts external domain

BloodHound Collection

Tip

BloodHound provides visual attack path analysis. Collect data with SharpHound, then import into BloodHound for analysis.
bash
# SharpHound collection
# Full collection (noisy)
.\SharpHound.exe -c All

# Stealthier - skip session collection
.\SharpHound.exe -c DCOnly

# Session collection (requires admin on targets)
.\SharpHound.exe -c Session

# From Linux with bloodhound-python
bloodhound-python -u user -p password -d corp.local -dc DC01.corp.local -c All

# Import resulting JSON files into BloodHound
# Look for:
# - Shortest path to Domain Admin
# - Kerberoastable users
# - AS-REP roastable users
# - Unconstrained delegation
# SharpHound collection
# Full collection (noisy)
.\SharpHound.exe -c All

# Stealthier - skip session collection
.\SharpHound.exe -c DCOnly

# Session collection (requires admin on targets)
.\SharpHound.exe -c Session

# From Linux with bloodhound-python
bloodhound-python -u user -p password -d corp.local -dc DC01.corp.local -c All

# Import resulting JSON files into BloodHound
# Look for:
# - Shortest path to Domain Admin
# - Kerberoastable users
# - AS-REP roastable users
# - Unconstrained delegation

Impacket Enumeration

bash
# Get users
GetADUsers.py -all -dc-ip DC_IP corp.local/user:password

# Find SPNs
GetUserSPNs.py -dc-ip DC_IP corp.local/user:password

# Find AS-REP roastable
GetNPUsers.py -dc-ip DC_IP corp.local/ -usersfile users.txt -no-pass

# Dump AD info
ldapdomaindump -u 'corp.local\user' -p 'password' DC_IP

# Enumerate shares
smbclient -L //DC_IP -U 'user%password'
# Get users
GetADUsers.py -all -dc-ip DC_IP corp.local/user:password

# Find SPNs
GetUserSPNs.py -dc-ip DC_IP corp.local/user:password

# Find AS-REP roastable
GetNPUsers.py -dc-ip DC_IP corp.local/ -usersfile users.txt -no-pass

# Dump AD info
ldapdomaindump -u 'corp.local\user' -p 'password' DC_IP

# Enumerate shares
smbclient -L //DC_IP -U 'user%password'

Quick Reference

Target Tool Value
Users with SPNs GetUserSPNs.py Kerberoasting targets
No preauth users GetNPUsers.py AS-REP roasting
Privileged groups PowerView High-value targets
Attack paths BloodHound Visual path analysis
Unconstrained deleg PowerView TGT capture targets