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: SOA authority, NS name servers, A/AAAA addresses, MX mail, TXT (SPF/DKIM/verification), SRV service locators, PTR reverse, CNAME alias
  • Mode (-t): what DNSRecon does, one or more of std,axfr,brt,srv,rvl,crt,zonewalk,tld,snoop
  • Standard enum (std): the default; pulls SOA, NS, A, AAAA, MX, SRV, TXT in 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 to PTR names
  • Resolver (-n): which DNS server answers; the default is your system resolver, which can differ from the authoritative one
  • Wildcard DNS: *.DOMAIN answers every name, so naive brute force “finds” everything; -f filters 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.

FlagDoesFlagDoes
-dTarget domain-fDrop wildcard false hits in brt
-tMode(s): std,axfr,brt,srv,rvl,crt,zonewalk-aAXFR test alongside standard enum
-DWordlist for brt / domain list for snoop-zDNSSEC zone walk alongside standard
-rIP CIDR or first-last range (reverse)-sReverse the SPF netblocks alongside standard
-nResolver to query-kAdd crt.sh certificate names
--threadsConcurrent lookups-wDeep whois + reverse its ranges
--lifetimePer-query timeout, seconds--tcpForce TCP queries
--csv / --jsonStructured output file--xml / --dbXML file / SQLite DB output
-vVerbose per-query trace-hFull 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 seeMeansDo next
[*] lineProgress / infoNormal running output
[+] recordA record was foundThis is loot; record it
[-] failedA query or transfer was deniedOften expected (AXFR); note it
SOA / NSAuthoritative serversQuery them directly with -n
A / AAAAName to IPv4 / IPv6Action items; hand to web tools
MXMail routingReveals a provider or internal mail host
TXTSPF / DKIM / tokensRead for netblocks and internal hints
SRVService and portPivot to AD or service enumeration
PTR (reverse)IP to nameHint only, often stale; verify forward

Troubleshooting#

ProblemCauseFix
command not foundNot installed / stale PATHReinstall; open a fresh shell; or run python3 dnsrecon.py
Could not resolveDNS/network down or a typoCheck the domain; pin -n with a known resolver
AXFR always failsTransfers correctly disabledExpected; note as not vulnerable and move on
Brute force finds nothingWeak wordlist or filtering resolverBigger WORDLIST, pin -n, slow it down
Every brute-force name resolvesWildcard DNSAdd -f to drop wildcard hits
Very slow runToo many threads on a flaky resolverLower --threads, raise --lifetime
Empty standard outputSparse zone or wrong domainRecheck the domain; confirm with dig DOMAIN any
Results differ from a tutorialVersion / flag changesCheck dnsrecon --version and dnsrecon -h

Gotchas#

  • Wildcard DNS makes brute force lie. If *.DOMAIN resolves, every guess “hits” the same IP. Watch for the wildcard warning and add -f so only real names survive.
  • -r is reverse (an IP range), -d is 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 -n or you may read a cached, filtered, or stale view of the zone.
  • crt, bing, and yand scrape 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 --threads low 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.

Find us elsewhere

Merch, stickers, and moreSupport the work at the Solvere Labs shop