dig (Domain Information Groper) is part of the ISC BIND DNS software suite and is the industry-standard tool for querying DNS servers. Unlike nslookup, dig was purpose-built for scripting and detailed diagnostic output, giving full visibility into DNS responses including flags, TTL values, and the authority/additional sections of a DNS response. For penetration testers, dig is essential for enumerating DNS records (A, AAAA, MX, TXT, NS, SOA, CNAME, SRV), testing for zone transfer vulnerabilities, and tracing the full DNS resolution path.
Installation
dig is included in the dnsutils (Debian/Kali) or bind-utils (RHEL/Fedora) package and is pre-installed on Kali Linux.
# Debian/Kali/Ubuntu
sudo apt update && sudo apt install dnsutils -y
# RHEL/CentOS/Fedora
sudo yum install bind-utils -y
# macOS (Homebrew)
brew install bind
Verify installation:
dig -v
Syntax
dig [@server] [OPTIONS] [name] [type] [class]
Command-Line Options
| Flag/Argument | Description |
|---|---|
@server | Specify the DNS server to query (e.g., @8.8.8.8) |
name | The domain/hostname to query |
type | Record type: A, AAAA, MX, NS, TXT, SOA, CNAME, SRV, PTR, ANY, AXFR |
-x IP | Reverse lookup for an IP address |
-4 / -6 | Force IPv4 or IPv6 for the query transport |
-p PORT | Use a non-standard port for the DNS query |
-f FILE | Batch mode: read lookup requests from a file |
-b ADDRESS | Set source IP address for queries (on multi-homed hosts) |
+short | Display a terse/short answer only |
+noall +answer | Display only the answer section |
+trace | Trace the delegation path from the root servers down |
+nssearch | Query all authoritative name servers for SOA info |
+tcp | Force the query to use TCP instead of UDP |
+notcp | Force UDP |
+dnssec | Request DNSSEC records in the reply |
+multiline | Print records in a verbose, multi-line format |
+identify | Show which server produced each answer (useful with multiple @server args) |
+stats / +nostats | Toggle query statistics footer |
+comments / +nocomments | Toggle comment lines in output |
+question / +noquestion | Toggle display of the question section |
-t TYPE | Alternative way to specify record type |
-c CLASS | Specify the query class (default IN) |
-4 | Use IPv4 query transport only |
AXFR | Used as record type to attempt a full zone transfer |
Basic Usage
dig example.com
Expected output:
; <<>> DiG 9.18.24-1-Debian <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5321
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 86400 IN A 93.184.216.34
;; Query time: 22 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun Jul 19 10:15:02 UTC 2026
;; MSG SIZE rcvd: 56
Practical Examples
Example 1 — Query MX records
dig example.com MX +short
10 mail.example.com.
Example 2 — Query all NS records
dig example.com NS +short
a.iana-servers.net.
b.iana-servers.net.
Example 3 — Attempt a zone transfer (AXFR)
dig axfr @ns1.target.com target.com
; Transfer failed.
(A properly secured DNS server should always refuse this; if it succeeds, it’s a critical misconfiguration exposing the entire zone.)
Example 4 — Reverse DNS lookup
dig -x 8.8.8.8 +short
dns.google.
Example 5 — Trace full delegation path
dig +trace example.com
. 518400 IN NS a.root-servers.net.
com. 172800 IN NS a.gtld-servers.net.
example.com. 172800 IN NS a.iana-servers.net.
example.com. 86400 IN A 93.184.216.34
Example 6 — Query TXT records (often reveals SPF, DKIM, verification tokens)
dig example.com TXT +short
"v=spf1 -all"
"google-site-verification=abc123XYZ"
Example 7 — Query using a specific resolver
dig @1.1.1.1 example.com A +short
93.184.216.34
Example 8 — Batch queries from a file
cat domains.txt
# example.com A
# example.org MX
dig -f domains.txt +short
93.184.216.34
10 mail.example.org.
Example 9 — Get only the answer section, no headers
dig example.com +noall +answer
example.com. 86400 IN A 93.184.216.34
Common Use Cases
- Enumerating live DNS records (A/AAAA/MX/TXT/NS/SOA) for a target domain.
- Testing whether a name server allows unauthorized zone transfers (
AXFR) — a critical finding if successful. - Performing reverse DNS lookups (PTR) to identify hostnames behind IP addresses discovered during scanning.
- Tracing the full DNS resolution chain to identify all name servers and delegation points.
- Extracting TXT records to find SPF/DKIM/DMARC misconfigurations relevant to phishing/email-spoofing assessments.
- Confirming DNS propagation after subdomain takeover or DNS pivoting tests.
Automation with Bash
Enumerate common record types for a domain in one pass:
#!/bin/bash
# dig_enum.sh - enumerate common DNS records for a domain
DOMAIN=$1
for TYPE in A AAAA MX NS TXT SOA CNAME; do
echo "=== $TYPE ==="
dig "$DOMAIN" "$TYPE" +short
echo
done
Usage:
./dig_enum.sh example.com
Test AXFR against every discovered name server automatically:
#!/bin/bash
DOMAIN=$1
for ns in $(dig "$DOMAIN" NS +short); do
echo "[*] Trying zone transfer via $ns"
dig axfr @"$ns" "$DOMAIN"
done
Tips and Best Practices
- Always use
+shortin scripts to get clean, parseable output. - Use
+noall +answerwhen you need slightly more context (TTL, record type) than+shortbut still want to avoid the verbose header/footer. - Test zone transfers against every name server returned by the
NSquery — misconfiguration is often isolated to just one secondary server. - Use
+tracewhen you suspect a broken or misconfigured delegation chain (e.g., lame delegation). - Query multiple public resolvers (
8.8.8.8,1.1.1.1,9.9.9.9) to detect DNS-based geofencing, split-horizon DNS, or CDN-based responses that differ by resolver location.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
connection timed out; no servers could be reached | Firewall blocking UDP/TCP port 53 outbound | Try a different network, or specify a reachable resolver with @8.8.8.8 |
;; Transfer failed. on AXFR | Server correctly refuses transfer (expected/secure behavior) | This is normal; note it as a passed control, not a bug |
| Empty answer section | Record type doesn’t exist for that domain, or query hit a caching resolver with a negative cache | Query authoritative name server directly with @ns1.domain.com |
| SERVFAIL status | DNSSEC validation failure or broken delegation | Use +cd to disable DNSSEC checking (for diagnostics only) |
| Inconsistent results between runs | CDN/GeoDNS load balancing return different IPs each query | Expected behavior; query multiple times to build a full picture |
References
- ISC BIND9 documentation: https://bind9.readthedocs.io/
man digmanual page- RFC 1035 – Domain Names, Implementation and Specification: https://www.rfc-editor.org/rfc/rfc1035
- DigitalOcean dig tutorial: https://www.digitalocean.com/community/tutorials/how-to-use-dig-and-nslookup-to-query-dns-servers
