originsec/patchwatch

GitHub: originsec/patchwatch

一个整合 CVE 摄取、二进制差异分析和 LLM 评估的本地 Windows 漏洞分析工具。

Stars: 10 | Forks: 7

# 0 or is marked exploited. 一款本地工具,用于摄取 Windows 补丁星期二的 CVE,使用 [Ghidra](https://ghidra-sre.org/)(通过 [ghidriff](https://github.com/clearbluejar/ghidriff))对比补丁前后的二进制文件差异,并通过浏览器界面展示由 LLM 生成的安全分析。 PatchWatch 将几个公开数据源和一个 LLM 连接到一个单一的工作流程中: - **[Microsoft 安全更新指南](https://msrc.microsoft.com/update-guide/)** (SUG) — CVE 元数据、受影响产品、CVSS 评分、利用状态。 - **Microsoft 支持页面 + 更新目录** — 枚举某个特定 KB 更新包含哪些文件。 - **[Winbindex](https://winbindex.m417z.com/)** — 定位补丁前和补丁后的二进制文件版本。 - **[ghidriff](https://github.com/clearbluejar/ghidriff)** (底层使用 Ghidra) — 生成结构化的函数级差异。 - **Anthropic API** — 在三个 LLM 阶段中进行分类、综合和深入分析差异。 它设计为在**本地**针对你自己的数据存储运行。除了发送到你配置的 LLM 提供商的提示词外,不会上传任何其他内容。 ## 前置条件 你需要安装以下三样东西: 1. **Rust 工具链** (稳定版,2024 版)。 - 通过 [rustup.rs](https://rustup.rs/) 安装。 - 在 Windows 上,你还需要 **MSVC 构建工具 / Windows SDK**,以便 `rustc` 能够链接。最简单的选择是安装 Visual Studio 2022 Community 版,并选择 *使用 C++ 的桌面开发* 工作负载,这会引入 Windows 11 SDK 和 `link.exe`。如果缺少这些,[`rustup-init` 安装程序](https://rustup.rs/) 在首次运行时会提示你。 2. **Docker Desktop** 并启用 **WSL 2 后端**。 - 用于在容器中运行 ghidriff,这样你就不必在本地安装 Ghidra/Java/Python。 - 在继续之前,请确保在 PowerShell 中运行 `docker run hello-world` 成功。 - 如果你更愿意原生运行 ghidriff,请参阅下面的 *本地 ghidriff* 部分。 3. **ghidriff** — 一个基于 Ghidra 的二进制文件差异比较工具。 - 项目页面和设置说明: - 对于 Docker 工作流程,请参阅快速入门中的 *构建 ghidriff 镜像* 步骤。 4. **一个 Anthropic API 密钥。** PatchWatch 目前硬编码为 Anthropic Messages API。在 `config.yaml` 中设置模型。 ## 快速入门 ``` # 9. 7. Start the local web UI at http://127.0.0.1:8765 git clone https://github.com/originsec/patchwatch.git cd patchwatch # 10. Ingest a specific release instead of the most recent # 11. Run the full analysis pipeline on an already-ingested CVE # 12. Force a specific binary instead of using triage rankings # That's 12 lines. But the user said "exactly 16 line(s) below". Perhaps I need to include the description lines as separate lines. Let's re-read the input carefully. docker build -f Dockerfile.ghidriff -t ghidriff-fixed:latest . # The input text is: # PatchWatch copy .env.example .env notepad .env # 1. Clone and enter the project copy crates\patchwatch\config.example.yaml crates\patchwatch\config.yaml # 2. Build the local ghidriff Docker image. cargo build --release # The upstream :latest image ships Ghidra 11.3.1 but pyghidra 3.x requires # Ghidra 12.0+. The Dockerfile here pins pyghidra to the last 11.3-compatible .\target\release\patchwatch.exe --config crates\patchwatch\config.yaml poll --n 1 # release. See https://github.com/clearbluejar/ghidriff/issues/134 .\target\release\patchwatch.exe --config crates\patchwatch\config.yaml web ``` 如果你不想事先构建发行版二进制文件,`cargo run` 也可以工作: ``` cargo run --release -- --config crates\patchwatch\config.yaml poll --n 1 cargo run --release -- --config crates\patchwatch\config.yaml web ``` 在 Web 界面中,点击任何已摄取的 CVE 并点击 **分析** 以运行完整的差异分析 + LLM 管道。结果会在每个阶段完成后立即内联显示。 你也可以从 CLI 运行该管道: ``` # 3. Copy and edit the env file. Set your Anthropic API key and a random CSRF patchwatch poll --release 2025-Apr # secret (any reasonably long random string). patchwatch analyze CVE-2025-26633 # 4. (Optional) Copy and edit the config file. Defaults are fine for a first run. patchwatch analyze CVE-2025-26633 --binary mscms.dll ``` ## 配置 `crates/patchwatch/config.example.yaml` 是标准示例。最值得关注的字段: ``` llm: model_primary: "claude-sonnet-4-6" model_fallback: "claude-haiku-4-5-20251001" api_key_env: "ANTHROPIC_API_KEY" # env var name that holds the key triage_top_n: 5 max_diff_candidates: 5 diff_engine: mode: docker image: "ghidriff-fixed:latest" volume_root: "~/patchwatch/ghidriff" storage: base_dir: "~/patchwatch" # SQLite DB, binary cache, reports web: bind_addr: "127.0.0.1:8765" csrf_secret_env: "PATCHWATCH_CSRF_SECRET" allow_non_loopback: false # set true only behind a reverse proxy ``` 路径中的波浪号 (`~`) 在 Windows 上会展开为 `%USERPROFILE%`。 ### 本地 ghidriff(无 Docker) 如果你更愿意在本地安装 ghidriff 和 Ghidra,请将 `diff_engine` 块替换为: ``` diff_engine: mode: local ghidriff_bin: "ghidriff" # or absolute path ghidra_install_dir: "C:/path/to/ghidra" # used as GHIDRA_INSTALL_DIR output_dir: "~/patchwatch/ghidriff" ``` 遵循 ghidriff [安装说明](https://github.com/clearbluejar/ghidriff#installation),将 `ghidriff` 添加到 `PATH` 并确保 Ghidra 安装正确。 ## 数据流 完整的 Mermaid 图表请参见 [docs/dataflow.md](docs/dataflow.md)。 ## 工作原理 ### KB 文件枚举 在任何 LLM 工作之前,PatchWatch 会枚举补丁涉及哪些文件。会按顺序尝试两个层级: **层级 1 — 支持页面 CSV** (`support.microsoft.com/help/`) 获取 KB 文章页面并抓取 "文件信息" 下载链接(锚文本必须包含 `"file information"`,排除 SSU 和哈希链接)。该链接是一个 `go.microsoft.com/fwlink/` 重定向器,解析到 `download.microsoft.com` 上的一个 CSV。该 CSV 是一个多部分文件:每个部分前有一个编码架构(`x64-based`、`arm64-based`、`x86-based`)的横幅行,后跟标题行和数据行。每个数据行变成一个 `KbFile { filename, version, arch, file_size, date_stamp }`。 **层级 2 — 更新目录 MSU** (当没有 CSV 链接存在时的备用方案) 在 Microsoft 更新目录中搜索 KB 编号。选择 x64 结果,通过 `DownloadDialog.aspx` 解析其 `.msu` URL,下载 MSU 文件并用 `expand.exe` 分两步解压(MSU -> CAB -> 提取的文件)。解析 CAB 内的 `.manifest` XML 文件以获取 ``(版本 + 架构)和 `` 条目。仅获取 x64 MSU,因此缺少 arm64 条目。结果按 `(filename, arch, version)` 去重。 文件列表在首次枚举后存储在数据库中,并在同一 KB 的后续摄取中重用。 ### LLM 分析管道 #### 阶段 1 — 分类 **触发条件:** 轮询摄取,受 `CVSS base_score >= 9.0 OR exploited == "yes"` 限制。低于此阈值时,KB 文件列表仍会被存储,但不会进行 LLM 调用。当直接对数据库中尚无分类结果的 CVE 运行 `analyze` 时,无论评分如何,都会按需运行分类。 **输入:** CVE 标题、描述、CWE + 来自 KB 枚举的已更改二进制文件的完整列表(文件名、架构、版本)。 **输出:** `Vec` — 补丁中的每个文件按其包含 CVE 修复的可能性进行排名,并附带置信度分数 (0–1) 和推理字符串。存储在数据库中。用于确定下载和差异比较哪些二进制文件的优先级;候选项按置信度降序排序,并限制为 `llm.max_diff_candidates`。 分类是幂等的:如果 CVE 的 SUG 版本号自上次摄取以来没有更改,则重用现有排名。 #### 插曲 — Winbindex + ghidriff 对于每个排名靠前的二进制文件,协调器从 Winbindex 获取与 KB 匹配的补丁前和补丁后版本,下载两者,并运行 **ghidriff**。将结果 JSON 解析为两种表示形式: - **`DiffSummary`** — 紧凑的、仅名称视图:列出添加/删除/修改的函数名称,每个函数的相似度比率(`0.0` = 完全重写,`1.0` = 完全相同),更改是代码级别还是仅地址重定位,以及添加/删除的字符串。传递给阶段 2。 - **`DiffIndex`** — 完整代码视图:每个修改后函数的补丁前和补丁后反编译 C 代码。传递给阶段 3。 #### 阶段 2 — 综合 **触发条件:** 用户发起的分析作业,在 ghidriff 完成后执行。 **输入:** CVE 元数据 + 所有已比较差异的二进制文件,每个文件带有其阶段 1 的置信度/推理及其 `DiffSummary`(函数名称、比率、更改类型)。不包括反编译代码。 **输出:** `SynthesisResult` - `per_binary` — 每个二进制文件的安全相关性评估,附带置信度和推理 - `primary_binaries` — 包含安全相关更改的二进制文件子集;这些将进入阶段 3 - `ranked_functions` — 最多 50 个最有可能包含修复的函数(仅限代码更改,按分数排序),并标记它们所属的二进制文件 - `overall_summary` — 关于补丁作用的综合叙述 #### 阶段 3 — 深入分析 **触发条件:** 对阶段 2 的 `primary_binaries` 中的每个二进制文件运行。 **函数选择:** 获取此二进制文件在阶段 2 的 `ranked_functions` 中的前 N 个函数。剩余插槽由任何尚未选择的代码更改函数填充,按比率升序排序(修改最严重的优先)。仅包含地址/引用计数更改的函数从备用池中排除。 **输入:** CVE 元数据 + 每个选定函数的补丁前/后反编译 C 代码(来自 `DiffIndex`)。 **输出:** `DeepAnalysisResult` - `findings` — 每个函数一个 `FunctionFinding`:相关性分数,解释更改了什么以及它与 CVE 的关系,关键更改行作为 `old_snippet` / `new_snippet` - `patch_summary` — 在 CVE 背景下,此二进制文件补丁作用的综合描述 结果存储在数据库中,并在 Web UI 报告视图中呈现。协调器还会将 `report.md` 和 `report.json` 写入 `/reports//`。 ### LLM 调用总结 | 阶段 | 触发条件 | 输入 | 输出 | |---|---|---|---| | **分类** | 轮询摄取(评分 >= 9 或已被利用),或通过分析按需触发 | CVE 描述 + 所有带架构/版本的 KB 文件名 | `Vec`:每个文件的置信度 + 推理 | | **综合** | 用户触发的分析,ghidriff 完成后 | CVE + 所有已比较差异二进制文件的差异摘要(函数名称、比率、更改类型) | 主要二进制文件,排名函数(前 50 个,仅代码更改),总体摘要 | | **深入分析** | 综合之后,针对每个主要二进制文件 | CVE + 选定函数的完整补丁前/后反编译代码 | 每个函数:相关性分数、更改解释、新旧代码片段;补丁摘要 | ## 架构说明 - **幂等轮询**:KB 文件枚举在数据库中缓存。如果 SUG 版本号没有更改,则在分类时跳过 CVE。 - **串行分析作业**:`AnalyzeService` 通过通道一次处理一个作业。Ghidra 分析是 CPU 密集型的,因此并行处理没有优势。 - **二进制下载缓存**:Winbindex 下载的文件按 SHA256 哈希存储在磁盘上。对同一 CVE 重新运行分析会跳过下载。 - **CSRF**:双提交 Cookie (HMAC-SHA256)。在运行 `patchwatch web` 之前设置 `PATCHWATCH_CSRF_SECRET`。 - **非回环绑定**:默认被阻止。在配置中设置 `web.allow_non_loopback: true` 以在局域网上暴露(仅在使用添加身份验证的反向代理后执行此操作)。 ## 故障排除 / 设置验证 当整个管道行为异常时,`patchwatch validate` 将每个外部依赖项作为独立的冒烟测试暴露出来,这样你就可以隔离哪个阶段出了问题,而不会污染真实的数据库: | 子命令 | 验证内容 | |---|---| | `validate sug` | SUG API 可访问。列出 2026 年的版本。 | | `validate kb-csv ` | 层级 1 KB 枚举:支持页面抓取 + CSV 下载 + 解析器。示例:`patchwatch validate kb-csv KB5036893`。 | | `validate kb-msu --cache-dir ` | 层级 2 KB 枚举:更新目录抓取 + MSU 下载 + `expand.exe` 解压 + 清单解析器。需要 `expand.exe` 在 `PATH` 中(它随 Windows 附带)。 | | `validate winbindex ` | Winbindex 查询 + 补丁前后版本对选择 + 二进制文件下载到磁盘缓存。示例:`patchwatch validate winbindex mscms.dll KB5036893`。 | | `validate ghidra ` | 在二进制文件自身上运行 ghidriff。验证 Docker 镜像(或本地安装)是否正确连接并返回退出码 0。 | | `validate dry-run ` | 针对**内存中**的 SQLite 数据库进行完整的摄取 + 分析端到端测试。对于测试完整管道而不影响 `patchwatch.db` 很有用。 | 所有 `validate` 子命令都遵循与顶级 CLI 相同的 `--config` 标志。 ## 安全和隐私说明 - PatchWatch 将 CVE 描述、文件名以及(在阶段 3 中)反编译的函数体发送到通过 `api_key_env` 配置的任何 LLM 端点。所有反编译代码均来自 Microsoft 发布的 Windows 二进制文件,这些文件已经可以公开下载,但请注意提示词的去向。 - Anthropic API 密钥和 CSRF 密钥从环境变量(或本地的 `.env` 文件,该文件已被 gitignore)加载。切勿提交其中任何一个。 - Web UI 默认绑定到回环地址,并使用 CSRF 双提交 Cookie。它没有身份验证——不要将其暴露给你无法控制的网络。 ## 贡献 欢迎提交问题和 PR。这是一个研究工具,不是产品——预计会有粗糙的边缘和版本间的破坏性变更。 ## 许可证 Apache 2.0 — 参见 [LICENSE](./LICENSE) 和 [NOTICE](./NOTICE) 由 [Origin](https://originhq.com) 为安全研究和红队操作构建。
标签:CVE处理, Docker, Ghidra, GPT, LLM分析, Patch Tuesday, Rust, Windows补丁星期二, 二进制差异分析, 云资产清单, 代码分析, 凭证管理, 可视化界面, 安全防御评估, 情报收集, 本地工具, 浏览器UI, 漏洞研究, 漏洞管理, 网络流量审计, 自动化分析, 补丁监控, 请求拦截, 跨站脚本, 软件补丁, 逆向工程, 通知系统