跳到主要内容

nuclei-poc-generator

用途

根据漏洞详情自动生成 Nuclei POC YAML 模板。当用户提供漏洞信息(CVE、配置错误、暴露文件、RCE、SQL 注入、SSRF、XSS 等)并希望生成可交付的 Nuclei YAML 扫描模板时使用。当用户提到 "nuclei"、"poc"、"yaml template"、"漏洞检测模板" 或 "nuclei template" 时也适用。

skills

---
name: nuclei-poc-generator
description: 根据漏洞详情自动生成 Nuclei POC YAML 模板。当用户提供漏洞信息(CVE、配置错误、暴露文件、RCE、SQL 注入、SSRF、XSS 等)并希望生成可交付的 Nuclei YAML 扫描模板时使用。当用户提到 "nuclei"、"poc"、"yaml template"、"漏洞检测模板" 或 "nuclei template" 时也适用。
argument-hint: "[漏洞详情]"
---

# Nuclei POC 生成器

根据用户提供的漏洞详情,生成可交付的 Nuclei YAML 模板。

## 使用说明

当用户提供漏洞详情时,按照以下工作流程生成完整的 Nuclei 模板:

### 步骤 1:收集关键信息

从用户输入中提取并确认以下信息,缺失关键字段时必须向用户询问:

