subenum v0.9.0

Every DNS query, accounted for.

subenum brute-forces subdomains from a wordlist, then tells you how much of the answer to trust. Each lookup is counted as resolved, NXDOMAIN, timeout or refused, and every run ends with a verdict a script can check.

go install github.com/TMHSDigital/subenum@latest

Scan only domains you own or have written permission to test.

subenum -rate 200 -type A,CNAME -show-records -stats run.json example.com
stdout
  1. www.example.com A=203.0.113.10
  2. api.example.com A=203.0.113.24
  3. mail.example.com A=203.0.113.31
  4. cdn.example.com CNAME=example.edgesuite.net
  5. vpn.example.com A=198.51.100.7
  6. old.example.com CNAME=old-app.herokuapp.com TAKEOVER?=dangling:heroku
  7. status.example.com CNAME=example.statuspage.io
  8. … 24 more
run.json
lookups 5,000 / 5,000
resolved
31
nxdomain
4,957
timeout
9
refused
3
complete 12 of 5000 lookups failed (timeout 9, refused 3, other 0), under 1%

A missing name is only news if the lookup got an answer.

When resolvers time out, a wordlist scan doesn't fail loudly. It returns fewer names and looks finished. subenum keeps a ledger of every lookup and grades the run, so you know whether “not found” means not there or not asked.

The verdict and its reason land in -stats run.json and on the last line of -format jsonl. One jq call turns it into a pipeline gate.

jq -e '.verdict == "complete"' run.json
  1. completeunder 1% of lookups failed

    12 of 5000 lookups failed (timeout 9, refused 3, other 0), under 1%

  2. degraded1% or more failed, or the run was cut short

    71 of 5000 lookups failed (timeout 64, refused 7, other 0)

  3. unreliableover 20% failed; the scan stops itself

    the reliability guard aborted the scan: 412 of 1800 lookups failed (timeout 398, refused 14, other 0)

What you can rely on

Each of these is a flag or a field you can check for yourself, not a promise in a README.

Resolver pools that can't lie to you

Spread queries across many resolvers. Failing ones are benched, every hit is re-checked against your trusted resolver before it's printed, and canary checks catch a resolver that hides names that exist.

-r resolvers.txt -dns-server 9.9.9.9

Wildcards, including rotating ones

subenum fingerprints wildcard answers before the scan and learns CDN pools that rotate. An inconclusive check is reported as inconclusive, never as “no wildcard”.

"wildcard": true, "wildcard_filtered": 112

A rate limit you can quote

-rate caps packets on the wire, counting retries and every record type, so the number in your rules of engagement is the number you send.

-rate 200   "achieved_qps": 198.6

Scope that holds

Excluded names are never queried, not filtered afterwards. Exact names and *.parent patterns, inline or from a file.

-exclude '*.corp.example.com'

Takeover hints

CNAMEs that dangle or point at takeover-prone services such as S3, GitHub Pages, Heroku and Azure are flagged for you to verify by hand.

TAKEOVER?=dangling:heroku

Change detection

Compare against the last run and print only names that appeared or disappeared. Exit code 4 means something changed.

-diff previous.jsonl

Encrypted transport

Send queries over plain DNS, DNS over TLS or DNS over HTTPS by changing one address.

-dns-server tls://1.1.1.1

One static binary

No runtime, no services, no API keys. A 5,000-entry wordlist is built in, so subenum yourdomain.com works out of the box.

go install github.com/TMHSDigital/subenum@latest

Run it the way your work runs

Resolved names go to stdout, one per line, so they pipe cleanly. Progress and the per-outcome breakdown go to stderr.

subenum example.com
subenum -w big-wordlist.txt -type A,AAAA,CNAME -show-records example.com
Getting started

Where it fits

subfinder covers passive sources. puredns, shuffledns and dnsx are built for raw mass resolution. subenum is the active brute-force step for when you need to defend the result: a single binary that shows its working.

It also teaches. -simulate gives marked, reproducible output with no network traffic, and -tui puts every option in a form.

The subenum terminal UI: a Configure Scan form with domain, wordlist, simulate, hit rate, DNS server, concurrency, timeout and attempts fields
subenum -tui

Start with one command.

go install github.com/TMHSDigital/subenum@latest && subenum -simulate example.com