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