LDAPDomainDump
LDAPDomainDump is a Python tool for extracting and analyzing Active Directory information via LDAP. It queries domain controllers to enumerate users, computers, groups, policies, and trust relationships, exporting results in multiple formats for both interactive analysis and scripting workflows.
Installation
Seção intitulada “Installation”Via pip
Seção intitulada “Via pip”pip install ldapdomaindump
From GitHub
Seção intitulada “From GitHub”git clone https://github.com/dirkjanm/ldapdomaindump.git
cd ldapdomaindump
pip install -r requirements.txt
python setup.py install
Verify Installation
Seção intitulada “Verify Installation”ldapdomaindump --help
Quick Start
Seção intitulada “Quick Start”Basic Domain Dump
Seção intitulada “Basic Domain Dump”ldapdomaindump -u 'DOMAIN\username' -p 'password' ldap://192.168.1.10
With LDAPS (SSL/TLS)
Seção intitulada “With LDAPS (SSL/TLS)”ldapdomaindump -u 'DOMAIN\username' -p 'password' ldaps://192.168.1.10
Using Null Session
Seção intitulada “Using Null Session”ldapdomaindump -u '' -p '' ldap://192.168.1.10
Authentication Methods
Seção intitulada “Authentication Methods”| Option | Usage | Example |
|---|---|---|
-u | Domain username | -u 'DOMAIN\user' or -u 'user@domain.com' |
-p | Password | -p 'password123' |
-at NTLM | NTLM hash authentication | -at NTLM -hashes lm:nt |
| LDAP (unencrypted) | ldap:// protocol | ldap://10.0.0.5 |
| LDAPS (SSL/TLS) | ldaps:// protocol | ldaps://10.0.0.5 |
| Anonymous | Empty credentials | -u '' -p '' |
Output Files Generated
Seção intitulada “Output Files Generated”LDAPDomainDump creates multiple files for each data type:
| File | Format | Purpose |
|---|---|---|
domain_users.html | HTML report | Interactive user enumeration |
domain_users.json | JSON data | Programmatic parsing |
domain_users.grep | Grep-friendly | CLI text processing |
domain_computers.html | HTML report | System inventory |
domain_computers.json | JSON data | Machine enumeration |
domain_computers.grep | Grep-friendly | OS/patch analysis |
domain_groups.html | HTML report | Group memberships |
domain_groups.json | JSON data | Membership parsing |
domain_groups.grep | Grep-friendly | Group extraction |
domain_policy.html | HTML report | Password policies |
domain_policy.json | JSON data | Policy data |
domain_policy.grep | Grep-friendly | Policy attributes |
domain_trusts.html | HTML report | Forest/domain trusts |
domain_trusts.json | JSON data | Trust relationships |
domain_trusts.grep | Grep-friendly | Trust enumeration |
Output Formats
Seção intitulada “Output Formats”HTML Reports
Seção intitulada “HTML Reports”Open in browser for interactive exploration:
firefox domain_users.html
# Sort by columns, search, view descriptions
JSON for Scripting
Seção intitulada “JSON for Scripting”Parse with tools like jq:
jq '.users[] | select(.userAccountControl | contains("NORMAL_ACCOUNT"))' domain_users.json
Grep-Friendly Format
Seção intitulada “Grep-Friendly Format”Process with grep, awk, sed:
grep "ADMIN" domain_groups.grep
Output Directory and Format Options
Seção intitulada “Output Directory and Format Options”Specify Output Directory
Seção intitulada “Specify Output Directory”ldapdomaindump -u 'DOMAIN\user' -p 'pass' -o /tmp/dump ldap://10.0.0.5
Disable Unwanted Formats
Seção intitulada “Disable Unwanted Formats”# HTML only
ldapdomaindump -u 'DOMAIN\user' -p 'pass' --no-json --no-grep ldap://10.0.0.5
# JSON only
ldapdomaindump -u 'DOMAIN\user' -p 'pass' --no-html --no-grep ldap://10.0.0.5
# Grep only
ldapdomaindump -u 'DOMAIN\user' -p 'pass' --no-html --no-json ldap://10.0.0.5
Custom Field Delimiter
Seção intitulada “Custom Field Delimiter”ldapdomaindump -u 'DOMAIN\user' -p 'pass' -d '|' ldap://10.0.0.5
# Changes delimiter from default to pipe character
Useful Grep Queries
Seção intitulada “Useful Grep Queries”Find Domain Administrators
Seção intitulada “Find Domain Administrators”grep "Domain Admins" domain_groups.grep
grep -i "admin" domain_users.grep
Find Disabled Accounts
Seção intitulada “Find Disabled Accounts”grep "DISABLED" domain_users.grep
Password Never Expires
Seção intitulada “Password Never Expires”grep "DONT_EXPIRE_PASSWORD" domain_users.grep
Extract Description Fields (Common Loot Location)
Seção intitulada “Extract Description Fields (Common Loot Location)”grep "Description:" domain_users.grep
grep -i "password\|pwd\|pass" domain_users.grep
Find Stale Accounts (Old lastLogon)
Seção intitulada “Find Stale Accounts (Old lastLogon)”grep "1601\|1980\|2000" domain_users.grep
# Look for ancient timestamps
Service Accounts
Seção intitulada “Service Accounts”grep -i "svc\|service\|managed service" domain_users.grep
Computer Inventory
Seção intitulada “Computer Inventory”grep "Windows Server" domain_computers.grep
grep "Windows 10" domain_computers.grep
grep "Server 2019" domain_computers.grep
Common Options
Seção intitulada “Common Options”| Option | Usage |
|---|---|
-u | Username (domain\user format) |
-p | Password |
-o | Output directory (default: current) |
-r | Referral host for multi-domain environments |
-at NTLM | Authentication type (NTLM) |
-hashes | LM:NT hashes instead of password |
--no-html | Skip HTML report generation |
--no-json | Skip JSON export |
--no-grep | Skip grep-friendly format |
-d | Field delimiter for grep output |
--dns-tcp | Use TCP for DNS queries |
Loot Analysis Workflow
Seção intitulada “Loot Analysis Workflow”1. Browser-Based Review
Seção intitulada “1. Browser-Based Review”# Open HTML reports in browser
firefox domain_users.html
firefox domain_groups.html
firefox domain_policy.html
2. Extract Data with jq
Seção intitulada “2. Extract Data with jq”# Get all user emails
jq -r '.users[] | .mail' domain_users.json | grep -v null
# Find users without password expiration
jq -r '.users[] | select(.userAccountControl | contains("DONT_EXPIRE_PASSWORD")) | .sAMAccountName' domain_users.json
# List all privileged groups
jq -r '.groups[] | select(.sAMAccountName | contains("Admin")) | .cn' domain_groups.json
3. CLI Processing with Grep
Seção intitulada “3. CLI Processing with Grep”# Find nested group memberships
grep -E "^cn=.*,cn=Users" domain_groups.grep
# Extract computer names and OS
awk -F'|' '{print $1,$3}' domain_computers.grep
# Search descriptions for sensitive info
grep -i "backup\|password\|key\|secret" domain_users.grep
4. Cross-Reference Analysis
Seção intitulada “4. Cross-Reference Analysis”# Find users in sensitive groups
for group in "Domain Admins" "Enterprise Admins" "Schema Admins"; do
echo "=== $group ==="
grep "$group" domain_groups.grep
done
Integration with Other Tools
Seção intitulada “Integration with Other Tools”Feed to BloodHound
Seção intitulada “Feed to BloodHound”# Combine ldapdomaindump JSON with BloodHound ingestor
# Export users and groups to BloodHound format for visualization
Combine with CrackMapExec
Seção intitulada “Combine with CrackMapExec”# Use ldapdomaindump to enumerate, then spray with CME
cme smb 10.0.0.0/24 -u 'user' -p 'pass' --shares
Enrich Impacket Workflows
Seção intitulada “Enrich Impacket Workflows”# Use enumerated usernames with GetNPUsers.py
python GetNPUsers.py -usersfile users.txt DOMAIN/
Parse for BloodHound CSV
Seção intitulada “Parse for BloodHound CSV”# Convert JSON output to BloodHound ingestor CSV format
jq -r '.users[] | [.cn, .memberOf[]] | @csv' domain_users.json
Troubleshooting
Seção intitulada “Troubleshooting”Connection Refused
Seção intitulada “Connection Refused”# Verify LDAP port is open
nmap -p 389,636 10.0.0.5
# Check firewall rules blocking LDAP
# Try LDAPS on 636 instead: ldaps://10.0.0.5
Invalid Credentials
Seção intitulada “Invalid Credentials”# Verify username format (DOMAIN\user or user@domain.com)
# Test with known valid account
# Check if account is locked or disabled
Timeout Issues
Seção intitulada “Timeout Issues”# Increase query timeout (depends on domain size)
# Try connecting directly to a specific DC
# Reduce scope with custom queries if supported
Permission Denied
Seção intitulada “Permission Denied”# Some objects may require higher privileges
# Try with Domain Admin or Enterprise Admin account
# Verify user has LDAP read permissions
No Output Generated
Seção intitulada “No Output Generated”# Verify LDAP connection successful
# Check output directory permissions
# Try specifying explicit output directory: -o /tmp/ldap_dump
Best Practices
Seção intitulada “Best Practices”- Use encrypted connections (LDAPS on port 636) when possible to avoid credential sniffing
- Test with null sessions first to determine what anonymous LDAP access reveals
- Archive results for offline analysis and comparison across time
- Cross-reference outputs between different formats to verify data integrity
- Sanitize sensitive data before sharing reports with third parties
- Document enumeration scope (date, credentials used, domain targeted)
- Monitor for detection - LDAP enumeration may trigger security alerts in mature environments
- Combine with other tools - use results as input for attack chain planning
- Review descriptions carefully - often contain passwords, notes, legacy system info
- Track stale accounts - old accounts may still have high privileges
Related Tools
Seção intitulada “Related Tools”| Tool | Purpose |
|---|---|
| windapsearch | LDAP enumeration alternative with different output options |
| ADFind | Windows-based AD enumeration (Windows only) |
| ldapsearch | OpenLDAP CLI tool for manual queries |
| enum4linux-ng | Multi-protocol enumeration including LDAP |
| BloodHound | AD visualization and attack path analysis |
| CrackMapExec | Multi-protocol post-exploitation framework |
| Impacket | Python toolkit with AD/LDAP utilities |
| PowerView | PowerShell-based AD enumeration |