DNS Enumeration Tools and Examples for Ethical Hacking on Kali Linux

Deepak Prasad
Tested on Kali GNU/Linux Rolling 2026.2 (kali-rolling)
Package nmap 7.99+dfsg-1kali1
dnsenum 1.3.2-1
dnsrecon 1.3.1-3
bind9-dnsutils 1:9.20.23-1
Applies to Kali Linux
Lab environment Kali + Metasploitable 2 on VirtualBox host-only — pentest lab setup
Privilege Normal user for most commands; sudo for package installs
Scope Active DNS enumeration with Nmap NSE scripts, dnsenum, DNSRecon, host, nslookup, and dig against a Metasploitable 2 BIND server. Ordinary record lookups use example.com; zone-transfer, dnsenum, and dns-brute demos use the authorized training zone zonetransfer.me. Covers NS, MX, SOA, A records, subdomain brute force, and AXFR checks. Does not cover passive DNS platforms, full subdomain takeover chains, or exploitation after record discovery.

DNS enumeration turns a domain name into a map of hosts, mail paths, and nameservers before you run port scans or exploit modules. You query DNS for A, NS, MX, SOA, and other record types, then feed those hostnames into Nmap or vulnerability research.

This guide walks through six command-line tools on Kali Linux against Metasploitable 2 BIND on port 53. Along the way I explain what each step checks and what a good result looks like. It uses example.com for standard record lookups and zonetransfer.me for authorized zone-transfer demonstrations. Every command and output block below was captured on that layout.

IMPORTANT
Run DNS enumeration only against domains and name servers you own or have explicit permission to test. Use an isolated host-only or internal virtual network. Do not brute-force subdomains or attempt zone transfers against third-party zones without authorization.

What is DNS enumeration in ethical hacking?

The rest of this guide maps hostnames, mail servers, and nameservers from DNS before you port-scan or exploit anything. You collect A, NS, MX, SOA, and related records — reconnaissance, not exploitation by itself.

DNS maps human-readable names to IPs and service metadata. DNS enumeration (sometimes called DNS interrogation) collects that metadata on purpose during reconnaissance:

  • Mail servers (MX) for phishing or 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)

Active enumeration means your tools query DNS directly (dnsrecon, host, Nmap dns-brute). That traffic may be logged on the nameserver. Passive methods pull historical data from third-party datasets (SecurityTrails, ViewDNS) without sending new queries to the target zone. This article focuses on active enumeration in a local lab.


Kali lab setup

Set up variables once so Metasploitable fingerprinting, example.com lookups, and zonetransfer.me demos each point at the right nameserver or domain. You end up with DNS_SERVER, DOMAIN, and AXFR targets ready for every tool below.

Before you run the examples:

  • Kali Linux with the tools below installed
  • Metasploitable 2 on the same host-only or internal network as Kali
  • Comfort reading record types and nameserver responses

Install the packages if they are missing on your Kali image:

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

The bind9-dnsutils package provides dig, host, and nslookup.

Metasploitable 2 network and DNS variables

Item Attacker (Kali) Target (Metasploitable 2)
Hypervisor Oracle VirtualBox (shared) Same host
Lab network Host-only / internal 192.168.56.0/24 Same subnet
Lab IP 192.168.56.115 on eth1 192.168.56.114 (DNS_SERVER)
Role Run enumeration tools from here ISC BIND 9.4.2 on port 53
Record demos host, nslookup, dnsrecon against example.com BIND answers version probes
Zone-transfer and brute-force demos dig, Nmap dns-brute, dns-zone-transfer, dnsenum against zonetransfer.me Training zone on nsztm1.digi.ninja
Service fingerprint dig, Nmap dns-nsid, -sV on port 53 version.bind returns 9.4.2

Substitute your own addresses if VirtualBox assigns a different range. Set the lab nameserver, documentation domain, and AXFR training targets once, then reuse them in every command:

bash
DNS_SERVER=192.168.56.114
DOMAIN=example.com
AXFR_DOMAIN=zonetransfer.me
AXFR_SERVER=nsztm1.digi.ninja
BRUTE_DOMAIN=zonetransfer.me
BRUTE_DNS_SERVER=nsztm1.digi.ninja

Record lookups for example.com use the IANA reserved documentation domain for single-query host, nslookup, and DNSRecon demos — not subdomain brute force or dnsenum runs. Zone-transfer, dnsenum, and dns-brute examples use zonetransfer.me, a domain provided for AXFR training. The tool sections below reuse these variables — only the enumeration program changes.


Scan port 53 with Nmap

Metasploitable exposes BIND on port 53. Confirm the daemon is up and read its version string before you query records on a domain — that version line feeds CVE research later in this guide.

Confirm BIND with Nmap version detection

Scan port 53 on the lab nameserver:

bash
nmap -Pn -p 53 -sV "$DNS_SERVER"

-Pn skips Nmap host discovery and treats the address as online, which helps on lab networks where ICMP may be filtered.

output
PORT   STATE SERVICE VERSION
53/tcp open  domain  ISC BIND 9.4.2

