cve_2026_92392_check.py 用于评估本地 curl 和 libcurl 制品是否存在
CVE-2026-92392,即 curl/libcurl 中
HTTP/2 上传的释放后使用(use-after-free)漏洞。
它支持被动本地清点、基于所提供 banner 的评估、非执行的挂载镜像扫描,以及有界的回环 HTTP/2 协议探测。该探测是防御性的,且非武器化。它不包含命令载荷、shellcode、内存地址操纵、信息泄露逻辑或 RCE 载荷。
主动探测仅绑定到 127.0.0.1,不接受远程目标 URL 或主机,并且仅执行所选的本地 curl 二进制文件。
该检查器区分四种不同的证据级别:
| 证据级别 | 它能确立什么 | 它不能确立什么 |
|---|---|---|
| 构建分类 | 一个带版本标识的 curl/libcurl 制品是否位于上游受影响范围之外、属于上游受影响但厂商补丁状态未知,或基于所提供的补丁状态证据被确认为受影响 | 应用程序是否实际使用了受影响的 HTTP/2 上传路径 |
| 运行时暴露上下文 | 所提供的应用程序事实是否表明 HTTP/2 上传能够到达攻击者控制的端点 | 漏洞是否被触发 |
| 协议刺激 | 本地回环测试装置是否在单个 HTTP/2 连接上通过两次上传交付了两种已记录的 reset 变体 | 释放后使用、崩溃原因或代码执行 |
| CVE 归因的 sanitizer 结果 | 候选序列、AddressSanitizer 堆释放后使用、上游受影响的制品标识以及匹配的 HTTP/2 调用栈是否均被观察到 | 在其他系统上的可靠性或实际可利用性 |
一次干净的运行、一次不完整的协议运行,或一次未崩溃的 sanitizer 运行,都不能证明某个构建是安全的。
CVE-2026-92392 影响 curl/libcurl 的 HTTP/2 上传处理。在上传过程中,受影响的构建可能处理携带 REFUSED_STREAM 或 HTTP_1_1_REQUIRED 的 HTTP/2 RST_STREAM。随后,在原始传输的 HTTP/2 状态被分离之后,缓冲的上传数据可能被解析为新请求。之后的 HTTP/2 回调可能解引用一个过期的 Curl_easy 指针。
用于修订此检查器的 REA 对比确认了相关的清理顺序差异:
Curl_conn_ev_data_done,处理待处理的句柄,然后才调用 Curl_req_done。Curl_req_done 到达 req_flush,而 HTTP/2 数据完成路径已经清除了流上下文。Curl_req_done,再执行 Curl_conn_ev_data_done,从而消除了该过期顺序。这是支持检查器证明模型的实现证据。厂商补丁状态仍需独立验证。
上游公告指出,存在漏洞的实现引入于 curl 8.12.0。检查器对上游版本分类如下:
| 版本条件 | 分类 |
|---|---|
| 早于 8.12.0 | NOT AFFECTED |
| 8.12.0 至 8.22.0(不含已修复的向后移植) | 上游受影响 |
| 8.14 分支在 8.14.3 或更高版本 | 已修复的向后移植 |
| 8.16 分支在 8.16.2 或更高版本 | 已修复的向后移植 |
| 8.20 分支在 8.20.2 或更高版本 | 已修复的向后移植 |
| 8.23.0 或更高版本 | NOT AFFECTED |
| 开发版、快照、nightly 或版本不明确 | INDETERMINATE |
厂商可以在不更改 curl 上游版本字符串的情况下向后移植修复。因此,受影响的上游版本是清点证据,而非厂商构建未打补丁的确凿证明。
仅当已通过厂商公告、软件包变更日志、源代码对比或其他可信的制品级方法验证了下游语义修复状态时,才使用 --patch-state。
--patch-state 值 | 含义 |
|---|---|
unknown | 默认值。受影响的上游版本会生成 UPSTREAM-AFFECTED VERSION。 |
absent | 运维人员已独立验证下游修复不存在。具备 HTTP/2 能力的受影响构建会生成 AFFECTED BUILD。 |
present | 运维人员已独立验证下游语义修复已存在。这是运维人员的断言,并非与 curl 上游修复在二进制层面等价的自动证明。 |
--poc 时需要本地 curl 可执行文件。--poc-proof asan 时需要经 AddressSanitizer 插桩的 curl 构建。--tls 时才需要 openssl 命令。主动 PoC 模式会拒绝脚本、包装器、无法识别的原生可执行文件以及 PE/Windows 二进制文件。被动评估仍可用于横幅和已挂载文件系统。
检查 PATH 中找到的 curl 二进制文件:
python3 cve_2026_92392_check.py
发出 JSON:
python3 cve_2026_92392_check.py --json
运行内部自测试:
python3 cve_2026_92392_check.py --self-test
python3 -O cve_2026_92392_check.py --self-test
检查选定的 curl 可执行文件和 libcurl 共享库:
python3 cve_2026_92392_check.py \
--curl-binary /opt/curl/bin/curl \
--libcurl-path /opt/curl/lib/libcurl.so \
--json
在不执行二进制文件的情况下评估受信任的 curl banner:
python3 cve_2026_92392_check.py \
--version-string 'curl 8.12.0 libcurl/8.12.0 nghttp2/1.61.0' \
--json
像 8.12.0 这样的裸版本号不能作为已验证的 curl/libcurl 身份证据被接受。
检查器有意不联系远程主机。请通过授权的管理渠道获取 banner,将其保存到本地,然后在本地进行评估:
ssh [email protected] 'curl --version' > host-curl-version.txt
python3 cve_2026_92392_check.py \
--version-file host-curl-version.txt \
--http2-use unknown \
--untrusted-upload unknown \
--https-certificate unknown \
--json
如果应用审查或可信追踪确认上传使用 HTTP/2、能够访问攻击者控制的端点,并接受其 HTTPS 证书,请明确提供这些事实:
python3 cve_2026_92392_check.py \
--version-file host-curl-version.txt \
--http2-use yes \
--untrusted-upload yes \
--https-certificate yes \
--patch-state unknown \
--json
对于明文 h2c,请使用 --https-certificate not-applicable。
--http2-use yes 标识运行时的 HTTP/2 使用情况。它并不能证明该
工件在编译时启用了 HTTP/2 支持。同样,--untrusted-upload yes
描述的是应用数据流,而 --https-certificate yes 记录的是
独立的 HTTPS 信任条件。
使用 --root 扫描已挂载的容器镜像、VM 镜像或解压后的
文件系统,而无需执行所发现的文件:
python3 cve_2026_92392_check.py \
--root /mnt/rootfs \
--json
根扫描:
curl、curl.exe 和 libcurl 的产物。INDETERMINATE。构建判定由两个条件驱动:
| 前提条件 | 含义 |
|---|---|
| P1 | 在受影响的上游范围内,经核实的 curl/libcurl 身份和版本,受经核实的下游补丁状态约束 |
| P2 | HTTP/2 支持已编译进被评估的产物 |
运行时暴露单独评估:
| 前提条件 | 含义 |
|---|---|
| P3 | 被评估的上传实际协商了 HTTP/2 |
| P4 | 应用程序可以上传到攻击者控制的 HTTP/2 端点 |
| P5 | 使用 HTTPS 时,HTTPS 证书被接受 |
| P6 | 漏洞利用特定的环境细节,如架构、libc、TLS 分配行为和 CA 证书包 |
| P7 | 漏洞利用侧的编排,如上传大小、并发性、载荷窗口和时序 |
P1 和 P2 决定构建适用性。P3 和 P4 决定是否识别出可能受影响的用途。P5 至 P7 影响远程利用条件,而非 HTTP/2 释放后使用漏洞是否存在。
| 判定 | 含义 |
|---|---|
NOT AFFECTED | 版本在上游受影响范围之外,识别出已修复的回移补丁,或权威确认 HTTP/2 不存在。 |
UPSTREAM-AFFECTED VERSION | 识别出具有 HTTP/2 支持的受影响上游版本,但下游补丁状态未知。 |
AFFECTED BUILD | 识别出受影响的上游版本和 HTTP/2 支持,并且 --patch-state absent 作为独立核实的证据提供。 |
INDETERMINATE | 无法确定产品身份、版本、HTTP/2 支持或发布状态。 |
默认主动探测针对绑定到 127.0.0.1 的服务器运行两次合成上传。它传递两种已记录的复位变体:
REFUSED_STREAMHTTP_1_1_REQUIRED对于每种变体,测试框架等待上传停滞,发送部分响应,发送 RST_STREAM,并记录流级证据。仅当两种复位变体均已传递,且每种变体在单个连接上观察到两个上传流时,协议证明才得到满足。
python3 cve_2026_92392_check.py \
--curl-binary /path/to/curl \
--poc \
--poc-proof protocol \
--json
STIMULUS REPRODUCED 的结果意味着已观察到有界协议条件。它并不证明 use-after-free、崩溃因果关系、CVE 归因或代码执行。
默认情况下,如果所选产物未被识别为受上游影响且支持 HTTP/2 的 curl 构建,则跳过 PoC 模式。--force 允许针对本地阴性对照运行无害的环回测试装置,但它不会绕过原生格式或产品身份验证。
python3 cve_2026_92392_check.py \
--curl-binary /path/to/known-fixed-curl \
--poc \
--force \
--json
AddressSanitizer 模式使用本地生成的合成上传内容,其中包含一个无害的类请求标记。它是一个候选清理路径探测,并非公开利用几何结构的副本。
python3 cve_2026_92392_check.py \
--curl-binary /path/to/asan/curl \
--poc \
--poc-proof asan \
--json
检查器仅在以下所有条件均成立时才报告 CVE-2026-92392 REPRODUCED:
heap-use-after-free。on_begin_headers 和 HTTP/2 上下文。若出现通用的 AddressSanitizer heap-use-after-free,但身份或堆栈不匹配,则报告为 SANITIZER UAF OBSERVED。这是一个内存安全信号,而非已确认的 CVE 归因。
若进程信号没有受支持的 sanitizer 诊断信息,则为 INCONCLUSIVE。
AddressSanitizer 构建配置示例:
CC=clang \
CFLAGS='-O1 -g -fno-omit-frame-pointer -fsanitize=address' \
LDFLAGS='-fsanitize=address' \
./configure --with-nghttp2 --disable-shared
make -j4
使用静态链接构建或有效的运行时库路径。不要依赖
LD_LIBRARY_PATH 或 DYLD_LIBRARY_PATH 来运行探测。
默认探测使用 h2c 先验知识。它测试 HTTP/2 清理 逻辑,但不声称能复现已公开的 TLS 或 RCE 堆布局。
使用 --tls 测试本地 HTTPS 和 ALPN h2 路径:
python3 cve_2026_92392_check.py \
--curl-binary /path/to/curl \
--poc \
--tls \
--json
在 TLS 模式下,检查器会为 127.0.0.1 创建一个有效期为一天的临时证书,通过 --cacert 将其提供给 curl,并在运行结束后删除临时材料。
重要字段包括:
| 字段 | 含义 |
|---|---|
verdict | 构建分类 |
reason | 支持构建判定的证据 |
exposure | 基于所提供上下文的运行时暴露评估 |
assessment_context.patch_state | 操作员提供的下游补丁状态 |
assessment_context.http2_use | 操作员提供的运行时 HTTP/2 使用事实 |
assessment_context.untrusted_upload | 操作员提供的端点可达性事实 |
assessment_context.https_certificate | 操作员提供的 HTTPS 证书接受事实 |
poc.status | 类型化 PoC 结果 |
poc.proof_satisfied | 是否达到所请求的协议或 ASan 证明级别 |
poc.protocol_reproduced | 两个变体是否均产生了所需的两次上传同一连接证据 |
poc.variant_matrix_complete | 两个重置变体是否均交付了有序基础刺激 |
poc.asan_uaf_observed | AddressSanitizer 是否报告了堆释放后使用 |
poc.cve_attribution_confirmed | 候选序列、受影响身份、ASan UAF 和匹配堆栈是否全部匹配 |
poc.cve_stack_match_variants | 具有所需符号化 HTTP/2 堆栈的重置变体 |
poc.two_stream_connection_variants | 在单个连接上观察到两次上传的变体 |
probe[].base_rst_stimulus_delivered | 为某个重置变体交付的有序基础刺激 |
probe[].candidate_sequence_delivered | 候选 ASan 序列是否到达重置后的 HTTP/2 流和响应 |
probe[].artifact_sha256_before 和 probe[].artifact_sha256_after | 用于检测所选二进制文件在探测期间发生变化的哈希值 |