Hacktricks-skills ldap-pentest
Perform LDAP/Active Directory pentesting including enumeration, anonymous access testing, credential attacks, and domain information extraction. Use this skill whenever the user mentions LDAP, Active Directory, directory services, ports 389/636/3268/3269, ldapsearch, windapsearch, ldapdomaindump, or wants to enumerate users/groups/computers from a domain. Also trigger for AD reconnaissance, LDAP brute force, anonymous bind testing, or extracting domain information.
install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest:
skills/network-services-pentesting/pentesting-ldap/SKILL.MDsource content
LDAP Pentesting Skill
A comprehensive guide for testing LDAP and Active Directory services for security vulnerabilities.
Quick Start
# Basic enumeration (anonymous) nmap -p 389,636 --script ldap-search -Pn <IP> # Check anonymous access ldapsearch -H ldap://<IP> -x -s base -b "" "(objectClass=*)" "*" + # With credentials ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' -b "DC=<domain>,DC=<tld>"
LDAP Basics
Default Ports:
- 389/tcp - LDAP (unencrypted)
- 636/tcp - LDAPS (SSL/TLS)
- 3268/tcp - Global Catalog (AD)
- 3269/tcp - Global Catalog SSL (AD)
Directory Structure:
Root (dc=local) ├── Organization (dc=moneycorp,dc=local) │ ├── Organizational Units (ou=it, ou=marketing) │ └── Objects (cn=user, cn=computer)
Step 1: Initial Reconnaissance
Banner Grabbing
nmap -n -sV --script "ldap* and not brute" <IP>
Check Service Availability
# Test LDAP ports nc -zv <IP> 389 636 3268 3269 # Get naming context (domain name) ldapsearch -H ldap://<IP> -x -s base namingcontexts
Anonymous Access Testing
# Try anonymous bind ldapsearch -H ldap://<IP> -x -s base -b "" "(objectClass=*)" "*" + # Try with arbitrary SNI (bypass TLS check) ldapsearch -H ldaps://<IP>:636/ -x -s base -b "" "(objectClass=*)" "*" + # Using NetExec for null bind netexec ldap <IP> -u '' -p '' --query "(objectClass=*)" ""
Step 2: Enumeration with Credentials
Basic User/Group/Computer Enumeration
# Extract users ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "CN=Users,DC=<domain>,DC=<tld>" "(objectClass=person)" sAMAccountName userPrincipalName # Extract computers ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "CN=Computers,DC=<domain>,DC=<tld>" "(objectClass=computer)" name # Extract groups ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "DC=<domain>,DC=<tld>" "(objectClass=group)" cn member
Extract Privileged Groups
# Domain Admins ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "CN=Domain Admins,CN=Users,DC=<domain>,DC=<tld>" "(objectClass=*)" sAMAccountName # Enterprise Admins ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "CN=Enterprise Admins,CN=Users,DC=<domain>,DC=<tld>" "(objectClass=*)" sAMAccountName # Administrators (Builtin) ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "CN=Administrators,CN=Builtin,DC=<domain>,DC=<tld>" "(objectClass=*)" sAMAccountName # Remote Desktop Users ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "CN=Remote Desktop Users,CN=Builtin,DC=<domain>,DC=<tld>" "(objectClass=*)" sAMAccountName
Full Domain Dump
# Dump everything from domain ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "DC=<domain>,DC=<tld>" "(objectClass=*)" "*" # Look for password hashes ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\\<user>' -w '<password>' \ -b "DC=<domain>,DC=<tld>" "(objectClass=*)" "*" | grep -i -A2 -B2 "userpas"
Step 3: Advanced Enumeration Tools
windapsearch
# Get computers python3 windapsearch.py --dc-ip <IP> -u <user@domain> -p <password> --computers # Get groups python3 windapsearch.py --dc-ip <IP> -u <user@domain> -p <password> --groups # Get users python3 windapsearch.py --dc-ip <IP> -u <user@domain> -p <password> --users # Get Domain Admins python3 windapsearch.py --dc-ip <IP> -u <user@domain> -p <password> --da # Get Privileged Users python3 windapsearch.py --dc-ip <IP> -u <user@domain> -p <password> --privileged-users
ldapdomaindump
# Full domain dump with credentials ldapdomaindump <IP> -u '<domain>\\<username>' -p '<password>' \ --authtype SIMPLE --no-json --no-grep -o /path/to/output # With relay IP (for Kerberos) ldapdomaindump <IP> -r <relay_ip> -u '<domain>\\<username>' -p '<password>'
NetExec (CME successor)
# BloodHound data collection netexec ldap <IP> -u <user> -p <password> --bloodhound -c All \ -d <DOMAIN.LOCAL> --dns-server <IP> --dns-tcp # Anonymous enumeration netexec ldap <IP> -u '' -p '' --query "(sAMAccountName=*)" "" # Extract specific attributes netexec ldap <IP> -u '' -p '' --query "(sAMAccountName=*)" "" \ | awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt
Step 4: Client-Side Artifacts (Linux)
When you have access to a Linux host integrated with LDAP/AD:
# Check for LDAP configuration files ls -l /etc/sssd/sssd.conf /etc/nslcd.conf /etc/ldap/ldap.conf /etc/krb5.conf 2>/dev/null # Extract sensitive configuration grep -nE '^(ldap_uri|ldap_search_base|ldap_default_bind_dn|ldap_default_authtok|id_provider|auth_provider)\s*=' \ /etc/sssd/sssd.conf /etc/nslcd.conf 2>/dev/null # View SSSD configuration sed -n '1,120p' /etc/sssd/sssd.conf 2>/dev/null # Test LDAP connection with found credentials ldapsearch -x -H ldap://<target> -D "<bind-dn>" -w '<password>' -b "<base-dn>"
What to look for:
- World-readable
/sssd.confnslcd.conf - Cleartext bind credentials (
)ldap_default_authtok - Directory-backed SSH or sudo integrations
Step 5: Password Attacks
Brute Force with Hydra
# LDAP brute force hydra -l <username> -P <password_list> <IP> ldap2 -V -f # With domain hydra -L <user_list> -P <password_list> <IP> ldap -l <domain>\\
Password Hash Extraction
# From LDAP database files (if accessible) cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u # Feed to John the Ripper john --format=SSHA <hash_file>
Step 6: Graphical Tools
Apache Directory Studio
- Download: https://directory.apache.org/studio/download/download-linux.html
- Use for visual LDAP browsing and modification
jxplorer
- Download: http://www.jxplorer.org/downloads/users.html
- Default install:
/opt/jxplorer
Godap
- Interactive TUI for LDAP/AD
- Supports: simple binds, pass-the-hash, pass-the-ticket, pass-the-cert
- Features: search/create/change/delete objects, group management, password changes, DACL editing
- GitHub: https://github.com/Macmod/godap
Ldapx
- LDAP proxy for traffic inspection/transformation
- Can bypass identity protection & monitoring tools
- GitHub: https://github.com/Macmod/ldapx
Common Attack Vectors
1. Anonymous Information Disclosure
- Enumerate users, groups, computers without credentials
- Extract password policy information
- Map domain structure for targeted attacks
2. Credential Harvesting
- Sniff cleartext credentials (LDAP without SSL)
- MITM attacks with certificate downgrade
- Extract bind credentials from client configs
3. Privilege Escalation
- Modify
attribute for SSH accesssshPublicKey - Add users to privileged groups
- Change password attributes
4. Password Spraying
- Use enumerated usernames with common passwords
- Target accounts with specific attributes (pwdLastSet patterns)
Python LDAP Enumeration
import ldap3 # Connect without credentials (anonymous) server = ldap3.Server('<IP>', get_info=ldap3.ALL, port=636, use_ssl=True) connection = ldap3.Connection(server) connection.bind() # Get server info print(server.info) # Search all objects connection.search( search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*' ) # Print entries for entry in connection.entries: print(entry) # With credentials connection = ldap3.Connection( server, 'uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN', 'PASSWORD', auto_bind=True )
pbis-open Commands
If pbis is installed (
/opt/pbis):
# Read keytab ./klist -k /etc/krb5.keytab # Get domain info ./get-status ./lsa get-status # Enumerate users/groups ./enum-users ./enum-groups ./enum-objects # Get group membership ./list-groups-for-user <username> ./enum-members --by-name "domain admins" # Search with adtool ./adtool -a search-user --name CN="*" --keytab=/etc/krb5.keytab -n <Username>
Kerberos Authentication
# Authenticate via Kerberos instead of NTLM ldapsearch -x -H ldap://<IP> -Y GSSAPI -b "DC=<domain>,DC=<tld>"
Configuration Files to Check
containers.ldif
,ldap.cfg
,ldap.confldap.xmlslapd.conf
(Microsoft AD)msadClassesAttrs.ldif
,nsslapd.sas_at.conf
(Netscape)nsslapd.sas_oc.conf
,slapd.sas_at.conf
(OpenLDAP)slapd.sas_oc.conf
Quick Reference
| Task | Command |
|---|---|
| Banner grab | |
| Anonymous test | |
| Get naming context | |
| Dump domain | |
| Extract users | |
| Extract computers | |
| Brute force | |
| BloodHound | |
Safety Notes
- Always have proper authorization before testing
- Anonymous enumeration may be logged and trigger alerts
- Brute force attacks can lock accounts
- Modifying LDAP attributes can break services
- Document all findings for remediation