The ISC BIND 9.4.2 string tells you the nameserver software generation. It is intentionally outdated on Metasploitable and worth noting before CVE research.

Read the CH TXT version string with dig

BIND often answers special CH TXT queries on version.bind:

bash
dig @"$DNS_SERVER" version.bind CH TXT +short
output
"9.4.2"

That one-line answer matches the Nmap -sV result. hostname.bind on the same server returned metasploitable in this lab, which confirms which VM answered the query.

Pull the version with the Nmap dns-nsid script

The dns-nsid script queries BIND-style version fields:

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

Use this script when you already have an open port 53 from a wider scan and want a quick BIND version line without a full dig invocation. BIND 9.4.2 is fingerprinted — move on to record enumeration and NSE scripts.


Compare DNS enumeration tools

The sections below walk Nmap scripts, dnsenum, DNSRecon, host, and nslookup against the same lab nameserver and authorized zones. Use this table to pick a path before you scale up brute lists or AXFR attempts.

Tool Best for Typical output
Nmap (dns-nsid, dns-brute, dns-zone-transfer) Version fingerprint on port 53; scripted subdomain brute force Script table lines inside Nmap report
dnsenum One-shot zone with AXFR attempts and optional scraping Colored sections for A, NS, MX, brute results
DNSRecon Scriptable per-record lines; multiple -t modes Timestamped INFO lines per record
host Fast manual lookups by record type Single-line answers
nslookup Interactive exploration; Windows parity Server banner plus record answer
dig Precise queries (CH TXT, AXFR, @server) Default detailed DNS packet layout

Start with dig or Nmap on the lab nameserver IP, then run dnsenum or DNSRecon when you need a broader record pass on an authorized domain.


Enumerate with Nmap DNS scripts

Nmap ships multiple DNS NSE scripts under /usr/share/nmap/scripts/. Here we brute-force subdomains on an authorized zone and test zone transfer — outputs land in the Nmap report under script result blocks.

Confirm the three 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

Next we run dns-brute for subdomain discovery and dns-zone-transfer for AXFR checks. For broader port and script patterns, see network reconnaissance with Nmap.

Brute-force subdomains with dns-brute

The dns-brute script guesses hostnames against a domain. Run it only against a zone you own or are explicitly authorized to test — not documentation domains such as example.com.

Set the authorized zone and the nameserver that should resolve brute-force queries (often the zone’s authoritative server):

bash
BRUTE_DOMAIN=zonetransfer.me
BRUTE_DNS_SERVER=nsztm1.digi.ninja

nmap -Pn -p 53 --dns-servers "$BRUTE_DNS_SERVER" \
    --script dns-brute \
    --script-args dns-brute.domain="$BRUTE_DOMAIN" \
    "$BRUTE_DNS_SERVER"

dns-brute resolves candidate A and AAAA records through Nmap’s configured DNS servers. The --dns-servers "$BRUTE_DNS_SERVER" option forces those lookups through the nameserver you name. Nmap’s DNS library uses DNS servers known to the OS by default; --dns-servers selects an alternate resolver.

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 for zone transfers

A misconfigured authoritative nameserver may allow AXFR zone transfers to any client. Query a domain the server actually hosts. Asking Metasploitable BIND to transfer example.com only proves that server is not authoritative for that zone, not that its AXFR policy is secure.

Use a zone you control, or the intentionally transferable training zone zonetransfer.me:

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

On the training nameserver, a successful transfer 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.
zonetransfer.me.        7200    IN      NS      nsztm2.digi.ninja.
www.zonetransfer.me.    7200    IN      A       5.196.105.14
;; XFR size: 47 records (messages 1, bytes 1846)

Some networks filter AXFR and return Transfer failed or REFUSED even against the training zone. Retry from a network that allows outbound DNS zone transfers.

Run the same check with Nmap’s dns-zone-transfer script, which requires the dns-zone-transfer.domain argument:

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 or filtering leaves port 53 open with no zone table lines.


Enumerate zones with dnsenum

dnsenum bundles record gathering, zone-transfer attempts, and optional Google scraping in one Perl run. Against zonetransfer.me you get A, NS, and MX sections before AXFR attempts — a full zone sketch in one command.

Because dnsenum automatically attempts AXFR against a domain’s authoritative nameservers, run it against the authorized training zone rather than example.com:

bash
dnsenum --noreverse "$AXFR_DOMAIN"
output
dnsenum VERSION:1.3.1

-----   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
ALT1.ASPMX.L.GOOGLE.COM.                 136      IN    A        173.194.41.27

Trying Zone Transfers and getting Bind Versions:
_________________________________________________

Trying Zone Transfer for zonetransfer.me on nsztm1.digi.ninja ...

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.

--dnsserver sends dnsenum’s A, NS, and MX queries through the supplied resolver. AXFR and PTR requests are still sent to the domain’s authoritative nameservers, per the dnsenum man page. Metasploitable BIND does not recurse cleanly for zonetransfer.me, so this walkthrough omits a --dnsserver "$DNS_SERVER" example rather than pointing dnsenum at example.com.

Save training-zone output to XML for reporting:

