gumslone/GumVulns

GitHub: gumslone/GumVulns

一款单文件 PHP 命令行工具,通过并行聚合多个漏洞数据库,支持按 CVE、关键词、CPE、purl 或 GitHub 链接检索漏洞情报并返回标准化结果。

Stars: 0 | Forks: 0

# GumVulns 一个单文件 PHP CLI,支持**并行搜索多个漏洞 API** 并 为每个匹配项返回标准化记录:**CVE id、描述、评分、严重程度、 攻击向量、来源**。 ## 环境要求 PHP 8.1+,并需配备 `curl`、`json` 和 `mbstring` 扩展。 ## 用法 提供三种查询模式,可根据输入自动检测: ``` # CVE id — 查询每个 source php gumvulns.php CVE-2021-44228 # keyword — NVD + Vulners php gumvulns.php "apache log4j" # GitHub download / source link — commit -> OSV.dev, owner/repo/tag -> CPE sources php gumvulns.php https://github.com/jquery/jquery/archive/refs/tags/3.3.1.zip php gumvulns.php https://github.com/owner/repo/commit/ # CPE / CPE stub — 解析 platform,解析其 title,返回所有匹配的 CVE php gumvulns.php "cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*" php gumvulns.php --cpe apache:log4j php gumvulns.php --cpe a:openbsd:openssh:9.1 --limit=20 # Package URL (purl) — 通过 OSV.dev 原生查询 php gumvulns.php "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1" php gumvulns.php "pkg:npm/lodash@4.17.20" php gumvulns.php "pkg:pypi/django@3.2" # 通用选项 php gumvulns.php CVE-2021-44228 --json php gumvulns.php CVE-2021-44228 --source=nvd,redhat php gumvulns.php --list-sources php gumvulns.php --help ``` ### CPE 模式 接受完整的 **CPE 2.3** 字符串 (`cpe:2.3:a:vendor:product:version:...`)、 旧版 **CPE 2.2 URI** (`cpe:/a:vendor:product:version`),或纯 **片段** (`product`, `vendor:product`, `vendor:product:version`, `a:vendor:product`)。 随后它会: 1. 将 CPE 解析为全部 11 个字段并输出分解结果。 2. 从 **NVD CPE 字典**解析平台标题。 3. 从支持 CPE 的来源(NVD `virtualMatchString`、Shodan CVEDB、Vulners)返回**所有匹配的 CVE**,并**按 CVE id 去重**。 每一行列出了报告该漏洞的所有来源。 结果排序规则为:**已确认存在漏洞的优先**(如果提供了版本号), 然后按 **CVSS 评分**排序;如果评分相同,则具有**已知公开 漏洞利用程序**(见下文)的 CVE 排名高于未被利用的 CVE。 ### 在 CPE 模式中添加 OSV (`--osv-package`) OSV.dev 不支持 CPE 搜索 —— 其查询 API 基于包坐标而非 CPE。要将 OSV 结果引入 CPE 搜索中,请显式指定包: ``` php gumvulns.php --cpe apache:log4j:2.14.1 \ --osv-package=Maven:org.apache.logging.log4j:log4j-core # 或一个 Package URL: php gumvulns.php --cpe apache:log4j:2.14.1 \ --osv-package="pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1" ``` `SPEC` 格式为 `ecosystem:name[@version]`(名称本身可以包含 `:`,例如 Maven 坐标)或一个 purl。如果提供了版本,则默认使用 CPE 的版本,因此 OSV 会精确返回影响该版本的公告 —— 这些结果会通过 CVE id 合并到 CPE 结果中,并通过 OSV 的版本 范围标记为 **VULNERABLE**。 ### 包 URL (purl) 模式 传入一个 [purl](https://github.com/package-url/purl-spec),GumVulns 将进行 **原生 OSV.dev 查询**(OSV 直接理解 purl,包括其版本),因此 您会准确获得影响该包版本的公告 —— 每一项都通过 OSV 的版本 范围标记为 **VULNERABLE**: ``` php gumvulns.php "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1" php gumvulns.php "pkg:npm/lodash@4.17.20" php gumvulns.php "pkg:pypi/django@3.2" ``` purl 的 `name` 和 `version` 也将用于查询支持 CPE 的来源 (NVD、Shodan、EUVD、Vulners),并用于驱动漏洞利用/PoC 和 EOL 补充信息,所有结果 均按 CVE id 合并。在此模式下,OSV 是权威的匹配器;CPE 来源 仅作为尽力而为的参考(purl 名称可能不等同于厂商的 CPE 产品字符串)。 ### GitHub 链接模式 粘贴一个 GitHub 下载或源码 URL,GumVulns 会提取其中的关键信息: | URL 形式 | 提取内容 | |---|---| | `…/archive/.tar.gz`, `…/commit/`, codeload `…/zip/` | commit SHA | | `…/archive/refs/tags/.zip`, `…/releases/download//…` | owner, repo, version | | `…/tree/`, `…/blob//…`, `raw.githubusercontent.com////…` | owner, repo, ref | 随后进行以下搜索: - **通过 commit** 在 **OSV.dev** 中搜索(使用 `{"commit": …}` 调用 `/v1/query`) —— OSV 会将该哈希值 与每个公告的 git 范围进行匹配。短 SHA 会首先通过 GitHub API 解析为完整 哈希(`GITHUB_TOKEN` 可提高速率限制)。 - **通过 CPE**(`owner`→vendor,`repo`→product,`tag`→version)在支持 CPE 的 来源(NVD、Shodan、Vulners)中进行搜索。 来自两条路径的结果将合并,并按 CVE id 去重。 ## 受影响版本范围 结果包含每个 CVE 的**受影响版本范围** —— 即该 范围起始和结束的版本,并带有包含/排除边界: - **NVD** —— 来自 CPE 配置节点的 `versionStartIncluding/Excluding` + `versionEndIncluding/Excluding`。 - **OSV** —— `introduced` / `fixed` / `last_affected` 事件(为支持生态系统/semver 版本,跳过 GIT commit 范围)。 - **GitHub Advisory** —— 每个受影响包的 `vulnerable_version_range`。 - **EUVD** —— ENISA 的 `product_version` 字符串(自由格式)。 在表格中,它们显示为一个 `Affected` 区块,例如: ``` Affected: org.apache.logging.log4j:log4j-core: >= 2.13.0, < 2.16.0 org.apache.logging.log4j:log4j-core: < 2.12.2 ``` `>=`/`<=` 表示该版本处于边界**包含**范围内,`>`/`<` 表示 **不包含**,而 `= X` 表示单一受影响版本。在 CPE 模式下,来自 所有来源的范围都会被合并并去重。`--json` 输出会将它们以结构化形式存放在 `affected[]` 下: ``` { "product": "org.apache.logging.log4j:log4j-core", "version_start_including": "2.13.0", "version_start_excluding": null, "version_end_including": null, "version_end_excluding": "2.16.0", "range": "org.apache.logging.log4j:log4j-core: >= 2.13.0, < 2.16.0" } ``` ## 版本漏洞标记 当您提供**版本**(例如 `apache:log4j:2.14.1` 之类的 CPE 或 GitHub tag 链接)时,GumVulns 会将其与每个 CVE 的受影响范围进行对比并标记: ``` Status: ⚠ VULNERABLE — queried version is within log4j: >= 2.13.0, < 2.16.0 Status: ✓ not affected — queried version is outside the affected ranges Status: ? unknown — no comparable version range for this product ``` 比对过程使用 PHP 的 `version_compare`(可处理 `2.0-beta9`、`1.2.1.2-jre17` 等),并遵循包含/排除边界。仅当漏洞范围的**产品** 与查询匹配时才会进行考量,因此查询 log4j 时,不会与诸如 仅仅捆绑了 log4j 的 Siemens 固件范围进行判定。已确认存在漏洞的结果 将置顶排序。`--json` 输出会为每个结果添加 `vulnerable`(`true`/`false`/ `null`)以及 `matched_range` 字段。 ## 漏洞利用 / PoC 可用性 每个结果都会为其 CVE 标注已知的**公开漏洞利用程序 / PoC** (表格中显示为 `Exploit:` 行,JSON 中显示为 `exploits[]`)。指标体系参考自 [search_vulns](https://github.com/ra1nb0rn/search_vulns): | 指标 | 来源文件 | 模式 | |---|---|---| | **Nuclei** 模板 | `projectdiscovery/nuclei-templates` `cves.json` | 所有 | | **Exploit-DB** | `exploit-database/exploitdb` `files_exploits.csv` | 所有 | | **Metasploit** | `rapid7/metasploit-framework` `db/modules_metadata_base.json` | 所有 | | **PoC-in-GitHub** | `nomi-sec/PoC-in-GitHub` (按 CVE 区分的 JSON) | CVE id 查询 | 这三个批量文件会(并行)下载一次,并 在 `~/.cache/gumvulns` 中缓存 6 小时;预热运行不会增加延迟。PoC-in-GitHub 是按 CVE 获取的,因此它仅在单个 CVE 查找时运行。使用 `--no-poc` 可跳过 所有漏洞利用补充信息。 ## 生命周期结束 (EOL) 状态 在提供版本号的 CPE / GitHub 模式下,GumVulns 会针对该产品查询 [endoflife.date](https://endoflife.date),并报告所查询 版本的发布分支是处于**支持阶段**还是**生命周期结束 (END-OF-LIFE)**: ``` Lifecycle: ⚠ END-OF-LIFE (branch 1, latest 1.2.17, EOL 2015-10-15) Lifecycle: supported (branch 2, latest 2.26.0) ``` 这会显示在 CPE 信息头部以及 JSON 输出的 `eol` 字段中。 ## CVSS 评分 当来源仅提供 CVSS **向量**而没有基础分数时(例如 OSV),将使用内置计算器 根据向量计算分数和定性严重程度,该计算器支持 **CVSS v2 和 v3.0/v3.1**(带前缀、纯粹或 带括号的向量)。CVSS v4 向量将予以显示,但暂不进行评分。 ## 来源 | 来源 | API key | CVE 查找 | 关键词 | CPE | Commit | |---|---|---|---|---|---| | NVD (NIST) | 可选 `NVD_API_KEY` | ✅ | ✅ | ✅ | — | | CIRCL CVE Search | — | ✅ | — | — | — | | Red Hat Security Data | — | ✅ | — | — | — | | Shodan CVEDB | — | ✅ | — | ✅ | — | | Ubuntu Security | — | ✅ | — | — | — | | OSV.dev (Google) | — | ✅ | — | — | ✅ | | GitHub Advisory DB | 可选 `GITHUB_TOKEN` | ✅ | — | — | — | | CISA KEV (已知漏洞利用) | — | ✅ | — | — | — | | FIRST EPSS (漏洞利用概率) | — | ✅ | — | — | — | | EUVD (ENISA, EU 数据库) | — | ✅ | ✅ | ✅ | — | | CVE Details (HTML 抓取) | cookie,见下文 | ✅ | — | — | — | | Vulners | `VULNERS_API_KEY` | ✅ | ✅ | ✅ | — | | VulnCheck | `VULNCHECK_API_KEY` | ✅ | — | — | — | | 漏洞利用/PoC 指标 | — | 补充信息 (所有模式) | | | | | endoflife.date | — | EOL 状态 (带版本) | | | | 除了上述查询来源外,结果还会被**进一步丰富**:每个 CVE 都会 标注已知的公开漏洞利用程序/PoC(Nuclei、Exploit-DB、Metasploit、PoC-in-GitHub —— 参考自 [search_vulns](https://github.com/ra1nb0rn/search_vulns)),并且当 提供版本时,会从 endoflife.date 获取其生命周期结束 (EOL) 状态。请参阅下文的 [漏洞利用 / PoC 可用性](#exploit--poc-availability) 和 [生命周期结束状态](#end-of-life-status)。 九个来源可以在**零配置**下运行。带密钥的来源在其 环境变量被设置时会自动启用: ``` export NVD_API_KEY=... # strongly recommended — NVD throttles hard without it export GITHUB_TOKEN=... export VULNERS_API_KEY=... export VULNCHECK_API_KEY=... ``` ### EUVD (ENISA) 和 CVE Details - **EUVD** 使用 ENISA EU 漏洞数据库 JSON 搜索 API (`euvdservices.enisa.europa.eu/api/search`)。CVE 查找通过文本搜索,并 保留 `aliases` 中包含该 CVE 的记录;CPE 模式则通过 `product`/`vendor` 进行过滤。 - **CVE Details** 没有免费 API 且处于 Cloudflare 保护之下,因此 GumVulns **会抓取公开的 CVE 页面** (`cvedetails.com/cve//`),从页面 meta 标签中提取 描述,并从 HTML 中提取 CVSS 向量(随后在本地计算 分数)。匿名服务器请求会收到 `403` Cloudflare 质询 —— 若要使用此功能,请从浏览器中复制 `cf_clearance`/会话 cookie 并导出: export CVEDETAILS_COOKIE='cf_clearance=...; ...' ## 输出 每个来源都会被标准化为相同的字段,当来源未提供严重程度时,将根据 CVSS 基础分数进行推导。请求通过 `curl_multi` 并发执行,因此总延迟大致 等于最慢来源的延迟。`Sources queried` 页脚会报告每个来源的 HTTP 状态、结果数量以及任何错误。 ## 添加来源 实现 `VulnSource`(`id`、`name`、`buildRequest`、`parse`),并将一个实例 添加到 `gumvulns_sources()` 中。聚合器会为您处理并发、超时和 错误报告。
标签:API聚合, CPE解析, CVE查询, ffuf, Homebrew安装, OpenVAS, PHP, XSS, 实时处理, 文档结构分析, 漏洞情报