> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

Bass: Weaponizing DNS Provider Infrastructure for Subdomain Enumeration at Scale

[ View on GitHub ]

Bass: Weaponizing DNS Provider Infrastructure for Subdomain Enumeration at Scale

Hook

Every time you run massdns with a standard public resolver list, you're leaving hundreds of perfectly valid DNS resolvers on the table—resolvers that already know about your target domain and can answer queries without triggering rate limits.

Context

Large-scale DNS enumeration has always been a game of cat and mouse with rate limiting. Tools like massdns revolutionized subdomain discovery by enabling concurrent queries across thousands of resolvers, but the bottleneck shifted from query speed to resolver availability. Most reconnaissance engineers rely on public resolver lists scraped from sources like public-dns.info, typically yielding 1,000-3,500 resolvers. The problem? When you're bruteforcing millions of potential subdomains against a target, even 3,500 resolvers means each one handles thousands of queries, triggering aggressive rate limiting from providers like Cloudflare or Akamai.

Bass approaches this differently by asking a fundamental question: if a domain uses Cloudflare's DNS infrastructure, why only query Cloudflare's public resolvers when dozens of their internal authoritative nameservers can answer the same queries? By fingerprinting a target's DNS provider, then scanning that provider's entire ASN network range for additional nameservers that share zone files, Bass can discover 100-6,000 additional resolvers per target. These aren't scraped from dubious sources—they're legitimate authoritative nameservers operated by the same infrastructure serving your target, meaning they have the zone data in memory and can respond without forwarding queries upstream.

Technical Insight

Provider Examples

Route53/Cloudflare/UltraDNS

Target Domain Input

Query Authoritative NS

Provider Fingerprinting

DNS Provider Detection

ASN Database Lookup

Scan Provider ASN Ranges

Discovered Resolvers

Public Resolver DB

~3.5k resolvers

Merge Resolver Lists

Optimized Resolver Output

System architecture — auto-generated

Bass's architecture revolves around a two-phase discovery process: provider identification and ASN-based resolver expansion. When you feed it a target domain, it first queries the domain's authoritative nameservers to determine the DNS provider. This isn't just parsing NS records—it fingerprints provider-specific response patterns and nameserver naming conventions (like ns-*.awsdns-*.com for Route53 or *.ultradns.net for UltraDNS).

Once the provider is identified, Bass consults its pre-compiled database of DNS provider ASN ranges. Here's where it gets interesting: major DNS providers operate massive networks of nameservers for redundancy and geographic distribution, but most aren't listed in public resolver databases. Bass scans these ASN ranges to discover nameservers that were validated during the tool's development phase to share zone files with the provider's primary nameservers. For a domain using Cloudflare, this might yield 200+ additional resolvers. For UltraDNS infrastructure, you could get 1,000+.

The practical implementation is straightforward. After installation with pip install -r requirements.txt, you run:

python bass.py -d target.com -o resolvers.txt

Bass queries the target's nameservers, identifies the provider (let's say it's NSOne), then merges NSOne-specific resolvers from its database with ~3,500 curated public resolvers, writing everything to resolvers.txt. You can then feed this directly to massdns:

massdns -r resolvers.txt -t A -o S subdomains.txt -w results.txt

The magic happens in how Bass maintains its provider databases. The repository includes pre-scanned resolver lists under bass/providers/, each validated against specific DNS providers. For example, dynect_resolvers.txt contains resolvers specifically discovered within Dyn's ASN ranges that successfully resolve zones hosted on Dynect infrastructure. This pre-validation is critical—not every IP in a DNS provider's ASN range runs a nameserver, and not every nameserver shares zone files across the provider's customer base.

The tool also handles edge cases intelligently. If a domain uses split-horizon DNS or multiple providers, Bass aggregates resolvers from all detected providers. If it can't fingerprint the provider (say, a custom in-house DNS infrastructure), it gracefully falls back to the public resolver list without failing.

What makes this approach powerful for reconnaissance is distribution of query load. With 5,000 resolvers instead of 1,500, you're reducing per-resolver query volume by 70%. When you're enumerating a domain with massdns at 10,000 queries per second, that's the difference between 6.6 queries per resolver per second versus 2 queries per resolver per second—well below most rate limiting thresholds. More resolvers means faster enumeration without triggering defensive measures, and because these are authoritative nameservers for your target's infrastructure, they respond with authoritative answers, not cached data that might be stale.

The codebase itself is compact and readable—primarily Python scripts that handle provider fingerprinting, ASN lookups via WHOIS data, and merging resolver lists. There's no complex dependency chain or architectural overhead. The value is entirely in the curated provider databases and the fingerprinting logic that connects targets to those databases.

Gotcha

Bass's biggest limitation is its reliance on pre-compiled provider databases. The tool was last significantly updated in 2020, and DNS provider infrastructure evolves constantly. If NSOne migrated to a new ASN range or Cloudflare restructured their nameserver topology since the databases were compiled, you won't get those new resolvers. There's no built-in mechanism to refresh provider databases dynamically—you're trusting that the maintainer's original ASN scans are still valid years later. For rapidly changing providers or newer DNS services that entered the market post-2020, Bass won't help.

The provider fingerprinting also assumes targets use major commercial DNS providers. If your target runs BIND on their own infrastructure, uses a regional DNS provider not in Bass's database, or employs anycast DNS with non-standard configurations, the tool provides zero value beyond its public resolver list—which you could get from any number of other sources. You're essentially paying the overhead of running Bass for the same result you'd get from downloading a public resolver list directly. The tool also lacks any resolver health checking—it assumes all resolvers in its databases are online and responsive, but IP ranges get reallocated and nameservers go offline. You might end up with hundreds of dead resolvers in your list, which wastes time during the massdns execution phase when it times out waiting for responses from non-existent servers.

Verdict

Use Bass if you're conducting large-scale subdomain enumeration (1M+ query wordlists) against targets hosted on major DNS providers like Cloudflare, Route53, UltraDNS, NSOne, or Dynect, and rate limiting is degrading your enumeration speed. The resolver count expansion genuinely helps distribute load and avoid defensive rate limiting. Also use it when you need authoritative answers rather than cached responses—the provider-specific resolvers are authoritative for your target's zones. Skip Bass if your target uses obscure or custom DNS infrastructure, if you're doing small-scale enumeration where 1,500 public resolvers suffice, or if you need guaranteed resolver freshness—the static databases might contain stale entries. Also skip it if you're targeting infrastructure that has changed DNS providers recently, since the provider detection might match against outdated configurations. For modern alternatives with active maintenance, consider puredns with dynamically validated resolver lists, though you'll sacrifice the provider-specific resolver discovery that makes Bass unique.