RicheyWorks/ZeroDayFeedParser

GitHub: RicheyWorks/ZeroDayFeedParser

一个Java威胁情报工具,从NVD获取最新CVE,按CVSS严重性排序,导出CSV并通过Discord发送严重漏洞告警。

Stars: 0 | Forks: 0

# ZeroDayFeedParser 一个基于 Java 的网络安全威胁情报工具,可从 NIST 国家漏洞数据库(NVD)获取实时 CVE 数据,按 CVSS 严重性对漏洞进行排序,导出结果为 CSV,并在发现关键威胁时通过 Discord 发送实时告警。 本项目作为综合项目呈现实例,展示了 REST API 集成、JSON 解析、威胁排序逻辑和自动化告警功能。 --- ## 目录 - [功能特性](#功能特性) - [项目结构](#项目结构) - [前置条件](#前置条件) - [安装与配置](#安装与配置) - [配置说明](#配置说明) - [运行应用](#运行应用) - [输出结果](#输出结果) - [架构概览](#架构概览) - [类参考](#类参考) - [NVD API 说明](#nvd-api-说明) - [Discord Webhook 设置](#discord-webhook-设置) - [扩展项目](#扩展项目) - [已知限制](#已知限制) - [依赖项](#依赖项) --- ## 功能特性 - 从 NVD 2.0 REST API 获取最近的 20 条 CVE - 解析 CVSS v3.1 / v3.0 严重性评分以及 CPE 数据中的受影响产品/厂商 - 按严重性对所有威胁进行排序(最高优先) - 筛选出高(≥ 7.0)和严重(≥ 9.0)的条目用于导出和告警 - 将排序结果导出为带时间戳的 CSV 文件,存放于 `reports/` 目录 - 通过 Webhook 将严重 CVE 发布到 Discord 频道 - 支持 `--dry-run` 模式,测试时抑制 Discord 告警 - 优雅处理 NVD 速率限制,并给出清晰的错误提示 - API 密钥和 Webhook URL 从环境变量读取,不硬编码在源码中 --- ## 项目结构 ``` ZeroDayFeedParser/ ├── pom.xml ├── reports/ # Auto-created on first run; CSV output lands here └── src/ └── main/ └── java/ └── com/ └── zeroday/ ├── Main.java # Entry point ├── engine/ │ └── ThreatRanker.java # Sorting and filtering logic ├── export/ │ ├── CsvExporter.java # CSV file writer │ └── DiscordAlerter.java # Discord webhook client ├── feed/ │ └── NvdParser.java # NVD 2.0 API client + JSON parser └── model/ └── ThreatEntry.java # CVE data model ``` --- ## 前置条件 - Java 17 或更高版本 - Apache Maven 3.8+ - 能访问互联网(以连接 `services.nvd.nist.gov`) - 一个拥有 Webhook URL 的 Discord 服务器(可选,仅用于告警) - 一个免费的 NVD API 密钥(可选,可将速率限制从 5 次/30秒提升至 50 次/30秒) --- ## 安装与配置 **1. 克隆或下载项目** ``` git clone https://github.com/yourname/ZeroDayFeedParser.git cd ZeroDayFeedParser ``` **2. 通过 Maven 安装依赖** ``` mvn clean install ``` Maven 将自动拉取三个依赖: - `jsoup 1.17.2` — HTML/HTTP 工具 - `jackson-databind 2.16.1` — JSON 解析 - `rome 1.18.0` — RSS Feed 支持(预留用于未来的 Feed 解析器) **3. 设置环境变量(参见[配置说明](#配置说明))** **4. 运行** ``` mvn compile exec:java -Dexec.mainClass="com.zeroday.Main" ``` --- ## 配置说明 ZeroDayFeedParser 使用环境变量来存储所有敏感信息。切勿在源码文件中硬编码凭证。 ### NVD API 密钥(推荐,非必需) 如果没有密钥,NVD API 允许 **每 30 秒 5 次请求**。使用免费密钥后,提升至 **每 30 秒 50 次请求**。 注册地址:https://nvd.nist.gov/developers/request-an-api-key ``` \# Windows Command Prompt set NVD\_API\_KEY=your-key-here \# PowerShell $env:NVD\_API\_KEY="your-key-here" \# macOS / Linux export NVD\_API\_KEY="your-key-here" ``` ### Discord Webhook URL(可选) 如果未设置此变量,`DiscordAlerter` 将记录一条警告并优雅跳过告警,不会导致程序崩溃。 ``` \# Windows Command Prompt set DISCORD\_WEBHOOK\_URL=https://discord.com/api/webhooks/your-webhook-here \# PowerShell $env:DISCORD\_WEBHOOK\_URL="https://discord.com/api/webhooks/your-webhook-here" \# macOS / Linux export DISCORD\_WEBHOOK\_URL="https://discord.com/api/webhooks/your-webhook-here" ``` --- ## 运行应用 ### 正常运行 获取 CVE、排序、写入 CSV,并对严重条目发送 Discord 告警。 ``` mvn compile exec:java -Dexec.mainClass="com.zeroday.Main" ``` ### 试运行模式 抑制 Discord 告警。适用于测试、演示和开发。 ``` mvn compile exec:java -Dexec.mainClass="com.zeroday.Main" -Dexec.args="--dry-run" ``` ### 控制台输出示例 ``` \[Main] Fetched 20 CVEs from NVD. \[Main] 7 High/Critical CVEs after filtering. \[CsvExporter] Wrote 7 entries to reports/zeroday-2025-04-19.csv \--- High / Critical CVEs --- \[2025-04-18] CVE-2025-21234 9.8 (Critical) apache/tomcat \[2025-04-18] CVE-2025-20981 8.8 (High) microsoft/windows \[2025-04-17] CVE-2025-19874 8.1 (High) linux/kernel ... ``` --- ## 输出结果 ### CSV 报告 每次运行都会在 `reports/` 目录下生成一个以日期命名的 CSV 文件: ``` reports/zeroday-2025-04-19.csv ``` 列说明: | 列名 | 说明 | |---|---| | CVE | CVE 标识符(例如 CVE-2025-21234) | | Severity | CVSS 基础评分(0.0 – 10.0) | | Label | 严重 / 高 / 中 / 低 | | Product | 来自 CPE 数据的供应商/产品 | | Date | NVD 发布日期 | | Patch Link | 指向 NVD 详情页面的直接链接 | | Summary | 漏洞的英文描述 | ### Discord 告警格式 对于每个严重评分 ≥ 9.0 的 CVE,将向配置的 Discord 频道发送一条消息: ``` \*\*Zero-Day Alert!\*\* `CVE-2025-21234` scored \*\*9.8\*\* (Critical) Product: apache/tomcat Patch: https://nvd.nist.gov/vuln/detail/CVE-2025-21234 ``` --- ## 架构概览 ``` NVD 2.0 REST API │ ▼ NvdParser.java — Fetches JSON, maps each vulnerability to a ThreatEntry │ ▼ ThreatRanker.java — rank(): sorts by severity descending — filterHighAndAbove(): keeps CVSS ≥ 7.0 │ ├──────────────────────────────────────┐ ▼ ▼ CsvExporter.java DiscordAlerter.java Writes reports/zeroday-DATE.csv POSTs webhook for CVSS ≥ 9.0 ``` `ThreatEntry` 模型是在各层之间传递的共享数据对象。它故意设计为普通的 Java 对象(无框架注解),以保持模型的可移植性和可测试性。 --- ## 类参考 ### `Main.java` 入口点。编排完整流水线:获取 → 排序 → 筛选 → 导出 → 告警。接受命令行参数 `--dry-run` 以抑制 Discord 调用。 ### `model/ThreatEntry.java` 不可变数据类,代表单个 CVE。字段:`id`、`product`、`summary`、`patchLink`、`severity`(double)、`date`(LocalDate)。 ### `feed/NvdParser.java` HTTP 客户端,面向 NVD 2.0 REST API(`services.nvd.nist.gov/rest/json/cves/2.0`)。解析 JSON 响应树,提取 CVE ID、英文描述、CVSS v3.1 评分(降级到 v3.0)、发布日期以及来自 CPE 匹配数据的供应商/产品。读取 `NVD_API_KEY` 环境变量,若存在则将其作为请求头附加。在 HTTP 403(速率限制)时抛出带有描述信息的 `RuntimeException`,而不是静默返回空结果。 ### `engine/ThreatRanker.java` 包含两个刻意分离的方法: - `rank(List)` — 按严重性降序对所有威胁排序,不进行筛选。由调用者决定导出哪些内容。 - `filterHighAndAbove(List)` — 仅返回 CVSS ≥ 7.0 的条目。 - `getSeverityLabel(double)` — 将评分映射为严重 / 高 / 中 / 低。 ### `export/CsvExporter.java` 将 UTF-8 编码的 CSV 写入 `reports/zeroday-DATE.csv`。如果 `reports/` 目录不存在则创建。按照 RFC 4180 转义摘要中的嵌入双引号。在原始评分旁包含严重性标签列。 ### `export/DiscordAlerter.java` 为每个 CVSS ≥9.0 的条目发送格式化的 Discord Webhook 消息。从环境变量 `DISCORD_WEBHOOK_URL` 读取 Webhook URL。如果变量未设置或为空,则记录一条通知并返回,不抛出异常。如果 Webhook 返回非 HTTP 204 状态码,则向 stderr 记录警告。 --- ## NVD API 说明 ### API 版本 本项目使用 **NVD 2.0 REST API**。旧版 1.1 JSON Feed(`nvdcve-1.1-recent.json`)已于 2023 年 12 月退役,返回 404。请勿使用。 本项目使用的实时端点: ``` https://services.nvd.nist.gov/rest/json/cves/2.0?resultsPerPage=20 ``` ### 速率限制 | 场景 | 限制 | |---|---| | 无 API 密钥 | 每 30 秒 5 次请求 | | 有免费 API 密钥 | 每 30 秒 50 次请求 | 如果超出限制,NVD 返回 HTTP 403。`NvdParser` 捕获此错误并抛出带有清晰消息的 `RuntimeException`,而不是静默返回零结果。 ### CVSS 评分 解析器首先尝试 CVSS v3.1,然后降级到 v3.0。如果两者都不存在(某些较旧或有争议的 CVE),严重性默认为 0.0,该条目将被 `filterHighAndAbove` 排除。 ### CPE 产品提取 供应商和产品名称从 `configurations` 块中的第一个 CPE 匹配字符串中提取。CPE 格式:`cpe:2.3:a:vendor:product:version:...`。这是尽力而为的做法——有些 CVE 没有 CPE 数据,将显示为 "Unknown"。 --- ## Discord Webhook 设置 1. 打开你的 Discord 服务器设置 → 集成 → Webhooks 2. 点击 **新建 Webhook**,给它一个名称(如 "ZeroDay Alerts"),并选择一个频道 3. 点击 **复制 Webhook URL** 4. 将其设置为环境变量 `DISCORD_WEBHOOK_URL`(参见[配置说明](#配置说明)) 告警器仅会发布 CVSS ≥ 9.0(严重)的 CVE。高严重性 CVE(7.0–8.9)仅导出到 CSV。 --- ## 扩展项目 ### 添加第二个 Feed 解析器 在 `com.zeroday.feed` 包中创建一个新类,返回 `List`。CIRCL CVE API 是一个不错的选择——它无需身份验证,并以干净的 JSON 格式返回最近的 CVE: ``` https://cve.circl.lu/api/last/10 ``` 然后在 `Main.java` 中合并结果,再传递给 `ThreatRanker`: ``` List all = new ArrayList<>(); all.addAll(nvdParser.fetchAndParse()); all.addAll(circlParser.fetchAndParse()); List ranked = ranker.rank(all); ``` ### 更改严重性筛选阈值 编辑 `ThreatRanker.filterHighAndAbove()` 中的常量: ``` .filter(t -> t.getSeverity() >= 7.0) // change 7.0 to your desired cutoff ``` ### 更改每次获取的 CVE 数量 编辑 `NvdParser` 中的 `resultsPerPage` 查询参数: ``` private static final String NVD\_URL = "https://services.nvd.nist.gov/rest/json/cves/2.0?resultsPerPage=50"; ``` NVD 允许的最大值为每请求 2000 条。 ### 定时自动运行 在 Windows 上,使用“任务计划程序”定时执行 Maven 命令。在 Linux/macOS 上,添加 cron 任务: ``` \# Run every 6 hours 0 \*/6 \* \* \* cd /path/to/ZeroDayFeedParser \&\& mvn -q compile exec:java -Dexec.mainClass="com.zeroday.Main" ``` --- ## 已知限制 - **HackerOneParser 尚未实现。** 仓库中的类存根不可用。HackerOne 没有免费的公开报告端点。它已被排除在主流水线之外。 - **无持久化去重。** 同一天运行两次工具会导致 CSV 中出现重复行,并且同一 CVE 会收到重复的 Discord 告警。简单的解决方案是在本地文件或 SQLite 数据库中记录已发布的 CVE ID。 - **产品字段是尽力而为的结果。** 并非所有 CVE 都提供 CPE 数据,提取逻辑仅使用第一个 CPE 匹配。涉及多个供应商的 CVE 可能只显示一个供应商。 - **无重试逻辑。** 瞬时网络故障将抛出异常而非重试。生产环境下,应将 HTTP 调用封装在带有指数退避的简单重试循环中。 --- ## 依赖项 | 依赖 | 版本 | 用途 | |---|---|---| | `org.jsoup:jsoup` | 1.17.2 | HTTP 工具 | | `com.fasterxml.jackson.core:jackson-databind` | 2.16.1 | JSON 解析 | | `com.rometools:rome` | 1.18.0 | RSS Feed 支持(预留) | 所有依赖均在 `pom.xml` 中声明,由 Maven 自动解析。Java 内置的 `java.net.http.HttpClient`(Java 11+)用于所有 HTTP 调用——无需额外添加 HTTP 客户端库。 --- ## 许可证 本项目作为网络安全综合项目提交。所有源代码均为作者原创。
标签:CVE, CVSS, Discord告警, GPT, JSON解析, JS文件枚举, Maven, NVD, PB级数据处理, REST API, 严重性评级, 二进制发布, 域名枚举, 威胁情报, 威胁情报源, 威胁源, 安全管理, 安全运维, 开发者工具, 开源工具, 数字签名, 数据提取, 渗透测试辅助, 漏洞管理, 漏洞验证, 网络安全, 网络安全监控, 网络调试, 自动化, 隐私保护, 零日漏洞, 驱动开发