Nuclei 模糊测试指南:如何把 Fuzzing 模板的误报和无效请求降下来
【免费下载链接】nucleiNuclei is a fast, customizable vulnerability scanner powered by the global security community and built on a simple YAML-based DSL, enabling collaboration to tackle trending vulnerabilities on the internet. It helps you find vulnerabilities in your applications, APIs, networks, DNS, and cloud configurations.项目地址: https://gitcode.com/GitHub_Trending/nu/nuclei
做 Web 漏洞扫描时,不少人发现模糊测试(Fuzzing,指向请求中自动注入变异载荷以触发异常)模板"请求发了几千条,有效结果没几条"——时间都耗在了明显无产出的参数上。Nuclei内置的模糊测试引擎用fuzzing规则精确控制"变异哪个位置、怎么变异",再配合-fuzz-param-frequency参数自动跳过无结果参数,能把无效请求砍掉大半,让 SQL 注入、SSRF 等扫描更快、误报更少。
第一步:5 分钟跑通一个 Nuclei Fuzzing 模板
仓库自带一套可运行的模糊测试集成模板,直接拿来验证环境是最快的路径:
- 准备一个本地 HTTP 目标(任何回显参数的服务即可);
- 打开官方示例模板 fuzz-body-json-sqli.yaml,对照它的字段理解结构;
- 执行扫描:
nuclei -t internal/tests/integration/testdata/fuzz/fuzz-body-json-sqli.yaml \ -u http://127.0.0.1:8080/user -debug-debug会打印每次实际发出的请求与载荷,方便确认变异是否落在预期参数上; 4. 没有命中时,调整matchers或收窄keys后重跑; 5. 完整规则字段说明见 FUZZING.md,模板级语法速查见 SYNTAX-REFERENCE.md。
这套模板对应的自动化验证逻辑在 fuzz_test.go 中,可以看到 Nuclei 自身如何用同一套模板回归测试。
六个字段读懂 fuzzing 块:变异行为全靠它们控制
一条模糊测试规则的核心定义在 pkg/fuzz/fuzz.go 的Rule结构体里,对应到 YAML 就是这六个常用字段:
| 字段 | 取值 | 作用 |
|---|---|---|
type | replace/prefix/postfix/infix/replace-regex | 变异方式:整体替换、加前缀、加后缀、中间插入、按正则替换 |
part | query/header/path/body/cookie/request | 攻击面,即请求中被替换的哪个部分 |
mode | single/multiple | 逐参数替换,还是同时替换所有匹配参数 |
keys | 参数名列表 | 只测指定参数,如["id","name"] |
keys-regex/values | 正则 | 按正则批量筛选参数名 / 参数值 |
fuzz | 载荷列表 | 实际注入的变异内容,支持{{var}}占位符 |
下面这段摘自 fuzz-body-json-sqli.yaml,演示对 JSON 请求体做后缀变异:
http: - payloads: injection: - "'" - "\"" fuzzing: - part: body type: postfix mode: single keys: ["username"] fuzz: - "{{injection}}" stop-at-first-match: true matchers: - type: word words: - "unrecognized token:"postfix表示在username原值末尾追加载荷而不是覆盖它,能保住 JSON 结构的合法性;stop-at-first-match: true则让该目标命中一条结果后停止,避免重复发请求。
mode的差别值得注意:仓库里的 fuzz-type.yaml 用single逐个替换id参数,fuzz-mode.yaml 用multiple同时替换id和name。前者请求少、定位准,后者能覆盖"多参数组合触发"的场景,大 payload 集建议先用single。
-fuzz-param-frequency 参数调优:自动砍掉无产出的参数
扫描大量目标时,同一个模板里总有少数参数"怎么测都不出结果"。Nuclei 的 pkg/fuzz/frequency/tracker.go 提供了一个Tracker(频率追踪器),按"参数 + 目标 + 模板"维度缓存计数:某参数连续 N 次变异无命中就标记为无趣并跳过;一旦某次命中,立即清除计数重新参与测试。缓存基于 ARC 策略,上限由DefaultMaxTrackCount(10000)控制。
启动逻辑在 internal/runner/runner.go 中:
fuzzFreqCache := frequency.New(frequency.DefaultMaxTrackCount, r.options.FuzzParamFrequency)第二个参数就是命令行开关,默认为 10:
nuclei -t ./templates/fuzz/ -u https://target.com -fuzz-param-frequency 10含义是"同一参数连续 10 次无结果后跳过"。目标少但参数多时可以调小(如 5)加速;目标广且担心漏测时调大即可,无需改模板。
常见坑与减少误报的匹配器组合
| 现象 | 原因 | 处理 |
|---|---|---|
| 请求量大但零命中 | part/keys过宽,测了大量无关参数 | 收窄keys,或加大-fuzz-param-frequency跳过阈值 |
| 模板在无关接口上乱跑 | 缺少前置条件 | 用pre-condition+ DSL 限定,如仅测contains(content_type, "application/json")的请求 |
| 单条 word 匹配误报高 | 关键词太泛 | 用matchers-condition: and叠加status、word、dsl多条件 |
| 值里带特殊字符的测不到 | 原值被整体破坏 | 换postfix/infix,或用replace-regex只替换匹配片段 |
以 fuzz-body-json-sqli.yaml 为例,它的pre-condition同时校验"非 GET/HEAD、content-type 含 json、路径含 /user",把变异请求限定在真正可能出漏洞的接口上——这一条比任何匹配器都更省流量。
总结:一张清单核对你的 Fuzz 模板
动手前对照这四点检查现有模板:
part+keys是否只圈住了真正的攻击面;- 有状态的目标是否加了
pre-condition; - 匹配器是否用
and组合了两个以上独立信号; - 是否启用了
-fuzz-param-frequency并在大目标集上观察跳过日志(-debug下可见Skipped ... as found uninteresting字样)。
更多字段细节见 FUZZING.md 与 SYNTAX-REFERENCE.md,模板整体规范见 README.md;想给项目补充模板或反馈模糊测试的行为问题,可以从 CONTRIBUTING.md 入手,或在仓库 Issue 区直接提交。
【免费下载链接】nucleiNuclei is a fast, customizable vulnerability scanner powered by the global security community and built on a simple YAML-based DSL, enabling collaboration to tackle trending vulnerabilities on the internet. It helps you find vulnerabilities in your applications, APIs, networks, DNS, and cloud configurations.项目地址: https://gitcode.com/GitHub_Trending/nu/nuclei
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考