ldapdomaindump: Complete Guide to Active Directory Enumeration and LDAP Domain Analysis Using Kali Linux

ldapdomaindump is a Python-based Active Directory enumeration tool that connects to a domain controller over LDAP and dumps comprehensive information about domain users, groups, computers, trusts, and policies into both human-readable HTML reports and machine-readable JSON/greppable files. Written by Dirk-jan Mollema as part of the “dirkjanm” toolset (the same author behind mitm6 and pywerview), it is widely used during the internal reconnaissance phase of Active Directory penetration tests because it requires nothing more than valid (even low-privileged) domain credentials, or in some misconfigured environments, an anonymous/null LDAP bind. The output gives an attacker (or auditor) a fast, structured overview of the domain’s user base, privileged group memberships, password policy, and computer inventory — all without needing to run noisy tools against every host individually.

Lightweight Directory Access Protocol (LDAP) is the primary protocol Active Directory uses to store and query directory information — users, groups, computers, organizational units, group policies, and trust relationships. Any authenticated domain user (by default) can query a significant portion of this data, making LDAP enumeration one of the highest-value, lowest-noise reconnaissance techniques in an AD environment.

ldapdomaindump automates this process. It performs an LDAP bind to a target domain controller and systematically enumerates:

It produces output in several formats simultaneously: styled HTML pages (for easy browsing), JSON (for scripting/parsing), and grep-friendly plaintext, making it equally useful for manual review and downstream automation (e.g., feeding data into BloodHound-style analysis or custom scripts).

Installation

ldapdomaindump is written in Python 3 and distributed via pip, and is also packaged directly in Kali’s repositories.

Installing via apt (Kali)

sudo apt update
sudo apt install ldapdomaindump -y

Verify:

ldapdomaindump --help

Installing via pip

pip3 install ldapdomaindump --break-system-packages

Installing from source (GitHub)

git clone https://github.com/dirkjanm/ldapdomaindump.git
cd ldapdomaindump
pip3 install . --break-system-packages

Verifying dependencies

ldapdomaindump depends on ldap3 and dnspython:

pip3 install ldap3 dnspython --break-system-packages

Confirm the version installed:

ldapdomaindump --version

Expected output:

ldapdomaindump 0.10.0

Syntax

General syntax:

ldapdomaindump [OPTIONS] <HOSTNAME_OR_IP>

Basic authenticated connection:

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' ldap://10.10.10.5

Anonymous/null bind attempt (only works if the DC allows it):

ldapdomaindump ldap://10.10.10.5

Command Line Options

FlagDescription
-u, --user USERUsername for LDAP bind, in DOMAIN\user or user@domain format
-p, --password PASSPassword for the bind account (prompted securely if omitted)
-at, --authtype TYPEAuthentication type: NTLM (default) or SIMPLE
-o, --outdir DIROutput directory for generated report files (default: current directory)
-n, --dns-server SERVERAlternate DNS server to use for resolving the domain controller
-r, --resolveResolve computer hostnames to IP addresses in the output
--no-jsonDisable JSON output generation
--no-htmlDisable HTML output generation
--no-grepDisable grepable output generation
-d, --delimiter CHARDelimiter character used in grepable output files (default tab)
-m, --minimalOnly dump minimal object attributes, for faster runs against large domains
-C, --no-cacheDisable caching, forcing a full attribute lookup for every object
--port PORTSpecify a custom LDAP port (default 389, or 636 for LDAPS)
-s, --sslForce an LDAPS (SSL/TLS) connection
-gc, --gcQuery the Global Catalog port (3268) instead of standard LDAP
--user-file FILEOnly dump attributes for usernames listed in this file

Basic Usage

Running a standard authenticated dump against a domain controller:

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' -o /home/kali/loot/corp_dump ldap://10.10.10.5

Expected output:

