Hi @caffix, thanks for all the work on v5 and the project in general. The rewrite has been great to explore, and I've been using it in a project where the new engine model has already paid off for us. Opening this as a question rather than a PR because I'm not sure whether what I'm seeing is an intentional change or a loose end, and I'd rather ask before writing code that turns out to be unwanted.
What I observed
In v5.1.1 (and on develop), the -brute CLI flag and the bruteforce.wordlists YAML key are still parsed, and the wordlist is loaded into config.Config.Wordlist. Nothing in engine/ reads that field, so the wordlist sits in memory and then goes unused. The only plugin under engine/plugins/brute/ is alterations.go, which consumes c.AltWordlist, not c.Wordlist. FQDN-Alterations even gates on cfg.BruteForcing && cfg.Alterations, which reuses the brute toggle to mean "also do alterations", so enabling -brute visibly does something — just not what a v4 user would expect.
Concretely:
config/brute.go populates c.Wordlist
internal/enum/cli.go:451 sets conf.Wordlist = e.BruteWordList.Slice()
git grep '\.Wordlist' engine/ returns nothing
From a user's point of view, amass enum -brute -w wordlist.txt example.com runs cleanly and produces no dictionary guesses of <word>.example.com. A v4 user would assume it did.
Why I'm asking
I couldn't find anything in the v5.0.0 release notes, the CHANGELOG, or issues/discussions that called out the removal. Other removals (subs/emails subcommands, the embedded collection engine, syslogd) are listed explicitly, so the omission feels more like an unfinished port than a deliberate excision — but I'd rather hear it from you than guess.
So the question is really: was wordlist brute force dropped from v5 on purpose, or is a Go port of resources/scripts/brute/bruteforcing.ads still on the roadmap?
If intentional, no objection from me — but in that case it'd probably be worth removing c.Wordlist and -w/-brute (or logging a clear warning) so users aren't silently getting less than they asked for.
Concrete suggestion, if a port is welcome
I'd be happy to contribute a PR if you're open to it. Rough shape I had in mind:
- New file
engine/plugins/brute/bruteforcing.go registering an FQDN handler at a priority after DNS-IP so we only generate guesses for names whose resolution status we already know.
- Gate on
cfg.BruteForcing, scope membership, and a TTL check via support.TTLStartTime + AssetMonitoredWithinTTL (mirroring how FQDN-Alterations avoids replays).
- Skip CNAMEs and names without A/AAAA, matching the v4 script's
has_cname / has_addr guards — this keeps noise down.
- Emit guesses through
support.StoreFQDNsWithSource / ProcessFQDNsWithSource so downstream DNS resolution drops synthetic names that don't resolve, and the ones that do flow naturally through DNS-IP, DNS-Subdomains, DNS-Apex.
- Optional recursion behind the existing v4 knobs (
recursive, min_for_recursive, max_depth) so depth stays bounded on large zones.
The scope decisions I'd want your steer on:
- Rate limiting: should the plugin lean on the resolver pool's existing concurrency, or carry its own semaphore the way some v4 scripts did?
- Recursion default: v4 defaulted to off and required
min_for_recursive. I'd keep that unless you prefer a stricter stance.
- Ethics/footprint: the wordlist is network active by nature. Happy to add a prominent
Active check and a log line on startup so users can't miss that they're generating live queries.
If you'd rather I open a smaller "document the limitation" PR that renames or gates the config keys, I can do that instead.
Either way, thanks again for the project and for maintaining it. Happy to adjust scope based on whatever direction you'd prefer.
Hi @caffix, thanks for all the work on v5 and the project in general. The rewrite has been great to explore, and I've been using it in a project where the new engine model has already paid off for us. Opening this as a question rather than a PR because I'm not sure whether what I'm seeing is an intentional change or a loose end, and I'd rather ask before writing code that turns out to be unwanted.
What I observed
In v5.1.1 (and on
develop), the-bruteCLI flag and thebruteforce.wordlistsYAML key are still parsed, and the wordlist is loaded intoconfig.Config.Wordlist. Nothing inengine/reads that field, so the wordlist sits in memory and then goes unused. The only plugin underengine/plugins/brute/isalterations.go, which consumesc.AltWordlist, notc.Wordlist.FQDN-Alterationseven gates oncfg.BruteForcing && cfg.Alterations, which reuses the brute toggle to mean "also do alterations", so enabling-brutevisibly does something — just not what a v4 user would expect.Concretely:
config/brute.gopopulatesc.Wordlistinternal/enum/cli.go:451setsconf.Wordlist = e.BruteWordList.Slice()git grep '\.Wordlist' engine/returns nothingFrom a user's point of view,
amass enum -brute -w wordlist.txt example.comruns cleanly and produces no dictionary guesses of<word>.example.com. A v4 user would assume it did.Why I'm asking
I couldn't find anything in the v5.0.0 release notes, the CHANGELOG, or issues/discussions that called out the removal. Other removals (
subs/emailssubcommands, the embedded collection engine, syslogd) are listed explicitly, so the omission feels more like an unfinished port than a deliberate excision — but I'd rather hear it from you than guess.So the question is really: was wordlist brute force dropped from v5 on purpose, or is a Go port of
resources/scripts/brute/bruteforcing.adsstill on the roadmap?If intentional, no objection from me — but in that case it'd probably be worth removing
c.Wordlistand-w/-brute(or logging a clear warning) so users aren't silently getting less than they asked for.Concrete suggestion, if a port is welcome
I'd be happy to contribute a PR if you're open to it. Rough shape I had in mind:
engine/plugins/brute/bruteforcing.goregistering an FQDN handler at a priority afterDNS-IPso we only generate guesses for names whose resolution status we already know.cfg.BruteForcing, scope membership, and a TTL check viasupport.TTLStartTime+AssetMonitoredWithinTTL(mirroring howFQDN-Alterationsavoids replays).has_cname/has_addrguards — this keeps noise down.support.StoreFQDNsWithSource/ProcessFQDNsWithSourceso downstream DNS resolution drops synthetic names that don't resolve, and the ones that do flow naturally throughDNS-IP,DNS-Subdomains,DNS-Apex.recursive,min_for_recursive,max_depth) so depth stays bounded on large zones.The scope decisions I'd want your steer on:
min_for_recursive. I'd keep that unless you prefer a stricter stance.Activecheck and a log line on startup so users can't miss that they're generating live queries.If you'd rather I open a smaller "document the limitation" PR that renames or gates the config keys, I can do that instead.
Either way, thanks again for the project and for maintaining it. Happy to adjust scope based on whatever direction you'd prefer.