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
Sezione intitolata “Installation”Via pip
Sezione intitolata “Via pip”pip install ldapdomaindump
From GitHub
Sezione intitolata “From GitHub”git clone https://github.com/dirkjanm/ldapdomaindump.git
cd ldapdomaindump
pip install -r requirements.txt
python setup.py install
Verify Installation
Sezione intitolata “Verify Installation”ldapdomaindump --help
Quick Start
Sezione intitolata “Quick Start”Basic Domain Dump
Sezione intitolata “Basic Domain Dump”ldapdomaindump -u 'DOMAIN\username' -p 'password' ldap://192.168.1.10
With LDAPS (SSL/TLS)
Sezione intitolata “With LDAPS (SSL/TLS)”ldapdomaindump -u 'DOMAIN\username' -p 'password' ldaps://192.168.1.10
Using Null Session
Sezione intitolata “Using Null Session”ldapdomaindump -u '' -p '' ldap://192.168.1.10
Authentication Methods
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “Output Formats”HTML Reports
Sezione intitolata “HTML Reports”Open in browser for interactive exploration:
firefox domain_users.html
# Sort by columns, search, view descriptions
JSON for Scripting
Sezione intitolata “JSON for Scripting”Parse with tools like jq:
jq '.users[] | select(.userAccountControl | contains("NORMAL_ACCOUNT"))' domain_users.json
Grep-Friendly Format
Sezione intitolata “Grep-Friendly Format”Process with grep, awk, sed:
grep "ADMIN" domain_groups.grep
Output Directory and Format Options
Sezione intitolata “Output Directory and Format Options”Specify Output Directory
Sezione intitolata “Specify Output Directory”ldapdomaindump -u 'DOMAIN\user' -p 'pass' -o /tmp/dump ldap://10.0.0.5
Disable Unwanted Formats
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “Useful Grep Queries”Find Domain Administrators
Sezione intitolata “Find Domain Administrators”grep "Domain Admins" domain_groups.grep
grep -i "admin" domain_users.grep
Find Disabled Accounts
Sezione intitolata “Find Disabled Accounts”grep "DISABLED" domain_users.grep
Password Never Expires
Sezione intitolata “Password Never Expires”grep "DONT_EXPIRE_PASSWORD" domain_users.grep
Extract Description Fields (Common Loot Location)
Sezione intitolata “Extract Description Fields (Common Loot Location)”grep "Description:" domain_users.grep
grep -i "password\|pwd\|pass" domain_users.grep
Find Stale Accounts (Old lastLogon)
Sezione intitolata “Find Stale Accounts (Old lastLogon)”grep "1601\|1980\|2000" domain_users.grep
# Look for ancient timestamps
Service Accounts
Sezione intitolata “Service Accounts”grep -i "svc\|service\|managed service" domain_users.grep
Computer Inventory
Sezione intitolata “Computer Inventory”grep "Windows Server" domain_computers.grep
grep "Windows 10" domain_computers.grep
grep "Server 2019" domain_computers.grep
Common Options
Sezione intitolata “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
Sezione intitolata “Loot Analysis Workflow”1. Browser-Based Review
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “Integration with Other Tools”Feed to BloodHound
Sezione intitolata “Feed to BloodHound”# Combine ldapdomaindump JSON with BloodHound ingestor
# Export users and groups to BloodHound format for visualization
Combine with CrackMapExec
Sezione intitolata “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
Sezione intitolata “Enrich Impacket Workflows”# Use enumerated usernames with GetNPUsers.py
python GetNPUsers.py -usersfile users.txt DOMAIN/
Parse for BloodHound CSV
Sezione intitolata “Parse for BloodHound CSV”# Convert JSON output to BloodHound ingestor CSV format
jq -r '.users[] | [.cn, .memberOf[]] | @csv' domain_users.json
Troubleshooting
Sezione intitolata “Troubleshooting”Connection Refused
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “No Output Generated”# Verify LDAP connection successful
# Check output directory permissions
# Try specifying explicit output directory: -o /tmp/ldap_dump
Best Practices
Sezione intitolata “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
Sezione intitolata “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 |