| name | vuln-checklist |
| description | 从渗透测试报告中梳理漏洞信息,生成系统漏洞清单 Excel 表。触发词:渗透报告整理漏洞清单、导出xlsx漏洞台账、统一高中低危等级、多URL按地址拆分。Supports PDF, DOC, DOCX, HTML, Markdown, text reports. 无论几份报告均只生成一个xlsx文件。 |
| arguments | [{"name":"report_path","description":"渗透测试报告文件的本地路径(支持 PDF/DOC/DOCX/HTML/MD/TXT 等格式)","required":false},{"name":"workspace","description":"工作区目录的绝对路径","required":false}] |
渗透测试报告 -> 系统漏洞清单表
从渗透测试报告中提取漏洞信息,生成标准化的系统漏洞清单 Excel 文件。
快速触发
当用户出现以下需求时直接启用本技能:
- "把这些渗透报告整理成一个漏洞清单"
- "导出 xlsx 漏洞台账"
- "统一高/中/低危等级"
- "一个漏洞有多个 URL,按地址拆分"
- 上传渗透测试报告文件(PDF/DOC/DOCX/HTML/TXT/MD)
- 粘贴渗透测试报告文本内容
输入与输出
输入
- 一份或多份报告文件:
.pdf .doc .docx .html .txt .md
- 可选:统一系统名称(未提供时从文件名或报告内容推断)
- 可选:输出文件路径(默认
系统漏洞清单-{报告简称}-{日期}.xlsx)
输出
Excel 文件,15 列固定顺序(详见下方"输出模板"章节)。第 J-O 列由用户后续填写,合并规则见文末独立章节。
输出模板
生成的 xlsx 文件包含以下 15 列(表名固定为"漏洞清单"):
| 列序 | 列名 | 说明 |
|---|
| A | 序号 | 自动编号,从 1 开始 |
| B | 系统名称 | 受影响的系统/应用名称 |
| C | 漏洞名称 | 漏洞的简短标题 |
| D | 风险等级 | 标准化后的风险等级 |
| E | 漏洞位置 | 漏洞存在的具体 URL/IP/路径/参数 |
| F | 漏洞详情 | 漏洞的详细描述和技术细节 |
| G | 漏洞危害 | 漏洞被利用可能造成的危害 |
| H | 修复建议 | 具体的修复措施和建议 |
| I | 渗透测试报告 | 关联的原始报告名称 |
| J | 系统组别 | 留空,由用户后续填写 |
| K | 系统负责人 | 留空,由用户后续填写 |
| L | 漏洞修复情况 | 留空,由用户后续填写 |
| M | 漏洞修复时间 | 留空,由用户后续填写 |
| N | 备注 | 留空,由用户后续填写 |
| O | 漏洞修复验证情况 | 留空,由用户后续填写 |
第 J-O 列由用户后续填写,重点生成第 A-I 列内容。
风险等级映射规则
从报告中提取原始风险等级后,按以下映射表统一标准化(大小写不敏感):
| 标准化等级 | 匹配的原始关键词 |
|---|
| 高危 | 严重问题、严重、超高危、高危、Critical、High |
| 中危 | 中等问题、中危、Medium |
| 低危 | 风险提示、轻度问题、低危、Low(含空值) |
| 信息 | 信息、提示、Info、Information |
| (未匹配) | 保留报告中的原始值 |
映射由 generate_checklist.py 脚本自动执行,不需要手动处理。
多地址拆分规则
适用条件:仅当漏洞名称包含以下关键词时才执行拆分:
拆分方式:
- 对漏洞位置字段按以下分隔符拆分:换行符、分号(
; ;)、逗号(, ,)、连续空白字符
- 去除首尾空白,丢弃拆分后为空的项
- 每个有效地址生成一条独立记录(漏洞名称、详情、危害、修复建议等其他字段复制)
- 若拆分后仅剩一个地址,保持单行不拆分
不适用拆分的漏洞:保持原始地址字段不变,不做任何拆分。
执行流程
以下 7 个步骤必须严格按顺序执行,不可跳过或调序。
步骤 1:确认输入文件
- 若用户提供了文件路径,检查文件是否存在
- 若文件不存在,明确提示"文件路径不存在:{path}"并停止处理该文件
- 若用户未提供路径,向用户提问:
请提供渗透测试报告文件路径。支持 PDF/DOC/DOCX/HTML/MD/TXT 格式。
等待用户确认路径后再继续。支持同时处理多个文件。
步骤 2:提取文本
根据文件后缀选择提取工具:
| 格式 | 工具 | 安装命令 |
|---|
| PDF | pdfplumber | pip install pdfplumber --break-system-packages |
| DOCX | python-docx | pip install python-docx --break-system-packages |
| DOC | olefile | pip install olefile --break-system-packages |
| HTML | beautifulsoup4 | pip install beautifulsoup4 --break-system-packages |
| TXT / MD | 直接读取 | 不需要额外工具 |
使用以下 Python 脚本模式提取文本(按文件格式选用):
import pdfplumber
with pdfplumber.open(filepath) as pdf:
text = "\n".join(page.extract_text() or "" for page in pdf.pages)
from docx import Document
doc = Document(filepath)
text = "\n".join(p.text for p in doc.paragraphs)
import olefile
def extract_doc_text(filepath):
ole = olefile.OleFileIO(filepath)
data = ole.openstream("WordDocument").read()
runs = []
run = []
i = 0
while i < len(data) - 1:
ch = int.from_bytes(data[i:i+2], 'little')
if (0x4E00 <= ch <= 0x9FFF or 0x3000 <= ch <= 0x303F or
0xFF00 <= ch <= 0xFFEF or 0x20 <= ch <= 0x7E or
ch in (0x0D, 0x0A, 0x09)):
run.append(chr(ch))
else:
if len(run) >= :
runs.append(.join(run))
run = []
i +=
(run) >= :
runs.append(.join(run))
ole.close()
.join(runs)
text = extract_doc_text(filepath)
bs4 BeautifulSoup
(filepath, , encoding=) f:
soup = BeautifulSoup(f.read(), )
text = soup.get_text()
(filepath, , encoding=) f:
text = f.read()
如果某工具未安装,先安装再提取。提取失败时报告具体错误并终止该文件处理。
步骤 3:识别漏洞块
从提取的文本中识别每条漏洞的边界:
-
优先按结构化标签分段:查找以下模式作为漏洞块的起始标记:
- 编号标题(如
1. 1、 一、 (一) [1] 漏洞一)
- 漏洞名称关键词行(如
漏洞名称 漏洞标题 名称: 标题:)
- 明显的分隔线或区块边界
-
其次按风险等级关键词辅助切分:若上述模式无法定位,以风险等级关键词出现的位置辅助判断块边界。
-
确保每个漏洞块包含完整信息,不截断、不跨块合并。
步骤 4:抽取字段
对每个漏洞块逐字段提取,以下为必抽字段:
| 字段 | 提取说明 |
|---|
| 系统名称 | 从报告标题、范围描述或漏洞上下文中提取;多条漏洞共用同一系统的,复制系统名称 |
| 漏洞名称 | 报告中明确给出的漏洞标题/名称 |
| 风险等级 | 报告中标注的原始风险等级(脚本会自动映射) |
| 漏洞位置 | URL、IP、端口、文件路径、参数名称等;多个地址用分号分隔 |
| 漏洞详情 | 漏洞类型的详细描述、技术原理、利用条件等 |
| 漏洞危害 | 漏洞被成功利用后的业务影响描述 |
| 修复建议 | 报告给出的具体修复方案和措施 |
缺失字段处理:缺失的必抽字段填入"未提供",不填空字符串。
提取结果整理为 JSON 数组,写入 /tmp/vulns_input.json:
{
"report_title": "渗透测试报告名称",
"input_file_count": 2,
"vulnerabilities": [
{
"system_name": "XX系统",
"vuln_name": "SQL注入漏洞",
"risk_level": "高危",
"vuln_location": "https://example.com/api?id=1",
"vuln_detail": "参数id未过滤...",
"vuln_harm": "可获取数据库数据...",
"fix_suggestion": "使用参数化查询..."
}
]
}
步骤 5:执行多地址拆分
调用 generate_checklist.py,脚本内部自动执行:
- 风险等级映射(按上述映射表标准化)
- 多地址拆分(按上述拆分规则,仅对"未授权/敏感信息泄露/越权"类型执行)
- 生成 xlsx 文件
- 输出统计信息
python3 .opencode/skills/vuln-checklist/generate_checklist.py \
--input /tmp/vulns_input.json \
--output /workspace/系统漏洞清单-{报告简称}-{日期}.xlsx \
--report-title "{原始报告名称}"
步骤 6:导出 Excel
脚本生成的 xlsx 满足以下规格:
- 工作表名称固定为"漏洞清单"
- 表头样式:Microsoft YaHei 10pt 加粗,金色背景(#FFC000),水平垂直居中,自动换行,细线边框
- 数据行样式:Microsoft YaHei 10pt,自动换行,细线边框,左对齐(序号列居中)
- 列宽自动调整,基于内容最大宽度 +2,上限 50
- 行高自适应内容
- 自动筛选已启用
步骤 7:输出结果说明
从脚本的输出中解析统计信息,向用户展示:
输入文件数: N
漏洞总数(拆分后): N
拆分新增行数: N
风险等级分布: 高危=N, 中危=N, 低危=N, 信息=N
未识别风险等级条目数: N(若有则列出原始值)
输出文件: /workspace/系统漏洞清单-xxx-20260623.xlsx
同时提醒用户后续补充 J-O 列(系统组别、负责人、修复情况等)。
注意事项
- 严格按报告原文提取漏洞,不自行推断或猜测未明确提及的信息
- 风险等级映射和地址拆分由脚本自动完成,不要在 AI 提取阶段手动处理
- 文件命名格式:
系统漏洞清单-{报告简称}-{YYYYMMDD}.xlsx
- 多文件处理时,将所有漏洞合并到同一份 JSON,报告名称取第一个文件或有代表性的名称
- 若漏洞数量超过 50 条,先生成前 50 条让用户确认格式后继续
- 提取完成后将
/tmp/vulns_input.json 保留以便排查问题
质量检查清单
生成 xlsx 后必须逐项自检:
合并规则(最高优先级)
无论上传几份渗透测试报告,均只生成一个 xlsx 表格文件。所有报告的漏洞合并到同一份清单中,以 report_title 字段区分来源。除非用户明确要求生成几个 xlsx。