
Amass v5 被指静默忽略 -alts 和 -brute 标志,CLI 与引擎间参数丢失
来源标题:Amass v5 silently ignores -alts and -brute: flags never cross the engine API
Amass v5 的 CLI 接受 -alts 和 -brute 标志,但这些参数从未传到引擎插件,程序仍以 0 退出且无报错。用户因此得不到变异域名和字典爆破结果,输出比 v4 更少。作者称测试套件在结构上无法发现该问题。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
软件工程 编程 安全 调试 你的 Amass v5 结果比 v4 更少。这是代码层面的原因。 legitbiz 7 分钟阅读· 刚刚
标志被接受了。引擎却从未收到它们。工具以 0 退出。
如果你在 v5 上运行 amass enum -alts -brute 却什么都没得到——没有变异名、没有字典猜测、没有报错——那不是你的用法有问题。我追踪了从 CLI 标志到引擎插件的路径,发现这些值从未完成传递。下面是追踪过程、一行类的修复方案,以及为什么测试套件在结构上根本无法捕获这个问题。
Amass v5 是一次重写。收集引擎移出了进程。CLI 现在是一个客户端。你输入:
amass enum -d example.com -alts -brute -aw altwords.txt -silent -nocolor
退出码:0。Stdout:安静。Stderr:安静。会话日志显示 FQDN-Alterations 插件已启动。数据库里有你的种子以及被动源找到的一切。它不包含 newsub.example.com 或 new-sub.example.com,即使这些名字可以解析。
v4 用户会以为自己配置错了。他们为暴力破解加上 -w wordlist.txt。同样的沉默。他们降级到 v4,或者自己写一个 Python 脚本来做变异,或者发帖说“amass v5 没有输出”,然后被告知使用 -passive。
v5 将 Amass 拆分为 CLI 和通过 HTTP 通信的引擎。当你运行 amass enum 时,客户端会序列化你的 config.Config 并 POST 它。服务端在 engine/api/server/v1/handlers.go 中这样做:
var config config.Config
if err := json.Unmarshal(raw, &config); err != nil {
反序列化到一个零值结构体。没有 NewConfig()。没有恢复默认值。JSON 载荷携带什么,就是引擎将永远拥有的全部配置。
所以问题变成:载荷是否携带了变异设置?
// Will discovered subdomain name alterations be generated?
Alterations bool `yaml:"-" json:"alterations,omitempty"`
FlipWords bool `yaml:"-" json:"-"`
FlipNumbers bool `yaml:"-" json:"-"`
AddWords bool `yaml:"-" json:"-"`
AddNumbers bool `yaml:"-" json:"-"`
MinForWordFlip int `yaml:"-" json:"-"`
EditDistance int `yaml:"-" json:"-"`
AltWordlist []string `yaml:"-" json:"alt_worldlist,omitempty"`
Alterations 有 JSON 名称。AltWordlist 有 JSON 名称(有一个拼写错误——alt_worldlist——这是另一个较小的罪过)。真正控制哪些技术运行的六个字段被标记为 json:"-"。
json:"-" 意味着:永远不序列化此字段。永远不从 JSON 填充它。它不存在于传输线上。
NewConfig()——在 CLI 进程中运行——将布尔值设为 true,将 EditDistance 设为 1。这些值在客户端内部生灭。引擎的结构体从零开始。Unmarshal 什么也不填充,因为 JSON 中没有东西可填充。
engine/plugins/brute/alterations.go 是唯一的消费者。它正确注册。Plugin started for FQDN-Alterations 日志行是真实的。然后它检查:
if cfg != nil && (!cfg.BruteForcing || !cfg.Alterations) {
return
if cfg.FlipWords && len(cfg.AltWordlist) > 0 { // line 104
...
if cfg.FlipNumbers { // line 107
...
if cfg.AddNumbers { // line 110
...
if cfg.AddWords && len(cfg.AltWordlist) > 0 { // line 113
...
if distance := cfg.EditDistance; distance > 0 { // line 117
...
cfg.Alterations 成功传递了(它有 JSON 名称),所以如果你传了 -alts,提前返回不会触发。每个技术分支都取决于一个没有传递过来的字段。全为 false。全为零。guesses 保持为空。插件返回 nil。没有存储调用。没有 MarkAssetMonitored。没有错误。
这就是 issue #1122,它在暴力破解路径上是同一类静默缺口。
-brute 和 -w wordlist.txt 被解析。config/brute.go 将单词列表加载到 c.Wordlist。internal/enum/cli.go 设置它。然后:
$ git grep '\.Wordlist' engine/
Nothing.
v5 中没有暴力破解插件。engine/plugins/brute/ 下唯一的文件是 alterations.go,它读取 c.AltWordlist,而不是 c.Wordlist。单词列表留在内存中,穿过 API(这个在其旅程中的某处确实有 JSON 名称,或者至少在客户端被加载到一个引擎忽略的结构体中),并且从未用于生成 <word>.example.com。
启用 -brute 表面上确实做了点什么——它是通过 cfg.BruteForcing 门控所必需的——但它并不做 v4 用户所说的暴力破解。结合 json:"-" 标签,用户体验是:你传了两个标志,工具接受了两个标志,而引擎收到的配置中每个生成技术都是关闭的。
config/config_test.go 有一个测试,名字很漂亮:MarshalJSON returns the expected JSON bytes:
expected := []byte(`{"seed":{},"scope":{"ports":[80,443]},"rigid_boundaries":false,"resolvers":null,"datasource_config":{},"transformations":{}}
`)
got, err := c.JSON()
if !reflect.DeepEqual(got, expected) {
它断言默认 NewConfig() 的精确序列化。预期字符串不包含 flip_words、edit_distance 或任何变异技术字段——因为这些字段被标记为 json:"-" 并正确地省略了。测试通过了。它一直在通过这个 bug。预期输出是伤口的照片。
一个固定配置结构体精确 JSON 的测试是一个好测试——前提是有人在结构体的契约改变时更新它。这里的契约是“这些字段不存在于传输线上”,而没有任何地方的任何测试断言它们应该存在,或者引擎端的反序列化会产生一个能够运行变异的配置。
问题报告者的选项 A(他在 #1140 中做了根因分析,为我节省了一个下午):给字段真正的 JSON 名称。
FlipWords bool `yaml:"-" json:"flip_words,omitempty"`
FlipNumbers bool `yaml:"-" json:"flip_numbers,omitempty"`
AddWords bool `yaml:"-" json:"add_words,omitempty"`
AddNumbers bool `yaml:"-" json:"add_numbers,omitempty"`
MinForWordFlip int `yaml:"-" json:"min_for_word_flip,omitempty"`
EditDistance int `yaml:"-" json:"edit_distance,omitempty"`
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。