bash
dnsenum --noreverse -o "$AXFR_DOMAIN.xml" "$AXFR_DOMAIN"

Collect DNS records with DNSRecon

DNSRecon prints one timestamped line per record in std mode — easy to script. Start with a standard pass against the documentation domain:

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 162.159.44.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. List other modes with dnsrecon -h (-t brt for brute force, -t axfr for zone transfer only).


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

List authoritative nameservers:

bash
host -t ns "$DOMAIN"
output
example.com name server hera.ns.cloudflare.com.
example.com name server elliott.ns.cloudflare.com.

Enumerate MX records:

bash
host -t mx "$DOMAIN"
output
example.com mail is handled by 0 .

MX 0 . is a Null MX record (RFC 7505). It explicitly means the domain does not accept email; the dot is not a mail host to scan. On corporate zones, MX rows usually name real mail hosts you can scan next.


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. The server banner and answer block show which resolver answered and what records came back.

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.

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.

Type exit to leave the interactive shell.


Map BIND versions to CVE research

Enumeration gives you software versions and exposure — not automatic exploitability. Record BIND 9.4.2 from the lab, then check advisories and confirm patch level before you treat a CVE as applicable.

Record the service, version, and exposure before searching a CVE database:

Port Finding Research result
53/tcp ISC BIND 9.4.2 (dns-nsid, -sV) Review the ISC BIND advisory index and NVD entries for 9.4.x; Metasploitable ships an intentionally old build

A version string is only a clue. BIND 9.4.2 is end-of-life and appears in lab images to practice patching and exposure review, not to imply every 9.4.2 server shares the same flaw set. Confirm patch level, recursion policy, and whether the nameserver is reachable from untrusted networks before you treat a CVE as applicable.

When enumeration reveals a host and port, continue with service scanning and banner grabbing on the IPs you discovered — only on systems you are authorized to test.


Troubleshooting

When host returns SERVFAIL, AXFR is refused, or dns-brute finds nothing, check the table below.

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"
dns-brute reports no hostnames Missing dns-brute.domain or wrong resolver Set dns-brute.domain="$BRUTE_DOMAIN" and --dns-servers "$BRUTE_DNS_SERVER" on an authorized zone
AXFR returns Transfer failed or REFUSED on zonetransfer.me Outbound AXFR filtered, or wrong nameserver Query "$AXFR_SERVER" (authoritative for the training zone); confirm the domain is zonetransfer.me, not example.com
dnsrecon cannot resolve domain No network or wrong -n nameserver Check routing to the internet or set -n "$DNS_SERVER" when the lab resolver should answer
dnsenum hangs on Google scraping Network blocked or captcha Omit -p / Google options; use --noreverse and a local wordlist with -f
Empty dig answer via lab server Query type not supported or recursion disabled Confirm port 53 is open with nmap -Pn -p 53 "$DNS_SERVER"; test version.bind CH TXT

References

  • Nmap dns-brute script
  • Nmap dns-nsid script
  • Nmap dns-zone-transfer script
  • Nmap DNS resolution
  • ZoneTransfer.me (DigiNinja)
  • RFC 7505 — Null MX
  • dnsenum man page (Debian)
  • ISC BIND advisory index
  • dnsenum (GitHub)
  • DNSRecon (GitHub)
  • ISC BIND
  • IANA example domains
  • Cloudflare — What is DNS?
  • Metasploitable 2 documentation (Rapid7)

Summary

DNS enumeration answers which hostnames and mail paths exist before you spend time on port scans. In this lab you fingerprinted Metasploitable BIND 9.4.2 with Nmap -sV, dig version.bind, and dns-nsid, ran dns-brute against the authorized zonetransfer.me zone, and practiced AXFR on its authoritative nameserver.

dnsenum demonstrates broad record collection and AXFR against zonetransfer.me, while DNSRecon, host, and nslookup use example.com for ordinary record lookups. Treat every nameserver and version string as a hypothesis: verify patch level, recursion policy, and authorization scope before you map findings to CVEs or expand scanning to newly discovered hosts.

On authorized lab targets, chain enumeration into banner grabbing and the Metasploitable 2 exploitation walkthrough. Never run brute-force or AXFR tests against domains or servers you are not permitted to query.


Frequently Asked Questions

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

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

3. When should I use dnsenum versus DNSRecon?

Both automate broad record collection. dnsenum bundles Google scraping and zone-transfer attempts in one Perl workflow. DNSRecon is Python-based, prints structured lines per record type, and is easy to script. Try DNSRecon for quick std enumeration; use dnsenum when you want AXFR and subdomain brute force in a single run.

4. 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. Well-managed zones return REFUSED or NOTAUTH.

5. 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.
Kennedy Muthii

Information Security Analyst

Accomplished professional proficient in Python, ethical hacking, Linux, cybersecurity, and OSINT. With a track record including winning a national cybersecurity contest, launching a startup in Kenya, and holding a degree in information science, he is currently engaged in cutting-edge research in ethical hacking.

  • Python (programming language)
  • Certified Ethical Hacker
  • White Hat (Computer Security)
  • Linux
  • Penetration Testing