DNS Enumeration and Subdomain Discovery on Kali Linux

Tested on Kali GNU/Linux Rolling 2026.2 (kali-rolling)
Package bind9-dnsutils 1:9.20.23-1
nmap 7.99+dfsg-1kali1
dnsenum 1.3.2-1
dnsrecon 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.
Short on time?Beta Get the gist of this 17-minute read in seconds, then ask follow-up questions

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.

IMPORTANT
Run DNS enumeration only against domains and name servers you own or have explicit permission to test. Confirm scope, storage, and export rules in your penetration testing rules of engagement before you query third-party zones or attempt zone transfers.

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.

bash
export DOMAIN=example.com
export DNS_SERVER=192.168.56.127   # your Metasploitable IP
export AXFR_DOMAIN=zonetransfer.me
export AXFR_SERVER=nsztm1.digi.ninja

Before you run the commands below:

  • Lab target — DNS_SERVER is your Metasploitable IP from the pentest lab target list. That variable drives the BIND version.bind and dns-nsid sections later in this guide.
  • Internet from Kali — Lookups on example.com, passive crt.sh queries, and active checks on zonetransfer.me need outbound DNS or HTTPS. A host-only VM with no NAT will fail those steps.
  • Which domain to use — example.com is for read-only record practice only. Zone-transfer and brute-force demos use the authorized training zone zonetransfer.me, not a client domain you have not scoped.
  • AXFR may be blocked — A timeout or Transfer failed often means filtering on the path; REFUSED means the server answered but declined. See the troubleshooting table when zonetransfer.me does not transfer from your network.
  • Missing tools — If dig, dnsenum, or dnsrecon is 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:

bash
dig +short A "$DOMAIN"
output
104.20.23.154
172.66.147.243

List authoritative nameservers the same way:

bash
host -t ns "$DOMAIN"
output
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:

bash
sudo apt update
sudo apt install -y nmap dnsenum dnsrecon bind9-dnsutils

The 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:

bash
dig +short A "$DOMAIN"
output
104.20.23.154
172.66.147.243

NS records

List authoritative nameservers:

bash
dig +short NS "$DOMAIN"
output
hera.ns.cloudflare.com.
elliott.ns.cloudflare.com.

MX records

Pull mail exchanger hostnames:

bash
dig +short MX "$DOMAIN"
output
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:

bash
dig +short SOA "$DOMAIN"
output
elliott.ns.cloudflare.com. dns.cloudflare.com. 2411783310 10000 2400 604800 1800

TXT records

Check SPF, DKIM, or verification strings:

bash
dig +short TXT "$DOMAIN"
output
"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:

bash
for type in A AAAA NS MX SOA TXT; do
    echo "=== $type ==="
    dig +short "$DOMAIN" "$type"
done
output
=== 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:

bash
dig @"$DNS_SERVER" version.bind CH TXT +short
output
"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:

bash
dig +short -x 8.8.8.8
output
dns.google.

host prints the same pointer in a single line:

bash
host 8.8.8.8
output
8.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:

bash
curl -fsS "https://crt.sh/?q=%25.${DOMAIN}&output=json" | jq -r '.[].name_value' | sort -u

During refresh testing, crt.sh intermittently returned HTTP 502 or timed out from this network. When the service answers, deduplicated names look like this:

output
*.example.com
example.com
m.example.com
www.example.com

Retry 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:

bash
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):

output
| 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.14

Tune 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:

bash
dig @"$AXFR_SERVER" "$AXFR_DOMAIN" AXFR

On a network that permits transfers against the training zone, a successful AXFR dumps the zone (trimmed):

output
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.

bash
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
bash
dnsenum --noreverse "$AXFR_DOMAIN"
output
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:

bash
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:

bash
dnsrecon -d "$DOMAIN" -t std
output
[*] 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.com

DNSRecon 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:

bash
printf 'www\nvpn\nowa\ntesting\n' > /tmp/zonetransfer-brt.txt

Point brt at that list on the authorized training zone:

bash
dnsrecon -d "$AXFR_DOMAIN" -t brt -D /tmp/zonetransfer-brt.txt
output
[*] 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 Found

Each 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:

bash
printf '%s\n' /usr/share/nmap/scripts/dns-{brute,nsid,zone-transfer}.nse
output
/usr/share/nmap/scripts/dns-brute.nse
/usr/share/nmap/scripts/dns-nsid.nse
/usr/share/nmap/scripts/dns-zone-transfer.nse

For 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:

bash
host -t A "$DOMAIN"
output
example.com has address 172.66.147.243
example.com has address 104.20.23.154

Enumerate MX records:

bash
host -t mx "$DOMAIN"
output
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:

bash
nslookup -type=ns "$DOMAIN"
output
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:

bash
nslookup -type=mx "$DOMAIN"
output
example.com	mail exchanger = 0 .

For interactive mode, start nslookup, set the query type, then enter the domain:

bash
nslookup
output
> 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:

bash
sudo nmap -sSU -p 53 --script dns-nsid "$DNS_SERVER"
output
PORT   STATE SERVICE
53/tcp open  domain
53/udp open  domain
| dns-nsid:
|_  bind.version: 9.4.2

Record 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


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.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with 15+ years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)