[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished

The specified output directory will then contain:

ls /home/kali/loot/corp_dump
domain_computers.html      domain_computers.json      domain_computers.grep
domain_groups.html         domain_groups.json         domain_groups.grep
domain_policy.html         domain_policy.json         domain_policy.grep
domain_trusts.html         domain_trusts.json         domain_trusts.grep
domain_users.html          domain_users.json          domain_users.grep
domain_users_by_group.html
index.html

Practical Examples with Output

Example 1 — Basic authenticated dump

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished

Example 2 — Dump using NTLM hash instead of password (via ldap3 pass-the-hash string)

ldapdomaindump -u 'CORP\jsmith' -p 'aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bd6bb76e3fdd' ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished

Example 3 — Specifying an output directory

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' -o /home/kali/loot/corp_ldap ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished

Example 4 — Forcing an LDAPS (SSL) connection on port 636

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' -s --port 636 ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK (SSL)
[*] Starting domain dump
[+] Domain dump finished

Example 5 — Resolving computer hostnames to IPs

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' -r -o /home/kali/loot/resolved ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[*] Resolving computer hostnames...
[+] Domain dump finished

Example 6 — Minimal dump for large/slow domains

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' -m -o /home/kali/loot/minimal ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump (minimal mode)
[+] Domain dump finished

Example 7 — Disabling HTML output, keeping only JSON/grep

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' --no-html -o /home/kali/loot/json_only ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished

Example 8 — Inspecting the domain password policy output

cat /home/kali/loot/corp_ldap/domain_policy.grep
Domain                  Min password length     Password history size   Lockout threshold   Min password age   Max password age
CORP.LOCAL               8                        24                       5                    1 day              90 days

Example 9 — Grepping for disabled accounts in the user dump

grep -i "ACCOUNTDISABLE" /home/kali/loot/corp_ldap/domain_users.grep | wc -l
14

Example 10 — Grepping for Domain Admins group membership

grep -A5 "Domain Admins" /home/kali/loot/corp_ldap/domain_groups.grep
Domain Admins
    CORP\Administrator
    CORP\svc_backup
    CORP\jdoe

Example 11 — Querying the Global Catalog port for a forest-wide view

ldapdomaindump -u 'CORP\jsmith' -p 'Summer2026!' -gc --port 3268 -o /home/kali/loot/gc_dump ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Bind OK (Global Catalog)
[*] Starting domain dump
[+] Domain dump finished

Example 12 — Attempting an anonymous/null bind

ldapdomaindump -o /home/kali/loot/anon_dump ldap://10.10.10.5
[*] Connecting to host...
[*] Binding to host
[+] Anonymous bind OK
[*] Starting domain dump
[+] Domain dump finished

Common Use Cases

Automation with Bash

Bash script to run a full dump and organize output by date

#!/bin/bash
# run_ldapdomaindump.sh - automate a dated domain dump
DC_IP="10.10.10.5"
USER='CORP\jsmith'
PASS='Summer2026!'
DATESTAMP=$(date +%Y-%m-%d)
OUTDIR="/home/kali/loot/ldapdump_${DATESTAMP}"

mkdir -p "$OUTDIR"
echo "[*] Running ldapdomaindump against $DC_IP"
ldapdomaindump -u "$USER" -p "$PASS" -o "$OUTDIR" -r "ldap://${DC_IP}"

echo "[+] Dump complete. Output stored in $OUTDIR"

Bash script to auto-extract Domain Admins from the grep output

#!/bin/bash
# extract_domain_admins.sh - pull domain admin usernames from an existing dump
DUMPDIR="$1"

if [ -z "$DUMPDIR" ]; then
    echo "Usage: $0 <path_to_dump_dir>"
    exit 1
fi

echo "[*] Domain Admins found:"
grep -A20 "^Domain Admins" "${DUMPDIR}/domain_groups.grep" | grep -E "CORP\\\\" 

Bash script to loop the dump across multiple discovered domain controllers

#!/bin/bash
# multi_dc_dump.sh - run ldapdomaindump against every DC in a list
DC_LIST="dc_ips.txt"
USER='CORP\jsmith'
PASS='Summer2026!'

while read -r dc; do
    echo "[*] Dumping $dc"
    ldapdomaindump -u "$USER" -p "$PASS" -o "/home/kali/loot/dc_${dc//./_}" "ldap://${dc}"
done < "$DC_LIST"

echo "[+] All DC dumps complete."

Tips and Best Practices

Troubleshooting

IssueLikely CauseResolution
ldap3.core.exceptions.LDAPBindErrorInvalid credentials or wrong auth typeVerify username format (DOMAIN\user); try -at SIMPLE if NTLM bind fails
Connection refusedLDAP port closed or filteredConfirm with nmap -p389,636,3268 <target>; check network path/firewall rules
Anonymous bind failsDC does not permit anonymous LDAP (default on modern AD)Use valid credentials instead; anonymous bind is increasingly rare on hardened domains
Dump completes but files are nearly emptyBind account has extremely restricted read permissionsConfirm account isn’t in a restricted OU; test with a different low-privileged account if available
SSL handshake failure with -sTarget requires a specific TLS version or valid certificate chainTry without -s on port 389 first, or verify DC’s LDAPS certificate configuration
Script hangs on large domainsFull (non-minimal) dump against a very large AD environmentUse -m for a minimal/faster dump, or --no-json/--no-html to reduce processing overhead
dns.resolver.NXDOMAIN errors with -rInternal DNS not reachable from KaliSpecify the domain’s internal DNS server explicitly with -n <dns_ip>

References

Exit mobile version