DNSRecon
DNSRecon turns a domain name into a structured map of its DNS: which name servers are authoritative, what records the zone publishes (A, AAAA, MX, NS, TXT, SRV, SOA), whether a zone transfer leaks the whole zone at once, and which subdomains the public records never mention. Reach for it as the first structured DNS pass on a scoped domain, before you touch a single web port.
Mental model: dnsrecon -d DOMAIN -t TYPE [options]. Pick a mode, point it at a target, save the output.
New to DNS enumeration? Core concepts
- Record types:
SOAauthority,NSname servers,A/AAAAaddresses,MXmail,TXT(SPF/DKIM/verification),SRVservice locators,PTRreverse,CNAMEalias - Mode (
-t): what DNSRecon does, one or more ofstd,axfr,brt,srv,rvl,crt,zonewalk,tld,snoop - Standard enum (
std): the default; pullsSOA, NS, A, AAAA, MX, SRV, TXTin one pass - Zone transfer (
axfr): asks each NS for the entire zone at once; it should fail on a healthy domain - Brute force (
brt): guesses subdomains from a wordlist (-D) because DNS never lists its own children - Reverse lookup (
-r CIDR): maps an IP range back toPTRnames - Resolver (
-n): which DNS server answers; the default is your system resolver, which can differ from the authoritative one - Wildcard DNS:
*.DOMAINanswers every name, so naive brute force “finds” everything;-ffilters those out
When to reach for DNSRecon (and when not)
Reach for it as the first structured DNS pass on a scoped domain: pull the records, test the zone transfer, and brute force subdomains in one run with saveable CSV/JSON, confirm AXFR is really disabled after a config change, or reverse an in-scope IP range to PTR names.
Reach for something else when you need one exact record fast (dig), high-speed subdomain brute force at scale (gobuster dns, ffuf), broad passive OSINT correlated across many related domains (amass), or application and vulnerability findings (DNSRecon reports DNS facts, not bugs).
Install, update, verify#
sudo apt install -y dnsrecon # Debian / Ubuntu / Kali
pipx install dnsrecon # isolated, on a general workstation
sudo apt install --only-upgrade -y dnsrecon # update the apt copy
pipx upgrade dnsrecon # update the pipx copy
dnsrecon --version # version string
command -v dnsrecon # confirm it is on PATH
dnsrecon -h # skim the modes and flags
From a git clone, run python3 dnsrecon.py in the repo instead of the packaged command. First safe run: dnsrecon -d DOMAIN against a domain you own or are authorized to query prints a clean report of [*] and [+] record lines, which proves it resolves and enumerates.
Flags you’ll actually use#
Skim these first; the cheat sheet below is these flags combined.
| Flag | Does | Flag | Does |
|---|---|---|---|
-d | Target domain | -f | Drop wildcard false hits in brt |
-t | Mode(s): std,axfr,brt,srv,rvl,crt,zonewalk | -a | AXFR test alongside standard enum |
-D | Wordlist for brt / domain list for snoop | -z | DNSSEC zone walk alongside standard |
-r | IP CIDR or first-last range (reverse) | -s | Reverse the SPF netblocks alongside standard |
-n | Resolver to query | -k | Add crt.sh certificate names |
--threads | Concurrent lookups | -w | Deep whois + reverse its ranges |
--lifetime | Per-query timeout, seconds | --tcp | Force TCP queries |
--csv / --json | Structured output file | --xml / --db | XML file / SQLite DB output |
-v | Verbose per-query trace | -h | Full option list |
Cheat sheet#
Each block starts simple and adds one flag at a time, so you can stop at the line that does the job.
# Verify
dnsrecon --version # confirm it is installed
# Standard records: stop at the line you need
dnsrecon -d DOMAIN # 1. SOA, NS, A, AAAA, MX, SRV, TXT
dnsrecon -d DOMAIN -t std # 2. same, mode named explicitly
dnsrecon -d DOMAIN -a # 3. + a zone-transfer attempt
dnsrecon -d DOMAIN -a -z -k # 4. + DNSSEC walk + crt.sh certs
# Zone transfer: success dumps the whole zone (a finding)
dnsrecon -d DOMAIN -t axfr # test every NS for AXFR
dnsrecon -d DOMAIN -a # AXFR alongside standard records
# Brute force subdomains: stop at the line you need
dnsrecon -d DOMAIN -t brt -D WORDLIST # 1. guess names from a list
dnsrecon -d DOMAIN -t brt -D WORDLIST -f # 2. + drop wildcard false hits
dnsrecon -d DOMAIN -t brt -D WORDLIST -f --threads 5 # 3. + gentler on the resolver
dnsrecon -d DOMAIN -t brt -D WORDLIST -f -n 192.168.56.10 # 4. + aim at one known resolver
# Reverse lookup an in-scope range -> PTR names
dnsrecon -r 192.168.56.0/24 # CIDR
dnsrecon -r 192.168.56.10-192.168.56.60 # explicit first-last range
# Services, certs, search-engine subdomains
dnsrecon -d DOMAIN -t srv # SRV locators (_ldap._tcp, _kerberos._udp ...)
dnsrecon -d DOMAIN -t crt # crt.sh certificate-transparency names
dnsrecon -d DOMAIN -t bing # Bing-scraped subdomains
dnsrecon -d DOMAIN -t yand # Yandex-scraped subdomains
# Niche modes
dnsrecon -d DOMAIN -t zonewalk # walk NSEC records on a DNSSEC zone
dnsrecon -d DOMAIN -t tld # test the base name across many TLDs
dnsrecon -t snoop -D WORDLIST -n 192.168.56.10 # cache-snoop one resolver
# Resolver, protocol, timing
dnsrecon -d DOMAIN -n 192.168.56.10 # pin the resolver
dnsrecon -d DOMAIN --tcp # force TCP (large answers, filtered UDP)
dnsrecon -d DOMAIN --lifetime 5 # wait longer per query on a flaky link
# Save structured output (diff runs, parse later)
dnsrecon -d DOMAIN --csv scans/dns.csv
dnsrecon -d DOMAIN --json scans/dns.json
dnsrecon -d DOMAIN --xml scans/dns.xml
dnsrecon -d DOMAIN --db scans/dns.db # SQLite
dnsrecon -d DOMAIN -t std,brt -D WORDLIST --csv scans/combo.csv # combine modes
Command breakdowns#
Each block below explains one situation, the exact command, and what to expect back.
Pull the standard records for a domain#
dnsrecon -d DOMAIN
Runs the default std mode: SOA, NS, A, AAAA, MX, SRV, and TXT in one pass. This is your baseline picture of the zone and the first command on any scoped domain.
Test whether a zone transfer is allowed#
dnsrecon -d DOMAIN -t axfr
Asks every listed name server for the whole zone. A [-] “transfer failed” per NS is the normal, healthy result; a full record dump is a real finding worth saving. -a runs the same test alongside standard records.
Brute force subdomains from a wordlist#
dnsrecon -d DOMAIN -t brt -D WORDLIST
Guesses names from WORDLIST because DNS does not list its children. Each hit prints as a resolved name with its A record; a miss just means the name did not resolve here. DNSRecon ships a list; SecLists has larger ones.
Filter out wildcard DNS false positives#
dnsrecon -d DOMAIN -t brt -D WORDLIST -f
When *.DOMAIN resolves everything, brute force “finds” every guess. -f drops records that match the detected wildcard IP, so the output is real names only.
Find service records (LDAP, Kerberos, SIP)#
dnsrecon -d DOMAIN -t srv
Enumerates SRV locators like _ldap._tcp and _kerberos._udp, returning the host and port behind each service. Often the fastest hint that a domain is Active Directory flavored.
Discover subdomains from certificate transparency#
dnsrecon -d DOMAIN -t crt
Pulls names from crt.sh certificate logs instead of the live zone, so it surfaces hosts that were ever issued a cert. Needs outbound internet, and the names are historical, so confirm each with a real query.
Reverse a private IP range to PTR names#
dnsrecon -r 192.168.56.0/24
Sweeps the range for PTR records. Accepts a CIDR or an explicit first-last range. Treat returned names as hints (they are often stale) and confirm the range is in scope before sweeping.
Pin the query to a specific resolver#
dnsrecon -d DOMAIN -n 192.168.56.10
Sends queries to that server instead of your system resolver. Use the in-scope authoritative NS so you see the real zone, not a cached or filtered public view.
Combine standard records and brute force in one run#
dnsrecon -d DOMAIN -t std,brt -D WORDLIST --csv scans/combo.csv
Comma-separated modes run back to back and land in one file. A tidy way to capture the baseline records and the guessed names together for notes and diffing.
Walk a DNSSEC zone with NSEC records#
dnsrecon -d DOMAIN -t zonewalk
On a DNSSEC-signed zone that uses NSEC, the signed “next name” pointers let DNSRecon enumerate the zone without brute force. Silent on NSEC3 or unsigned zones.
Save results as CSV or JSON for diffing#
dnsrecon -d DOMAIN -t std --json scans/std.json
--json, --csv, --xml, and --db write structured output you can diff between runs or post-process with jq. Always save; re-running noisy lookups because you lost the output is the avoidable mistake.
Slow the scan down to stay quiet#
dnsrecon -d DOMAIN -t brt -D WORDLIST --threads 5 --lifetime 5
--threads 5 keeps concurrency low so you do not flood one resolver; --lifetime 5 waits longer per query on a slow link. A fast brt run is a visible burst of NXDOMAIN responses.
Force TCP for large answers or filtered UDP#
dnsrecon -d DOMAIN --tcp
Sends queries over TCP 53 instead of UDP. Use it when answers are truncated, when UDP is filtered, or when a resolver only honors TCP.
Expand a name across many TLDs#
dnsrecon -d DOMAIN -t tld
Strips the TLD off the base name and tries it against the IANA TLD list, surfacing the same brand registered under other extensions. Useful for footprinting related registrations.
Cache-snoop a resolver for visited domains#
dnsrecon -t snoop -D WORDLIST -n 192.168.56.10
Asks the resolver (non-recursively) whether each name in the list is already cached, hinting at what that network has looked up. Needs a specific resolver (-n) and a domain list (-D).
Reading the output#
| You see | Means | Do next |
|---|---|---|
[*] line | Progress / info | Normal running output |
[+] record | A record was found | This is loot; record it |
[-] failed | A query or transfer was denied | Often expected (AXFR); note it |
SOA / NS | Authoritative servers | Query them directly with -n |
A / AAAA | Name to IPv4 / IPv6 | Action items; hand to web tools |
MX | Mail routing | Reveals a provider or internal mail host |
TXT | SPF / DKIM / tokens | Read for netblocks and internal hints |
SRV | Service and port | Pivot to AD or service enumeration |
PTR (reverse) | IP to name | Hint only, often stale; verify forward |
Troubleshooting#
| Problem | Cause | Fix |
|---|---|---|
command not found | Not installed / stale PATH | Reinstall; open a fresh shell; or run python3 dnsrecon.py |
Could not resolve | DNS/network down or a typo | Check the domain; pin -n with a known resolver |
| AXFR always fails | Transfers correctly disabled | Expected; note as not vulnerable and move on |
| Brute force finds nothing | Weak wordlist or filtering resolver | Bigger WORDLIST, pin -n, slow it down |
| Every brute-force name resolves | Wildcard DNS | Add -f to drop wildcard hits |
| Very slow run | Too many threads on a flaky resolver | Lower --threads, raise --lifetime |
| Empty standard output | Sparse zone or wrong domain | Recheck the domain; confirm with dig DOMAIN any |
| Results differ from a tutorial | Version / flag changes | Check dnsrecon --version and dnsrecon -h |
Gotchas#
- Wildcard DNS makes brute force lie. If
*.DOMAINresolves, every guess “hits” the same IP. Watch for the wildcard warning and add-fso only real names survive. -ris reverse (an IP range),-dis forward (a name). Handing a domain to-r, or a CIDR to-d, silently gets you nothing useful.- The system resolver is not the authoritative server. Results depend on who answers, so pin the in-scope NS with
-nor you may read a cached, filtered, or stale view of the zone. crt,bing, andyandscrape the internet, not the target. They return public and historical names and need outbound access, so treat their output as leads to confirm, not live zone truth.- AXFR failing is the healthy outcome. A dump is the finding; “transfer failed” is not a tool error, so do not chase it as a bug.
- Brute force and reverse sweeps are loud and scope-sensitive. They generate a burst of lookups a resolver logs easily; confirm scope and keep
--threadslow before the first query.
Pairs with#
dig confirms any DNSRecon finding with one precise query and is faster when you only need a single record. gobuster dns and ffuf push subdomain brute force harder once the zone looks worth it, and with nmap they take over the HTTP side once a web host appears. amass correlates passive OSINT across many related domains where DNSRecon stays focused on one. theHarvester seeds wordlists and context with names and emails, and jq slices the --json output into tidy notes.