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