安全研究/安全视界/如何编写高质量的 Nuclei PoC 模板
如何编写高质量的 Nuclei PoC 模板
2026-07-27 08:23分享

Nuclei 是目前渗透测试与安全评估领域最主流的基于模板的漏洞扫描引擎。编写一个高质量、低误报且易于维护的 PoC(Proof of Concept)模板,是安全工程师的核心能力之一。本文将从结构规范、语法要点、匹配逻辑及最佳实践等维度,系统阐述如何编写生产级的 Nuclei 模板。

一、 Nuclei 模板的基本结构

一个标准的 Nuclei 模板由元数据(Info)和请求逻辑(Requests)两大部分组成。清晰的元数据是模板被正确分类、检索和执行的前提。

1. 核心元数据字段

id**:** CVE-2024-XXXXX-poc

info**:**

  name**:** "示例应用未授权访问漏洞"

  author**:** "your_name"

  severity**:** high

  description**:** "示例应用 /api/admin 接口缺乏鉴权,导致未授权用户可获取敏感配置。"

  reference**:**

    - https://example.com/advisory

  classification**:**

    cvss-metrics**:** "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"

    cvss-score**:** 9.8

    cve-id**:** CVE-2024-XXXXX

  tags**:** "cve,cve2024,example,unauth"

关键点: - id: 必须全局唯一,建议遵循 CVE-年份-编号 或 厂商-产品-漏洞类型 的命名规范。 - severity: 严格依据 CVSS 评分填写,可选值为 info, low, medium, high, critical。 - tags: 使用逗号分隔,便于 nuclei -tags 进行筛选。

2. 请求逻辑结构

http**:**

  - raw**:**

      - |

        GET /api/admin/config HTTP/1.1

        Host: {{Hostname}}

        User-Agent: Mozilla/5.0

    matchers-condition**:** and

    matchers**:**

      - type**:** status

        status**:**

          - 200

      - type**:** word

        words**:**

          - "db_password"

          - "internal_api_key"

        condition**:** and

二、 YAML 语法与变量使用要点

Nuclei 模板基于 YAML 格式,语法错误是导致模板加载失败的主要原因。

1. 动态变量系统

Nuclei 提供了强大的动态变量替换机制,避免硬编码:

变量

说明

示例

{{BaseURL}}

目标基础 URL

https://example.com

{{Hostname}}

仅主机名(含端口)

example.com:8080

{{RootURL}}

协议+主机+端口

https://example.com:8080

{{randstr}}

随机字符串

用于探测反射型 XSS 或盲注

{{date}}

当前日期

用于时间戳相关测试

2. 语法注意事项

  • 缩进: 严格使用2个空格,禁止使用 Tab。

  • 特殊字符: 包含:, {, }, | 的字符串必须使用双引号包裹。

  • 多行文本: 使用| (保留换行) 或 > (折叠换行) 处理 Raw 请求体。

  • 注释: 使用# 添加注释,解释复杂的正则或匹配逻辑,提高可读性。

三、 匹配器(Matchers)与提取器(Extractors)

这是 PoC 的灵魂,决定了检测的准确性。

1. 匹配器(Matchers)最佳实践

原则:多维度交叉验证,拒绝单一指标。

  • Status Code: 仅作为辅助条件,不要单独使用。

  • Word: 匹配响应体中的特征字符串。务必设置part: body 或 part: header,避免全量搜索导致的性能损耗。

  • Regex: 用于匹配动态内容(如版本号、Token)。```yaml

    • type: regex regex:

      • ‘version:?(..)’ part: body ```

    • DSL: 用于复杂的逻辑判断。```yaml

      • type: dsl dsl:

        • “status_code == 200 && contains(body, ‘success’) && !contains(body, ‘error’)” ```

2. 提取器(Extractors)

用于从响应中提取关键数据(如 POC 验证所需的 Token、版本号),通常与 Matchers 配合使用。

extractors**:**

  - type**:** regex

    part**:** body

    group**:** 1

    regex**:**

      - '"token":"([a-zA-Z0-9_-]+)"'

技巧: - 使用 group: 1 仅提取正则捕获组内容,而非整个匹配行。 - 设置 internal: true 可将提取结果作为变量供后续请求使用(多步 PoC 必备)。

四、 编写高质量 PoC 的最佳实践

1. 安全性与无害化

  • 只读优先: 默认使用GET 请求。若必须使用 POST/PUT,确保 Payload 不会修改、删除数据或触发业务逻辑(如发送邮件、创建订单)。

  • 避免DoS: 禁止在 PoC 中使用递归请求、大文件下载或高并发 Payload。

  • 随机化: 文件名、参数值使用{{randstr}},防止 WAF 拦截或日志污染。

2. 性能优化

  • 减少请求数: 尽量在单次请求中完成验证。

  • Stop-at-first-match: 对于多Path 探测,设置 stop-at-first-match: true,命中即停。

  • 精确匹配: 正则表达式避免使用.* 等贪婪匹配,使用 [^"]+ 等限定符。

3. 可维护性

  • 自描述: name和 description 要清晰说明漏洞原理,而非仅写 “Check vulnerability”。

  • 引用权威: reference必须包含官方公告、CVE 详情页或高质量技术分析文章。

  • 版本兼容: 若漏洞仅影响特定版本,在description 或 tags 中注明,或使用 DSL 进行版本预检。

五、 常见错误与避坑指南

错误类型

典型表现

解决方案

高误报

仅匹配状态码 200

增加 Body 关键字或 Regex 校验,使用 matchers-condition: and

YAML 解析失败

yaml: line X: mapping values are not allowed

检查缩进,特殊字符加引号,使用在线 YAML Lint 工具验证

Payload 被拦截

403 Forbidden

修改 User-Agent,对 Payload 进行 URL 编码或 Unicode 编码

逻辑漏洞

验证了错误页面

确认匹配特征在漏洞存在时才出现,而非错误页面或默认页面

路径硬编码

/admin/login 写死

使用 {{BaseURL}} 拼接,支持子目录部署场景

六、 验证与调试流程

  1. 本地验证: 使用nuclei -t template.yaml -u target -debug 查看完整请求/响应。

  2. 单元测试: 使用nuclei -t template.yaml -u target -jsonl -o result.json 验证输出格式。

  3. 误报测试: 在已知安全的目标上运行,确认无误报。

  4. 社区规范: 提交前运行nuclei -t template.yaml -validate 确保符合官方规范。

编写优秀的 Nuclei PoC 不仅是技术的体现,更是对安全责任的践行。始终牢记:精准、安全、可复现是衡量一个 PoC 价值的唯一标准。