| Tested on | Kali GNU/Linux Rolling 2026.2 (kali-rolling) |
|---|---|
| Package | bind9-dnsutils 1:9.20.23-1nmap 7.99+dfsg-1kali1dnsenum 1.3.2-1dnsrecon 1.6.0-1 |
| Lab environment | Pentest lab |
| Cert prep | CompTIA PenTest+ PT0-003 — Domain 2 (Reconnaissance and Enumeration) |
| Privilege | Normal user for most commands; sudo for package installs |
| Scope | Active DNS enumeration with dig, host, nslookup, reverse DNS, Nmap NSE scripts, dnsenum, and DNSRecon; passive subdomain hints from certificate transparency and DNSdumpster; BIND fingerprinting on Metasploitable 2; AXFR and dns-brute on the authorized training zone zonetransfer.me. Record demos use example.com. Does not cover subdomain takeover chains or exploitation after record discovery. |
DNS enumeration turns a domain into hostnames, mail paths, and nameservers before you port-scan or run exploit modules. You query record types such as A, NS, and MX, pull passive subdomain hints from certificate logs, then feed confirmed names into Nmap or service scanning.
DNS enumeration quick start on Kali
Export these variables once and reuse them in every command below. These exports last for the current shell only — re-run the block in a new terminal.
export DOMAIN=example.com
export DNS_SERVER=192.168.56.127 # your Metasploitable IP
export AXFR_DOMAIN=zonetransfer.me
export AXFR_SERVER=nsztm1.digi.ninjaBefore you run the commands below:
- Lab target —
DNS_SERVERis your Metasploitable IP from the pentest lab target list. That variable drives the BINDversion.bindanddns-nsidsections later in this guide. - Internet from Kali — Lookups on
example.com, passive crt.sh queries, and active checks onzonetransfer.meneed outbound DNS or HTTPS. A host-only VM with no NAT will fail those steps. - Which domain to use —
example.comis for read-only record practice only. Zone-transfer and brute-force demos use the authorized training zonezonetransfer.me, not a client domain you have not scoped. - AXFR may be blocked — A timeout or
Transfer failedoften means filtering on the path;REFUSEDmeans the server answered but declined. See the troubleshooting table whenzonetransfer.medoes not transfer from your network. - Missing tools — If
dig,dnsenum, ordnsreconis not found, install the packages in the tools section with apt.
If you only need a fast record pass on a documentation domain, start with dig and host:
dig +short A "$DOMAIN"104.20.23.154
172.66.147.243List authoritative nameservers the same way:
host -t ns "$DOMAIN"example.com name server hera.ns.cloudflare.com.
example.com name server elliott.ns.cloudflare.com.For BIND version fingerprinting on Metasploitable, query version.bind against $DNS_SERVER. Zone-transfer and brute-force demos later in this guide use $AXFR_DOMAIN and $AXFR_SERVER.
What is DNS enumeration in ethical hacking?
DNS maps human-readable names to IPs and service metadata. DNS enumeration collects that metadata on purpose during reconnaissance:
- Mail routing (MX) for identifying email providers and authorized SMTP-testing paths
- Nameservers (NS) for zone-transfer and misconfiguration checks
- Hostnames and subdomains (A, CNAME) that widen the scan target list
- SOA and TXT records that reveal infrastructure hints
Enumeration is not exploitation by itself, but it often precedes banner grabbing and service scanning on the hosts you discover.
Pen testers query these record types most often during active enumeration:
| Record | What it tells you |
|---|---|
| A / AAAA | IPv4 or IPv6 address for a hostname |
| NS | Authoritative nameserver for a zone |
| MX | Mail exchanger hostnames |
| SOA | Start of authority: primary NS, admin contact, serial |
| TXT | Arbitrary text (SPF, DKIM, verification tokens) |
| CNAME | Alias pointing to another hostname |
| SRV | Service location (LDAP, Kerberos, and similar) |
| PTR | Reverse DNS name for an IP (in-addr.arpa) |
SRV records matter most on Active Directory and other enterprise zones because they can reveal LDAP, Kerberos, and similar service locations. This guide does not manufacture SRV output on example.com; run dig +short SRV _ldap._tcp.<zone> on an authorized enterprise or lab DNS zone where those records exist.
Active DNS enumeration generates fresh DNS queries for the target namespace. Depending on the command and resolver path, those queries may reach recursive resolvers and authoritative nameservers and can be logged. Explicit queries such as dig @authoritative-server, AXFR, and brute forcing contact named DNS infrastructure more directly. Passive methods read certificate transparency logs or search indexes (crt.sh, DNSdumpster) without sending new queries to the target zone. This guide covers both, with active lab work against Metasploitable and authorized public training zones.
DNS enumeration tools on Kali
Pick a starting tool from what you need — not every job needs the same binary:
| Need | Best starting tool | Why |
|---|---|---|
| One record / exact DNS question | dig |
Most precise; supports @server, AXFR, and CH TXT probes |
| Quick A / MX / NS lookup | host |
Simple syntax when you already know the record type |
| Full automated DNS pass | dnsenum |
Records, AXFR attempts, and brute-force workflow in one run |
| Task-specific enumeration | DNSRecon | Explicit std, brt, axfr, rvl, and crt modes |
| DNS scripts inside a port-scan workflow | Nmap NSE | dns-brute, dns-zone-transfer, and dns-nsid beside Nmap |
| Passive hostname hints | crt.sh / DNSdumpster | Certificate and index data without direct target probing |
Use the table to choose a first tool, then walk the sections below for command examples on $DOMAIN, Metasploitable BIND, and the authorized $AXFR_DOMAIN training zone.
Install the tool packages if they are missing. Use apt to refresh indexes and install the DNS enumeration stack:
sudo apt update
sudo apt install -y nmap dnsenum dnsrecon bind9-dnsutilsThe bind9-dnsutils package provides dig, host, and nslookup.
Enumerate DNS records with dig
dig is the most flexible DNS client on Kali. Use +short for scripting and the default verbose layout when you need flags, TTLs, or DNSSEC data. Verbose output includes a ;; SERVER: line — your resolver address will differ from any sample in this guide.
A and AAAA records
Resolve IPv4 A records through your system resolver:
dig +short A "$DOMAIN"104.20.23.154
172.66.147.243NS records
List authoritative nameservers:
dig +short NS "$DOMAIN"hera.ns.cloudflare.com.
elliott.ns.cloudflare.com.MX records
Pull mail exchanger hostnames:
dig +short MX "$DOMAIN"0 .MX 0 . is a Null MX record (RFC 7505). It explicitly means the domain does not accept email.
SOA records
Read the primary nameserver and zone serial:
dig +short SOA "$DOMAIN"elliott.ns.cloudflare.com. dns.cloudflare.com. 2411783310 10000 2400 604800 1800TXT records
Check SPF, DKIM, or verification strings:
dig +short TXT "$DOMAIN""v=spf1 -all"
"_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9"Query multiple record types explicitly
Modern authoritative servers may minimize, refuse, or synthesize responses to ANY queries (RFC 8482). Do not rely on ANY for complete enumeration — query important types one at a time:
for type in A AAAA NS MX SOA TXT; do
echo "=== $type ==="
dig +short "$DOMAIN" "$type"
done=== A ===
104.20.23.154
172.66.147.243
=== AAAA ===
=== NS ===
hera.ns.cloudflare.com.
elliott.ns.cloudflare.com.
=== MX ===
0 .
=== SOA ===
elliott.ns.cloudflare.com. dns.cloudflare.com. 2411783310 10000 2400 604800 1800
=== TXT ===
"v=spf1 -all"
"_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9"On Metasploitable, point dig at the lab nameserver for BIND version strings:
dig @"$DNS_SERVER" version.bind CH TXT +short"9.4.2"The hostname.bind CH TXT probe returned metasploitable on the same server, which confirms which VM answered.
Reverse DNS enumeration
Reverse DNS maps an IP to a hostname through PTR records in in-addr.arpa (or ip6.arpa for IPv6). Use it to label scan results or correlate logs when forward and reverse names disagree.
Query Google's public resolver address:
dig +short -x 8.8.8.8dns.google.host prints the same pointer in a single line:
host 8.8.8.88.8.8.8.in-addr.arpa domain name pointer dns.google.Many anycast or CDN addresses have no useful PTR record. A forward A lookup on example.com may return Cloudflare IPs with an empty reverse answer — that is normal, not a tool failure.
Metasploitable in the lab does not publish a PTR for its BIND address. Querying the Metasploitable BIND server directly returned SERVFAIL. That means the server could not complete the reverse lookup; it does not by itself prove that no reverse zone exists.
Subdomain discovery
Subdomain discovery widens the hostname list before you scan. This guide stays DNS-specific — certificate transparency, passive indexes, dns-brute, dnsenum, and DNSRecon. For Amass, Subfinder, and large wordlist workflows, see subdomain enumeration tools.
Passive hints with crt.sh and DNSdumpster
Before you brute-force subdomains on a nameserver, check public indexes that already list certificate and DNS data. These steps are passive: they read third-party logs, not the target authoritative server.
Certificate Transparency (CT) logs contain certificates and precertificates submitted to public CT logs. Searching a domain often surfaces staging, development, legacy, or otherwise non-obvious hostnames that never appeared on the public website.
Search in a browser at https://crt.sh/?q=%.example.com, or pull JSON on the CLI with curl:
curl -fsS "https://crt.sh/?q=%25.${DOMAIN}&output=json" | jq -r '.[].name_value' | sort -uDuring refresh testing, crt.sh intermittently returned HTTP 502 or timed out from this network. When the service answers, deduplicated names look like this:
*.example.com
example.com
m.example.com
www.example.comRetry after a minute, or continue with theHarvester's crtsh source in the OSINT tools guide. Feed confirmed hostnames into the same list you use for active checks.
DNSdumpster is a web-based passive reconnaissance site. Enter an authorized domain, solve the captcha, and review the mapped A, NS, MX, and TXT records plus nearby hosts the index already knows about.
DNSdumpster does not replace dig or AXFR on nameservers you are allowed to test. Treat its output as candidate hostnames to verify with your own queries before you scan or exploit anything.
Active subdomain brute force with Nmap
Nmap ships the dns-brute script for wordlist-based subdomain guessing. Run it only against a zone you own or are explicitly authorized to test — not documentation domains such as example.com.
Point brute-force queries at the zone's authoritative nameserver:
nmap -Pn -p 53 --dns-servers "$AXFR_SERVER" \
--script dns-brute \
--script-args dns-brute.domain="$AXFR_DOMAIN" \
"$AXFR_SERVER"--dns-servers forces lookups through the nameserver you name. Nmap's DNS library uses OS resolvers by default; this flag selects an alternate resolver for the script.
Against the training zone, the script returned several resolvable subdomains (trimmed):
| dns-brute:
| DNS Brute-force hostnames:
| www.zonetransfer.me - 5.196.105.14
| vpn.zonetransfer.me - 174.36.59.154
| owa.zonetransfer.me - 207.46.197.32
|_ testing.zonetransfer.me - 5.196.105.14Tune brute force with script arguments such as dns-brute.hostlist, dns-brute.threads, and dns-brute.srv when you need a custom wordlist or SRV lookups.
Test DNS zone transfers (AXFR)
A misconfigured authoritative nameserver may allow AXFR zone transfers to any client. Query a domain the server actually hosts:
dig @"$AXFR_SERVER" "$AXFR_DOMAIN" AXFROn a network that permits transfers against the training zone, a successful AXFR dumps the zone (trimmed):
zonetransfer.me. 7200 IN SOA nsztm1.digi.ninja. robin.digi.ninja. 2019100801 172800 900 1209600 3600
zonetransfer.me. 7200 IN A 5.196.105.14
zonetransfer.me. 7200 IN NS nsztm1.digi.ninja.
www.zonetransfer.me. 7200 IN A 5.196.105.14
;; XFR size: 47 records (messages 1, bytes 1846)A timeout or Transfer failed can indicate that AXFR traffic is blocked somewhere on the path. REFUSED means the DNS server answered but declined the transfer.
Run the same check with Nmap's dns-zone-transfer script. Nmap provides another way to issue the same AXFR test, but it will not bypass network filtering or a server-side refusal.
nmap -Pn -p 53 --script dns-zone-transfer \
--script-args dns-zone-transfer.domain="$AXFR_DOMAIN" \
"$AXFR_SERVER"When AXFR succeeds, Nmap lists zone records under dns-zone-transfer: on port 53. A transfer blocked by policy leaves port 53 open with no zone table lines.
Automate DNS enumeration with dnsenum
dnsenum bundles record gathering, zone-transfer attempts, and optional Google scraping in one Perl run. Because dnsenum automatically attempts AXFR against a domain's authoritative nameservers, run it against the authorized training zone rather than example.com:
| Option | Purpose |
|---|---|
--noreverse |
Skip reverse lookups |
-f FILE |
Custom subdomain wordlist |
-o FILE |
Save XML output |
--dnsserver SERVER |
Query a specific DNS server |
-r |
Recursion on subdomains; brute force discovered subdomains that have an NS record |
dnsenum --noreverse "$AXFR_DOMAIN"dnsenum VERSION:1.3.2
----- zonetransfer.me -----
Host's addresses:
__________________
zonetransfer.me. 6937 IN A 5.196.105.14
Name Servers:
______________
nsztm1.digi.ninja. 10472 IN A 81.4.108.41
nsztm2.digi.ninja. 10474 IN A 5.196.105.10
Mail (MX) Servers:
___________________
ASPMX.L.GOOGLE.COM. 136 IN A 192.178.211.27
Trying Zone Transfers and getting Bind Versions:
_________________________________________________
Trying Zone Transfer for zonetransfer.me on nsztm1.digi.ninja ...The banner matches the Kali package in the intro table (dnsenum 1.3.2-1). Older package builds may print a different version number. The A, NS, and MX sections map the zone before dnsenum attempts AXFR on each authoritative nameserver. On a network that permits transfers, the Trying Zone Transfer step lists the full zone; filtered paths may show REFUSED or stop after the attempt line.
Save training-zone output to XML for reporting:
dnsenum --noreverse -o "$AXFR_DOMAIN.xml" "$AXFR_DOMAIN"dnsenum exits silently when the XML write succeeds.
Automate DNS enumeration with DNSRecon
DNSRecon prints one timestamped line per record. Use -t to pick a task-specific mode:
| Mode | Purpose |
|---|---|
std |
General A/AAAA/MX/NS/SOA/SRV enumeration |
brt |
Wordlist-based subdomain brute force |
axfr |
Test nameservers for zone transfer |
rvl |
Reverse lookup IP ranges or CIDR blocks |
crt |
Certificate Transparency lookup |
Modes such as brt and axfr generate DNS activity against the target namespace, while crt queries Certificate Transparency data and belongs to the passive-discovery side of the workflow. The crt mode depends on crt.sh availability; upstream DNSRecon releases after the Kali package may handle crt.sh responses differently if you install outside apt.
Run std mode from Kali with working outbound DNS:
dnsrecon -d "$DOMAIN" -t std[*] std: Performing General Enumeration against: example.com...
[*] DNSSEC is configured for example.com
[*] SOA elliott.ns.cloudflare.com 172.64.35.228
[*] NS elliott.ns.cloudflare.com 172.64.35.228
[*] NS hera.ns.cloudflare.com 173.245.58.162
[*] A example.com 104.20.23.154
[*] A example.com 172.66.147.243
[*] Enumerating SRV Records
[*] 0 Records Found
[*] Completed enumeration for domain: example.comDNSRecon prefixes lines with timestamps in live output; the record rows above are trimmed for readability.
brt mode is the main reason to reach for DNSRecon over dig when you want wordlist-driven subdomain guesses with structured output. Kali ships a full list at /usr/share/wordlists/dnsmap.txt; against zonetransfer.me that pass can run for several minutes. The sample below uses a short training-zone wordlist so the lab demo finishes in seconds — swap in the dnsmap path when you need broader coverage on an authorized zone:
printf 'www\nvpn\nowa\ntesting\n' > /tmp/zonetransfer-brt.txtPoint brt at that list on the authorized training zone:
dnsrecon -d "$AXFR_DOMAIN" -t brt -D /tmp/zonetransfer-brt.txt[*] brt: Performing host and subdomain brute force against: zonetransfer.me...
[*] A www.zonetransfer.me 5.196.105.14
[*] A owa.zonetransfer.me 207.46.197.32
[*] A vpn.zonetransfer.me 174.36.59.154
[*] CNAME testing.zonetransfer.me www.zonetransfer.me
[*] 5 Records FoundEach A or CNAME line is a hostname to verify and feed into Nmap. List every mode with dnsrecon -h.
Nmap DNS NSE scripts
Confirm the three DNS scripts used in this walkthrough:
printf '%s\n' /usr/share/nmap/scripts/dns-{brute,nsid,zone-transfer}.nse/usr/share/nmap/scripts/dns-brute.nse
/usr/share/nmap/scripts/dns-nsid.nse
/usr/share/nmap/scripts/dns-zone-transfer.nseFor broader port and script patterns, see network reconnaissance with Nmap. Subdomain brute force and AXFR demos appear in the sections above; the dns-nsid script is covered under lab BIND fingerprinting below.
Query records with host
When you already know the record type you need, host is the fastest manual check. Each answer line names a hostname, IP, or nameserver you can feed into Nmap next.
Resolve IPv4 A records through your system resolver:
host -t A "$DOMAIN"example.com has address 172.66.147.243
example.com has address 104.20.23.154Enumerate MX records:
host -t mx "$DOMAIN"example.com mail is handled by 0 .On corporate zones, MX records usually identify the systems or third-party services handling mail. Treat them as infrastructure leads and confirm ownership and scope before scanning them.
Query records with nslookup
nslookup supports one-shot queries and an interactive shell — useful when you want to explore record types without memorizing dig flags.
For a quick NS lookup:
nslookup -type=ns "$DOMAIN"Server: 192.168.0.1
Address: 192.168.0.1#53
Non-authoritative answer:
example.com nameserver = elliott.ns.cloudflare.com.
example.com nameserver = hera.ns.cloudflare.com.The Server: line shows which resolver answered — your address will differ from the sample.
Request MX records the same way:
nslookup -type=mx "$DOMAIN"example.com mail exchanger = 0 .For interactive mode, start nslookup, set the query type, then enter the domain:
nslookup> set type=ns
> example.com
Server: 192.168.0.1
Address: 192.168.0.1#53
Non-authoritative answer:
example.com nameserver = elliott.ns.cloudflare.com.
example.com nameserver = hera.ns.cloudflare.com.The interactive Server: line uses the same resolver as one-shot mode — yours will differ.
Type exit to leave the interactive shell.
Lab-specific BIND fingerprinting on Metasploitable
Metasploitable exposes BIND 9.4.2 on port 53. From Kali in your pentest lab, confirm the daemon is up with nmap -Pn -p 53 -sV "$DNS_SERVER" — the version line should read ISC BIND 9.4.2, matching the dig version.bind answer on the same host.
The dns-nsid script queries BIND-style version fields without a full dig invocation. DNS commonly listens on both UDP and TCP port 53, so scan both when you fingerprint lab BIND:
sudo nmap -sSU -p 53 --script dns-nsid "$DNS_SERVER"PORT STATE SERVICE
53/tcp open domain
53/udp open domain
| dns-nsid:
|_ bind.version: 9.4.2Record the version string for exposure review. Discovered services feed later vulnerability research — only on systems you are authorized to test.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
SERVFAIL from host "$DOMAIN" "$DNS_SERVER" |
Lab BIND does not recurse cleanly for all record types | Use host -t A "$DOMAIN" without a server argument, or query version.bind with dig @"$DNS_SERVER" |
dnsrecon times out on lab Kali |
Kali has no route to public DNS on that network path | Confirm NAT or outbound DNS on the pentest lab Kali VM |
dns-brute reports no hostnames |
Missing dns-brute.domain or wrong resolver |
Set dns-brute.domain="$AXFR_DOMAIN" and --dns-servers "$AXFR_SERVER" on an authorized zone |
AXFR returns Transfer failed on zonetransfer.me |
Outbound AXFR filtered or timed out on your network path | Retry from a network that allows zone transfers; confirm the domain is zonetransfer.me, not example.com |
AXFR returns REFUSED on zonetransfer.me |
Authoritative server declined the transfer | Expected on restricted zones; Nmap dns-zone-transfer issues the same AXFR request and will not bypass a server refusal |
| crt.sh returns 502 or times out | crt.sh or network path temporarily unavailable | Retry later; use DNSdumpster or theHarvester's crtsh source for passive names |
| dnsenum hangs on Google scraping | Network blocked or captcha | Omit -p / Google options; use --noreverse and a local wordlist with -f |
| Empty reverse answer for a CDN IP | No PTR published for that address | Try another IP from the same netblock or continue with forward DNS only |
Summary
DNS enumeration maps hostnames, mail paths, and nameservers before port scans. This guide walked dig and host on example.com, explicit per-type queries instead of ANY, reverse DNS with dig -x, passive crt.sh hints, and active checks with dns-brute, AXFR, dnsenum, and DNSRecon on zonetransfer.me where your network allows transfers. Metasploitable BIND 9.4.2 fingerprinting used dig version.bind and Nmap dns-nsid against your lab target.
Treat every nameserver and version string as a hypothesis — verify patch level, recursion policy, and authorization scope before you expand scanning. For passive collection and large wordlist workflows, continue with the OSINT tools and subdomain enumeration guides linked above.
References
- dig(1) — BIND 9 Administrator Reference Manual
- host(1) — BIND 9 Administrator Reference Manual
- Nmap
dns-brutescript - Nmap
dns-nsidscript - Nmap
dns-zone-transferscript - Nmap DNS resolution library
- ZoneTransfer.me training zone (DigiNinja)
- RFC 7505 — Null MX
- RFC 8482 — Providing Minimal-Sized Responses to DNS Queries That Have QTYPE=ANY
- dnsenum man page (Debian)
- dnsenum (GitHub)
- DNSRecon (GitHub)
- ISC BIND
- IANA example domains
- Cloudflare — What is DNS?
- crt.sh certificate search
- Metasploitable 2 documentation (Rapid7)
Frequently Asked Questions
What is DNS enumeration in ethical hacking?
DNS enumeration collects hostnames, mail servers, nameservers, and other records from DNS. Pentesters use that data to map subdomains, spot misconfigurations such as open zone transfers, and plan later scanning phases.
Is DNS enumeration illegal?
DNS enumeration is appropriate on domains and name servers you own or are explicitly authorized to test. Laws, provider terms, and organizational policies vary, so obtain permission before querying third-party zones or running brute-force subdomain lists.
When should I use dnsenum versus DNSRecon?
dnsenum bundles broad record collection, AXFR attempts, brute forcing, reverse lookups, and legacy search scraping in one workflow. DNSRecon provides clearer task-specific modes such as std, brt, axfr, rvl, and crt. Try DNSRecon for quick std enumeration; use dnsenum when you want AXFR and subdomain brute force in a single run.
What is a DNS zone transfer and why does it matter?
A zone transfer (AXFR) asks a nameserver to copy an entire DNS zone. When misconfigured servers allow transfers to any client, an attacker can download every hostname in the zone without brute force. Properly restricted authoritative servers commonly refuse unauthorized AXFR requests, for example with REFUSED or NOTAUTH.
Why does host work but dig against my lab DNS server returns empty?
Old or minimal BIND builds may answer CH TXT version probes but fail or return SERVFAIL for some recursive lookups. Point version and Nmap script tests at the lab nameserver IP, and use your normal resolver or explicit record tools for public documentation domains when the lab server does not forward cleanly.
How do I enumerate subdomains without brute forcing the target DNS?
Certificate Transparency logs and passive search sites such as crt.sh and DNSdumpster list hostnames from public certificate and DNS indexes. They do not replace active AXFR or brute-force checks on authorized zones, but they widen the candidate list before you send queries to the target nameserver.

