Aller au contenu

adidnsdump

adidnsdump is a Python tool that performs LDAP queries against Active Directory to extract all DNS records from AD-integrated DNS zones, revealing hidden and tombstoned records that standard DNS queries cannot reach. It’s essential for comprehensive network reconnaissance in Windows domain environments.

Install via pip:

pip install adidnsdump

Install from GitHub source:

git clone https://github.com/dirkjanm/adidnsdump.git
cd adidnsdump
pip install .

Verify installation:

adidnsdump --version

Basic enumeration with domain credentials:

adidnsdump -u domain\\username -p password dc.domain.local

Using domain\user format on Unix systems:

adidnsdump -u 'domain\username' -p 'password' dc.domain.local

Prompt for password interactively:

adidnsdump -u domain\\username dc.domain.local

Using domain credentials:

adidnsdump -u domain\\user -p password dc.domain.local
adidnsdump -u domain\\user -p password -d domain.local dc.domain.local

Force LDAPS encrypted connection:

adidnsdump --ssl -u domain\\user -p password dc.domain.local

Query forest-wide DNS zones instead of domain zones:

adidnsdump --forest -u domain\\user -p password dc.domain.local
OptionPurpose
-u / --userUsername in domain\user format
-p / --passwordPassword (omit for interactive prompt)
-d / --domainExplicit domain name
--sslUse LDAPS (port 636) for encrypted connection
--forestQuery ForestDnsZones instead of DomainDnsZones

Default domain DNS zone:

adidnsdump -u domain\\user -p password dc.domain.local

Forest-wide DNS zones:

adidnsdump --forest -u domain\\user -p password dc.domain.local

Legacy DNS zones (pre-2003):

adidnsdump --legacy -u domain\\user -p password dc.domain.local

Query specific zone by name:

adidnsdump --zone subdomain.domain.local -u domain\\user -p password dc.domain.local

Multiple zones across forest:

adidnsdump --forest -u domain\\user -p password dc.domain.local > forest_dns.txt

Default CSV output:

adidnsdump -u domain\\user -p password dc.domain.local
# Outputs to records.csv

Specify custom output filename:

adidnsdump -u domain\\user -p password -o dns_enum.csv dc.domain.local

JSON output format:

adidnsdump --json -u domain\\user -p password dc.domain.local

Combined with file redirection:

adidnsdump -u domain\\user -p password dc.domain.local > all_records.csv

Typical CSV output includes:

Name,Type,TTL,Data
server1,A,600,192.168.1.10
mail,MX,3600,mail.domain.local
_ldap._tcp,SRV,600,"0 100 389 dc1.domain.local"
alias,CNAME,3600,target.domain.local

Attempt DNS resolution of discovered records:

adidnsdump -r -u domain\\user -p password dc.domain.local

This identifies which hosts are active vs tombstoned/stale:

adidnsdump -r -u domain\\user -p password -o dns_resolved.csv dc.domain.local

Resolve with custom DNS server:

adidnsdump -r --dns-server 8.8.8.8 -u domain\\user -p password dc.domain.local

adidnsdump queries LDAP objects in the AD schema to retrieve DNS data:

LDAP Path: CN=MicrosoftDNS,DC=DomainDnsZones,DC=domain,DC=local

Retrieves from dnsRecord and dnsNode attributes containing:

  • Active DNS records
  • Tombstoned records marked for deletion
  • Manually created records with restricted ACLs
  • Aged records not cleaned by scavenging

Standard DNS queries cannot access these because:

Standard DNS (port 53) → Only returns active, authoritative records
LDAP Query → Direct AD database access → All stored records

Why AD-integrated DNS contains hidden records:

Records marked for deletion but not yet removed:

# Appears in LDAP but fails DNS resolution
adidnsdump -r shows: oldhost, TOMBSTONE, fails to resolve

Records visible only to directory administrators:

# Standard users cannot query via DNS
# LDAP access with AD creds reveals it
adidnsdump -u privuser shows internal.corp.local records

Stale records awaiting cleanup:

# Server last updated 365+ days ago
# Still in LDAP, may not resolve via DNS
adidnsdump -r identifies dead.domain.local as non-responsive

Zone delegation pointers:

# Points to subdomain.domain.local authoritative servers
# Visible in parent zone LDAP, not via standard DNS
adidnsdump -r -u domain\\user -p password dc.domain.local | \
  grep ",A," | cut -d, -f3 | sort -u > targets.txt
nmap -iL targets.txt -p 22,3389,445

Export DNS data for infrastructure mapping:

adidnsdump -u domain\\user -p password dc.domain.local
# Use output to identify service account hosts
# Cross-reference with BloodHound for lateral movement paths
# Create comprehensive asset inventory
adidnsdump -r -o dns_complete.csv -u domain\\user -p password dc.domain.local
# Maps hostnames → IPs → services → AD objects
# Use adidnsdump to enumerate zones
adidnsdump -u domain\\user -p password dc.domain.local | cut -d, -f1 | sort -u
# Then use dnstool.py for dynamic DNS updates if testing

Verify credentials and domain format:

# Wrong format
adidnsdump -u username -p password dc.domain.local  # FAILS

# Correct format
adidnsdump -u domain\\username -p password dc.domain.local  # OK

Check domain controller reachability:

ping dc.domain.local
nslookup dc.domain.local

Verify LDAP path exists:

ldapsearch -x -H ldap://dc.domain.local -b "CN=MicrosoftDNS,DC=DomainDnsZones,DC=domain,DC=local"

Try with explicit domain:

adidnsdump -d domain.local -u domain\\user -p password dc.domain.local

Disable SSL verification if needed (testing only):

# May require custom cert handling
adidnsdump --ssl -u domain\\user -p password dc.domain.local

Add DNS server specification:

adidnsdump --dns-server 192.168.1.1 -u domain\\user -p password dc.domain.local

Reduce scope with specific zone:

adidnsdump --zone subdomain.domain.local -u domain\\user -p password dc.domain.local
  • Use account with minimal necessary privileges
  • Read-only domain user can enumerate DNS
  • Does not require Domain Admin
# Avoid command-line password exposure
adidnsdump -u domain\\user dc.domain.local
# Enter password at prompt (not logged in shell history)
  • Output contains internal infrastructure mapping
  • Store CSV results securely
  • Remove before final report delivery if sensitive

Always verify results:

# Compare with standard DNS queries
adidnsdump -r -o ad_records.csv -u domain\\user -p password dc.domain.local
dig @dc.domain.local axfr domain.local  # Zone transfer (if allowed)

Large forests with many zones:

# Query one zone at a time
for zone in subdomain1 subdomain2 subdomain3; do
  adidnsdump --zone $zone.domain.local -u domain\\user -p password dc.domain.local
done
ToolPurpose
dnstool.pyDNS enumeration and manipulation; similar to adidnsdump
digStandard DNS query tool; limited to public records
nslookupDNS name resolution; does not reveal hidden records
PowerView Get-DomainDNSRecordPowerShell alternative for DNS enumeration
DNSReconDomain reconnaissance including zone transfers
ldapsearchDirect LDAP queries; manual approach
ResponderDNS spoofing and LLMNR/mDNS exploitation
NmapNetwork scanning; uses adidnsdump output for targets
BloodHoundAD relationship mapping; enriched with DNS data