| 字段 | 必填 | 需要提取的内容 |
|-------|:---:|----------------|
| **漏洞类型** || CVE、配置错误、暴露文件/目录、RCE、SQLi、SSRF、XSS、SSTI、LFI、RFI、IDOR、认证绕过、信息泄露等 |
| **目标路径/端点** || 哪个 URL 路径或端点存在漏洞 |
| **HTTP 方法** || GET、POST、PUT、DELETE、PATCH 等 |
| **请求详情** || Headers、Body(POST 参数、JSON、XML 等)、查询参数 |
| **预期响应特征** || 状态码、响应正文关键词/正则、响应头、响应大小 |
| **严重级别** || critical / high / medium / low / info |
| **漏洞影响** || 漏洞造成的实际危害描述(如"可获取服务器权限"、"导致敏感数据泄露") |
| **修复建议** || 具体修复措施(如"升级至 x.x 版本"、"关闭暴露的端点") |
| **Fofa 查询语句** || Fofa 搜索引擎查询语句,用于资产发现(如 `app="TargetApp"`|
| **参考链接** || CVE 编号、公告 URL、博客文章、漏洞利用参考 |
| **标签** || cve、rce、sqli、xss、exposed-panels、misconfig 等 |

### 步骤 2:选择模板方式

在两种 HTTP 请求格式之间选择:

- **简化格式(`method` + `path` + `headers` + `body`**:用于简单的 GET/POST 请求,路径直接且 body 简单。
- **原始格式(`raw` 块)**:当请求需要以下特性时使用:
- 自定义/多行 HTTP 请求格式
- 辅助函数(如 `{{base64()}}``{{rand_text_alpha()}}`
- 多个顺序请求(漏洞利用链)
- 在特定位置注入动态变量
- 非标准 HTTP 语法

**默认使用简化格式**,除非明确需要原始格式。

### 步骤 3:选择匹配器(Matchers)

根据漏洞的表现形式选择适当的匹配器:

| 场景 | 推荐匹配器 |
|----------|-------------------|
| 响应正文包含特定字符串 | `type: word` |
| 响应匹配正则表达式 | `type: regex` |
| 特定 HTTP 状态码 | `type: status` |
| 复杂逻辑条件 | `type: dsl` |
| 响应大小校验 | `type: size` |
| 需要验证不匹配(排除) | 添加 `negative: true` |

**匹配器最佳实践:**
- **当存在 2 个或以上 matchers 时,必须添加 `matchers-condition: and`**:Nuclei 中多个 matchers 默认遵循 OR 逻辑——只要任意一个 matcher 命中即判定漏洞存在。若未设置 `matchers-condition: and`,当 `type: status` 匹配器单独命中(如状态码 200)时,即使 word/regex matcher 未匹配也会产生误报
- **单个 word matcher 内含 2 个或以上 words 时,默认添加 `condition: and`**:要求全部关键词同时匹配才命中,最大程度减少误报。仅在多个关键词互斥(即响应中不可能同时出现所有关键词,只需匹配其一即可确认漏洞)时才使用 `condition: or`,但这种情况极为罕见,需在模板注释中说明使用 or 的理由
- 简单字符串匹配优先用 `word` 而非 `regex`(更快,性能更好)
- 响应正文匹配使用 `part: body`(默认),响应头匹配使用 `part: header`
- 多步骤漏洞利用中,中间步骤匹配器使用 `internal: true`

```yaml
# 正确示例:多个 matchers 必须添加 matchers-condition: and
matchers-condition: and
matchers:
- type: word
words:
- "root:x:0:0:"
- type: status
status:
- 200

# 错误示例:缺少 matchers-condition: and,200 状态码单独命中即误报
matchers:
- type: word
words:
- "root:x:0:0:"
- type: status
status:
- 200
```

### 步骤 4:选择提取器(Extractors)

**以下场景必须添加提取器:**

| 漏洞类型 | 提取目的 | 提取器示例 |
|----------|----------|-----------|
| **RCE / 命令执行** | 提取命令执行结果(如 `whoami` 输出) | `type: regex` 匹配命令输出 |
| **文件包含(LFI/RFI)** | 提取读取到的文件内容(如 `/etc/passwd`| `type: regex` 匹配文件内容片段 |
| **SQL 注入** | 提取数据库查询结果(如数据库版本) | `type: regex` 匹配返回的数据 |
| **SSTI** | 提取模板注入执行结果 | `type: regex` 匹配计算/执行结果 |
| **多步骤利用** | 提取 Token/Session 供后续请求使用 | `type: regex` + `internal: true` |
| **版本/信息检测** | 提取并展示版本号等关键信息 | `type: regex``type: json` |

**对于命令执行和文件包含类漏洞,提取器不是可选项——必须添加,以在扫描结果中展示漏洞执行的实际输出。**

**提取器数量限制规则:**
- **展示用提取器(非 `internal`**:每个 POC 最多只能有 **1 个**。用于向扫描结果输出漏洞利用的实际结果(如命令执行输出、文件内容、数据库查询结果)。如果需要展示多项信息,应合并到一个提取器中,使用更宽泛的正则捕获
- **内部提取器(`internal: true`**:数量不受限制。用于多步骤利用中提取 Token/Session 等中间变量供后续请求使用,不输出到终端

```yaml
# 正确示例:1个展示用提取器 + 多个内部提取器
extractors:
- type: regex
name: cmd_result # 展示用提取器(唯一)
regex:
- 'uid=\d+\(\w+\).*gid=\d+\(\w+\)'
- type: regex
name: csrf_token
part: body
regex:
- 'name="csrf" value="([^"]+)"'
group: 1
internal: true # 内部提取器(不限数量)
- type: regex
name: session_id
part: header
regex:
- 'session_id=([^;]+)'
group: 1
internal: true # 内部提取器(不限数量)

# 错误示例:2个展示用提取器(超出限制)
extractors:
- type: regex
name: uid_result # 展示用提取器 1 ❌
regex:
- 'uid=\d+\((\w+)\)'
group: 1
- type: regex
name: gid_result # 展示用提取器 2 ❌ 超出限制
regex:
- 'gid=\d+\((\w+)\)'
group: 1
```

### 步骤 5:生成模板

按以下完整结构构建 YAML。**info 块必须包含全部必填字段:name、author、severity、description、impact、remediation、reference、metadata.fofa_query、tags。**

```yaml
id: <唯一ID-不含空格>

info:
name: <描述性名称>
author: <作者名>
severity: <critical|high|medium|low|info>
description: <简洁描述检测的漏洞内容>
impact: <漏洞造成的实际危害影响>
remediation: <具体修复措施和建议>
reference:
- <参考URL>
metadata:
fofa-query: '<Fofa 查询语句>'
tags: <逗号分隔的标签>

http:
- method: <GET|POST|PUT|DELETE|...>
path:
- "{{BaseURL}}<漏洞路径>"
# 可选的请求头:
headers:
Header-Name: value
# 可选请求体(POST/PUT 时使用):
body: "<请求体>"

# 匹配器(必填)
# 当存在 2 个或以上 matchers 时,必须添加 matchers-condition: and
# matchers-condition: and
matchers:
- type: <word|regex|status|dsl|size>
words:
- "<特征字符串1>"
- "<特征字符串2>"
condition: and # 默认值:要求全部关键词匹配;仅在关键词互斥时使用 or
# part: body (默认值;匹配响应头用 header)

# 提取器(命令执行/文件包含等漏洞必填)
extractors:
- type: regex
name: <提取结果名称>
regex:
- "<正则表达式>"
group: 1
```

### 步骤 6:验证并输出

交付模板前逐项检查:
1. `id` 不含空格
2. `info` 块包含全部必填字段:`name``author``severity``description``impact``remediation``reference``metadata.fofa_query``tags`
3. `severity` 是以下之一:info、low、medium、high、critical
4. `fofa-query` 已填入有效的 Fofa 查询语句
5. 所有动态变量语法正确:`{{BaseURL}}``{{Hostname}}`
6. 匹配器与漏洞类型匹配,特征字符串有足够特异性
7. 当存在 2 个或以上 matchers 时,必须包含 `matchers-condition: and`
8. **命令执行/文件包含/SQLi/SSTI 类漏洞必须包含 extractors**
9. **展示用提取器(非 internal)最多 1 个**;内部提取器(internal: true)数量不限
10. 模板自包含、可直接使用
11. 仅输出原始 YAML 内容到代码块中,供用户直接保存为 `.yaml` 文件

## info 块字段说明

```yaml
info:
name: <模板名称,描述性标题>
author: <作者,建议使用格式如 d4m1ts 或公司/团队名>
severity: <严重级别:critical|high|medium|low|info>
description: <漏洞原理简述,说明检测了什么问题>
impact: <漏洞利用成功后的实际危害,如"攻击者可远程执行任意命令,完全控制目标服务器">
remediation: <具体可操作的修复方案,如"升级至 v2.5.1 及以上版本"或"在防火墙上限制该端点访问">
reference:
- <官方公告/CVE链接>
- <分析文章链接>
metadata:
fofa-query: '<Fofa搜索语法>'
tags: <标签列表,逗号分隔>
```

## 动态变量参考

| 变量 | 描述 | 示例值 |
|----------|-------------|---------------|
| `{{BaseURL}}` | 完整输入 URL(含协议、主机、端口、路径) | `https://example.com:443/foo/bar.php` |
| `{{RootURL}}` | 根 URL(协议 + 主机 + 端口) | `https://example.com:443` |
| `{{Hostname}}` | 主机名(含端口) | `example.com:443` |
| `{{Host}}` | 仅主机名 | `example.com` |
| `{{Port}}` | 端口号 | `443` |
| `{{Path}}` | URL 路径(目录) | `/foo` |
| `{{File}}` | 路径中的文件名 | `bar.php` |
| `{{Scheme}}` | 协议方案 | `https` |
| `{{interactsh-url}}` | Interactsh OOB 地址(盲检测用) | `c0123xxxxx.oast.fun` |

## 匹配器类型快速参考

```yaml
# 关键词匹配器(最常用)
matchers:
- type: word
words:
- "string1"
- "string2"
condition: and # 默认:全部关键词匹配才命中;仅在关键词互斥时使用 or
part: body # body(默认)、header、all

# 状态码匹配器
matchers:
- type: status
status:
- 200
- 302

# 正则匹配器
matchers:
- type: regex
regex:
- "pattern[0-9]+"
part: body

# DSL 匹配器(复杂条件)
matchers:
- type: dsl
dsl:
- "status_code == 200 && contains(body, 'admin')"

# 反向匹配器(未找到时命中)
matchers:
- type: word
words:
- "error"
negative: true
```

## 提取器语法参考

> **数量限制**:展示用提取器(非 `internal`)每个 POC 最多 1 个;内部提取器(`internal: true`)数量不限。

```yaml
# 正则提取器 — 最常用,用于 RCE/文件包含/SQLi 结果提取
extractors:
- type: regex
name: cmd_result # 提取结果名称
part: body
regex:
- "CMD_RESULT:(.*)" # 正则匹配
group: 1 # 捕获组序号

# JSON 提取器 — 从 JSON 响应中提取数据
extractors:
- type: json
name: user
part: body
json:
- '.[] | .id'

# KVAL 提取器 — 提取响应头中的键值
extractors:
- type: kval
kval:
- content_type # 注意:短划线必须替换为下划线

# DSL 提取器 — 基于表达式提取
extractors:
- type: dsl
dsl:
- len(body)

# 动态提取器(供后续请求使用)
extractors:
- type: regex
name: csrf_token
part: body
regex:
- '<input\sname="csrf_token"\svalue="([[:alnum:]]{16})"\s/>'
group: 1
internal: true # 不输出到终端,仅供后续请求使用 {{csrf_token}}
```

## 严重级别指南

| 级别 | 适用场景 |
|----------|-------------|
| **critical** | RCE、未授权数据泄露、硬编码关键凭据、可获取服务器控制权、任意文件上传执行 |
| **high** | SQL 注入、认证绕过、LFI/RFI、SSRF 访问内网、任意文件上传 |
| **medium** | XSS、敏感信息泄露、目录列表、默认凭据、CSRF |
| **low** | 轻微信息泄露、非敏感配置错误、可被利用但影响有限的漏洞 |
| **info** | 版本检测、技术指纹识别、暴露面板(无直接漏洞) |

## 标签参考

| 类别 | 建议标签 |
|----------|---------------|
| 基于 CVE | `cve``cve-YYYY-NNNNN` |
| RCE/代码执行 | `rce``unauth` |
| SQL 注入 | `sqli``sqli-error``sqli-blind` |
| XSS | `xss``reflected-xss``stored-xss` |
| SSRF | `ssrf` |
| 文件包含 | `lfi``rfi` |
| 文件/路径暴露 | `exposure``config``backup``git` |
| 默认凭据 | `default-login``default-credentials` |
| 面板/后台暴露 | `exposed-panel``admin-panel``login` |
| 配置错误 | `misconfig``exposure` |
| 认证绕过 | `auth-bypass``unauth` |
| SSTI | `ssti` |

## 常见模板模式

### 模式 1:简单文件/目录检测

```yaml
id: exposed-env-file

info:
name: 暴露的 .env 文件
author: security-researcher
severity: medium
description: 检测包含敏感凭据的暴露 .env 文件,可能泄露数据库密码等关键信息。
impact: 攻击者可获取数据库连接信息、API密钥等敏感凭据,导致数据泄露或进一步渗透。
remediation: 在 Web 服务器配置中禁止对 .env 文件的访问,或将 .env 文件移出 Web 根目录。
reference:
- https://example.com/advisory
metadata:
fofa-query: 'body="DB_HOST" && body="DB_PASSWORD"'
tags: exposure,config,env

http:
- method: GET
path:
- "{{BaseURL}}/.env"
matchers:
- type: word
words:
- "DB_HOST"
- "DB_PASSWORD"
condition: and
```

### 模式 2:POST 方式的 RCE(含提取器)

```yaml
id: cve-2024-xxxxx-rce

info:
name: ExampleApp CVE-2024-XXXXX 远程代码执行
author: security-researcher
severity: critical
description: ExampleApp 存在未授权 RCE,通过向 /api/exec 发送构造的 POST 请求可执行任意系统命令。
impact: 未经认证的攻击者可远程执行任意系统命令,完全控制目标服务器。
remediation: 立即升级至 ExampleApp v2.5.1 及以上版本。临时缓解:在防火墙上限制 /api/exec 端点访问。
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2024-XXXXX
metadata:
fofa-query: 'app="ExampleApp"'
tags: cve,cve-2024-xxxxx,rce,unauth

http:
- method: POST
path:
- "{{BaseURL}}/api/exec"
headers:
Content-Type: application/json
body: '{"cmd": "id"}'

matchers-condition: and
matchers:
- type: word
words:
- "uid="
- type: status
status:
- 200

extractors:
- type: regex
name: cmd_result
regex:
- 'uid=\d+\((\w+)\)'
group: 1
```

### 模式 3:原始请求 + 多步骤利用

```yaml
id: multi-step-auth-bypass

info:
name: 多步骤认证绕过漏洞
author: security-researcher
severity: high
description: 通过 Token 泄露结合权限校验缺失,可实现认证绕过并访问管理接口。
impact: 攻击者可绕过认证机制,直接访问管理后台,获取敏感数据或执行管理操作。
remediation: 修复 Token 泄露接口的权限校验,确保所有管理接口均需有效认证。
reference:
- https://example.com/advisory
metadata:
fofa-query: 'app="VulnerableApp"'
tags: auth-bypass,multi-step

http:
- raw:
- |
GET /api/leak-token HTTP/1.1
Host: {{Hostname}}

- |
POST /api/admin-action HTTP/1.1
Host: {{Hostname}}
Authorization: Bearer {{token}}

extractors:
- type: regex
name: token
part: body
regex:
- '"token":"([^"]+)"'
group: 1
internal: true

matchers:
- type: word
words:
- "admin"
part: body
```

### 模式 4:文件包含漏洞(含提取器)

```yaml
id: lfi-path-traversal

info:
name: 路径遍历导致的本地文件包含漏洞
author: security-researcher
severity: high
description: 通过路径遍历读取服务器上的敏感文件,如 /etc/passwd,存在 LFI 漏洞。
impact: 攻击者可读取服务器上的任意文件,包括配置文件、源代码和系统文件,导致敏感信息泄露。
remediation: 对用户输入的路径参数进行严格白名单校验,禁止包含 "../" 等路径遍历字符。
reference:
- https://example.com/advisory
metadata:
fofa-query: 'body="file=" && body="view"'
tags: lfi,path-traversal

http:
- method: GET
path:
- "{{BaseURL}}/view?file=../../../../etc/passwd"

matchers:
- type: word
words:
- "root:x:0:0:"

extractors:
- type: regex
name: file_content
regex:
- 'root:x:0:0:.*'
```

## 辅助函数参考

Nuclei 支持丰富的 DSL 辅助函数,可在 `raw` 请求和 DSL 表达式中使用。完整列表参见:[Helper Functions 官方文档](https://docs.projectdiscovery.io/templates/reference/helper-functions)

### 常用辅助函数

| 函数 | 描述 | 示例 | 输出 |
|------|------|------|------|
| `base64(src)` | Base64 编码 | `base64("Hello")` | `SGVsbG8=` |
| `base64_decode(src)` | Base64 解码 | `base64_decode("SGVsbG8=")` | `Hello` |
| `md5(input)` | MD5 哈希 | `md5("Hello")` | `8b1a9953c4611296a827abf8c47804d7` |
| `sha256(input)` | SHA256 哈希 | `sha256("Hello")` | `185f8db32271fe...` |
| `url_encode(input)` | URL 编码 | `url_encode("hello world")` | `hello%20world` |
| `url_decode(input)` | URL 解码 | `url_decode("hello%20world")` | `hello world` |
| `to_lower(input)` | 转小写 | `to_lower("HELLO")` | `hello` |
| `to_upper(input)` | 转大写 | `to_upper("hello")` | `HELLO` |
| `concat(args...)` | 字符串拼接 | `concat("a", "b", "c")` | `abc` |
| `contains(input, sub)` | 检查子串 | `contains("Hello", "lo")` | `true` |
| `len(arg)` | 获取长度 | `len("Hello")` | `5` |
| `rand_base(n)` | 生成 n 位随机字符串 | `rand_base(8)` | `aB3xK9mQ` |
| `rand_text_alpha(n)` | 生成 n 位随机字母 | `rand_text_alpha(8)` | `AbCdEfGh` |
| `rand_text_numeric(n)` | 生成 n 位随机数字 | `rand_text_numeric(8)` | `38472910` |
| `rand_int(min, max)` | 生成随机整数 | `rand_int(1, 100)` | `42` |
| `unix_time()` | 当前 Unix 时间戳 | `unix_time()` | `1700000000` |
| `hex_encode(input)` | Hex 编码 | `hex_encode("aa")` | `6161` |
| `hex_decode(input)` | Hex 解码 | `hex_decode("6161")` | `aa` |
| `reverse(input)` | 字符串反转 | `reverse("abc")` | `cba` |
| `replace(str, old, new)` | 字符串替换 | `replace("Hello", "He", "Ha")` | `Hallo` |
| `gzip(input)` | GZip 压缩 | `base64(gzip("Hello"))` | `+H4sIAAAA...` |
| `gzip_decode(input)` | GZip 解压 | `gzip_decode(hex_decode("1f8b..."))` | `Hello` |
| `hmac(algo, data, key)` | HMAC 计算 | `hmac("sha1", "test", "key")` | `8856b111...` |
| `generate_jwt(json, algo, sig)` | 生成 JWT Token | `generate_jwt("{\"user\":\"admin\"}", "HS256", "secret")` | `eyJhbGci...` |
| `date_time(fmt)` | 格式化日期时间 | `date_time("%Y-%M-%D")` | `2024-01-15` |
| `regex(pattern, input)` | 正则匹配测试 | `regex("H.*o", "Hello")` | `true` |
| `ends_with(str, suffix)` | 检查结尾 | `ends_with("Hello", "lo")` | `true` |
| `starts_with(str, prefix)` | 检查开头 | `starts_with("Hello", "He")` | `true` |
| `repeat(str, n)` | 重复字符串 | `repeat("../", 5)` | `../../../../../` |
| `print_debug(args...)` | 调试输出 | `print_debug(1+2)` | `3` |
| `compare_versions(v, constraints...)` | 版本比较 | `compare_versions("v1.0.0", ">v0.9.0")` | `true` |

### 辅助函数使用方式

`raw` 请求中嵌入:
```yaml
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
Authorization: Basic {{base64('admin:admin')}}
X-Token: {{rand_text_alphanumeric(16)}}
```

在 DSL 匹配器中使用:
```yaml
matchers:
- type: dsl
dsl:
- "contains(to_lower(body), 'success') && status_code == 200"
- "len(body) > 100"
```

## 输出格式

始终在代码块中输出完整的 YAML。不要在文件内容中包含额外的注释说明。输出应可直接复制粘贴为 `.yaml` 文件:

```yaml
id: template-id

info:
name: 模板名称
author: d4m1ts
severity: medium
description: 模板描述。
impact: 漏洞造成的实际危害。
remediation: 修复建议。
reference:
- https://example.com
metadata:
fofa-query: 'app="Example"'
tags: example,tag

http:
- method: GET
path:
- "{{BaseURL}}/vulnerable-path"
matchers:
- type: word
words:
- "indicator-string"
- "another-indicator"
condition: and
```

## 最佳实践

1. **减少误报**:当存在 2 个或以上 matchers 时必须添加 `matchers-condition: and`,确保所有 matcher 同时命中才判定漏洞存在;单个 word matcher 内含 2 个或以上 words 时默认添加 `condition: and`,仅在关键词互斥(不可能同时出现)时才使用 `condition: or`
2. **RCE/LFI/SQLi 必须含提取器**:命令执行和文件包含等漏洞必须在模板中添加 extractors 展示漏洞结果,这是强制要求
3. **展示用提取器最多 1 个**:非 `internal` 的提取器每个 POC 限制为 1 个,如需展示多项信息应合并到一个提取器中;`internal: true` 的内部提取器数量不限
3. **info 块必须完整**:每个 POC 必须包含 name、author、severity、description、impact、remediation、reference、metadata.fofa_query、tags 九个字段
4. **fofa-query 必须真实有效**:提供可在 Fofa 平台实际使用的查询语句,用于资产测绘
5. **YAML 使用代码块**:始终用带 yaml 标记的代码块输出模板
6. **简单字符串匹配优先用 word**:比 regex 性能更好
7. **包含参考链接**:始终添加 CVE、公告 URL 或博客链接
8. **使用描述性 ID**:遵循模式如 `cve-YYYY-NNNNN``tech-stack-vuln-name``exposed-service-name`
9. **匹配最具体的特征**:不要匹配在大量响应中都会出现的通用文本
10. **在脑中验证模板**:确认匹配器对应真实的漏洞响应特征