Back to Articles

Puredns: How Two-Stage DNS Resolution Solves the Wildcard Subdomain Problem

[ View on GitHub ]

Puredns: How Two-Stage DNS Resolution Solves the Wildcard Subdomain Problem

Hook

During a single subdomain enumeration run, wildcard DNS can generate tens of thousands of false positives—turning what should be 50 real subdomains into an unusable list of 50,000 garbage entries. Puredns exists because traditional DNS bruteforcing tools couldn't tell the difference.

Context

Subdomain enumeration is foundational to security reconnaissance. Before attacking or securing a web property, you need to know what exists. Tools like massdns revolutionized this space by enabling millions of DNS queries per minute, but they introduced a new problem: speed without accuracy is just expensive noise.

The wildcard DNS problem occurs when an organization configures their DNS to return valid IP addresses for any subdomain query, whether that subdomain actually exists or not. A domain like "*.example.com" might resolve every possible combination—randomstring123.example.com, doesnotexist.example.com, literally-anything.example.com—all returning the same IP address. This breaks traditional subdomain discovery. You can't distinguish between real assets like api.example.com and the infinite universe of non-existent subdomains. DNS poisoning adds another layer of complexity: some public DNS resolvers return incorrect or malicious results, either through compromise or misconfiguration. Security researchers and bug bounty hunters needed a tool that could process queries at massdns scale while filtering out both wildcards and poisoned entries automatically.

Technical Insight

Puredns implements a two-stage resolution pipeline that separates speed from trust. In the first stage, it feeds your wordlist through massdns using a large pool of public DNS resolvers. These resolvers are fast and numerous but untrusted—they might be slow, misconfigured, or compromised. This stage prioritizes throughput, resolving millions of potential subdomains quickly. The output is a candidate list of domains that received positive DNS responses.

The second stage is where puredns demonstrates its sophistication. Every domain from the candidate list gets validated against a small set of trusted resolvers (defaulting to Google's 8.8.8.8 and 8.8.4.4). But before validating, puredns runs its wildcard detection algorithm. It generates random subdomains for each parent domain, queries them, and analyzes response patterns. If random.example.com and anotherandom.example.com both resolve to the same IP address, puredns flags example.com as a wildcard root and filters out all subdomains under it that match the wildcard pattern.

Here's a typical workflow integrating puredns with other enumeration tools:

# Generate subdomain candidates from a wordlist
puredns bruteforce wordlist.txt example.com -r resolvers.txt -w results.txt

# Or validate a list of discovered subdomains from multiple sources
cat amass.txt subfinder.txt certspotter.txt | \
  sort -u | \
  puredns resolve -r resolvers.txt -w validated.txt

# Pipe validated domains directly into httpx for web probing
puredns resolve domains.txt -r resolvers.txt -q | \
  httpx -silent -status-code -title

The wildcard detection algorithm is probabilistic but conservative. Instead of querying hundreds of random subdomains (which would slow down the process), puredns queries a small sample and uses statistical analysis to determine wildcard behavior. If the confidence threshold isn't met, it errs on the side of inclusion rather than filtering out potential legitimate subdomains. This tuning favors false positives over false negatives—you might get a few wildcard entries through, but you won't lose real subdomains.

The resolver management system deserves attention. Puredns sanitizes and validates resolver lists before use, removing duplicates and non-responsive servers. It implements rate limiting to prevent overwhelming resolvers or triggering rate limits. The tool tracks resolver performance and can dynamically adjust which resolvers to use based on response times and error rates. This is critical when you're working with public resolver lists that inevitably contain dead or slow servers.

For the bruteforce mode specifically, puredns handles domain permutations intelligently:

# Bruteforce with automatic wildcard filtering
puredns bruteforce best-dns-wordlist.txt example.com \
  --resolvers resolvers.txt \
  --write results.txt \
  --write-wildcards wildcards.txt \
  --wildcard-tests 10

The --wildcard-tests flag controls how many random subdomains to test per root domain. Higher values increase accuracy but slow down the process. The --write-wildcards option outputs detected wildcard roots to a separate file, which is valuable for understanding the target's DNS configuration. You can also use --wildcard-batch to control how many domains are tested in parallel during wildcard detection.

Puredns also handles DNS poisoning by cross-referencing results. When a domain resolves in the first stage using untrusted resolvers, the second stage queries trusted resolvers. If the results differ significantly (different IP addresses, one resolves while the other doesn't), puredns flags this as potential poisoning and can filter it out or mark it for manual review. This two-tier trust model is what separates puredns from simpler DNS tools that treat all resolvers equally.

Gotcha

The biggest operational challenge with puredns is resolver list maintenance. The tool's effectiveness is directly proportional to the quality of your resolver list. Public DNS resolvers appear and disappear constantly. They get rate-limited, shut down, or start returning garbage results. You'll need to regularly validate and update your resolver lists, or accept degraded performance. Many users build automation around tools like dnsvalidator to keep resolver lists fresh, but this adds operational overhead.

The dependency on massdns is both a strength and a weakness. While massdns provides exceptional speed, it means puredns can't be distributed as a single binary. You need to install massdns separately, ensure it's in your PATH, and manage version compatibility. On some systems (particularly macOS), this can be frustrating. The installation process isn't complex, but it's not as simple as downloading a single executable. Additionally, if massdns has bugs or limitations, puredns inherits them. You're trusting two tools instead of one, and debugging issues can require understanding both codebases.

The wildcard detection algorithm, while sophisticated, has edge cases. Some organizations implement complex wildcard patterns—maybe wildcards only exist for certain subdomain depths (*.prod.example.com but not *.example.com), or different wildcards return different IP addresses based on geolocation or load balancing. Puredns handles many of these scenarios but not all. You might need to manually review results for targets with particularly complex DNS configurations. The tool also struggles with extremely large-scale operations (tens of millions of domains) without significant memory and bandwidth resources.

Verdict

Use if: You're performing security reconnaissance or bug bounty hunting at scale, dealing with targets that implement wildcard DNS, need to process large wordlists (100k+ entries) efficiently, or are building automated subdomain enumeration pipelines where accuracy matters. Puredns excels when you have decent bandwidth, can maintain a quality resolver list, and need production-ready results rather than raw DNS query output. It's particularly valuable when you're aggregating subdomain results from multiple sources and need a final validation step that removes noise. Skip if: You're doing small-scale DNS lookups (under 10k queries), can't invest time in resolver list maintenance, need a zero-dependency standalone tool, or are working in bandwidth-constrained environments. For quick one-off subdomain checks, traditional tools like dig or host are simpler. If you want an all-in-one enumeration framework without manual configuration, consider amass instead. Also skip if you're not dealing with wildcard DNS—in that case, massdns alone might suffice.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/d3mondev-puredns.svg)](https://starlog.is/api/badge-click/cybersecurity/d3mondev-puredns)