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

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

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

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
gitlab-gitaly-fetch-ssrf — GitLab CE 19.4.1 Gitaly fetch SSRF 的概念验证与实验环境:GitHub/Bitbucket 导入器跳过了 resolved_address 固定,使已认证用户能够重新绑定 DNS 并访问内部主机。 | Kitploit
工具/GitHubGitHub/abraxas/gitlab-gitaly-fetch-ssrf
漏洞分析漏洞利用Web应用程序漏洞利用安全虚拟化渗透测试红队实验室与实践
GitHubabraxas/gitlab-gitaly-fetch-ssrf

gitlab-gitaly-fetch-ssrf

GitLab CE 19.4.1 Gitaly fetch SSRF 的概念验证与实验环境:GitHub/Bitbucket 导入器跳过了 resolved_address 固定,使已认证用户能够重新绑定 DNS 并访问内部主机。

查看仓库
215天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Abraxas Labs - gitlab-gitaly-fetch-ssrf

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  gitlab-gitaly-fetch-ssrf

gitlab-gitaly-fetch-ssrf

GitLab CE 19.4.1 - GitLab Inc.

GitHub Enterprise / Bitbucket Server 导入(以及启用该标志时的 Direct Transfer)会跳过 Projects::ImportService#get_resolved_address。Repository#fetch_as_mirror 默认 resolved_address: ""。Gitaly 的 FetchRemote / CreateRepositoryFromURL 会重新解析克隆主机名。UrlBlocker 此前已允许了一个公共 A 记录。重新绑定后,git-HTTP 对象就会落入被导入的项目中。

一个已登录、且能执行 GitHub Enterprise 导入的用户,可以让 Gitaly 对某个主机执行 git-fetch,而该主机已不再是 UrlBlocker 所固定的那个 IP。

ID暂无 CVE
CWECWE-918、CWE-367
CVSSHigh: 7.7 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
产品GitLab CE
受影响版本19.4.1-ce.0(v19.4.1-ee 树上的 26212baacadb)
认证已认证用户,GitHub Enterprise / Bitbucket Server 导入器
许可证GNU Affero GPL v3.0
实验环境仅 127.0.0.1

攻击者能做什么

将 GitHub Enterprise 导入指向其控制的主机名。Rails 的 UrlBlocker.validate! 允许了一个公共 A 记录。ParallelImporter.imports_repository? 为 true,因此 ImportService 从不固定地址。RepositoryImporter#fetch_as_mirror 以空的 resolved_address 调用 Gitaly。Gitaly 的 git 会 HTTP-fetch 该名称当前指向的任何地址。被导入的仓库中就包含了这些对象。

在全能 omnibus 上,那就是 worker 的 loopback。直接使用 http://127.0.0.1 克隆主机名会失败关闭。通过 URL 导入仓库已经会固定地址。Direct Transfer 需要 bulk_import_enabled(自管理默认 false)。

同一产品的同类遗留问题:Gitea HTTPS 导入固定地址丢失、webhook 0.0.0.0/8。

我是如何发现的

我阅读了 19.4.1 的补丁说明,然后看了导入器。Projects::ImportService#get_resolved_address 会将主机名重写为已验证的 IP,并将其传入 Gitaly。GitHub 和 Bitbucket Server 并行导入器设置了 imports_repository? 并跳过该路径。

project.repository.fetch_as_mirror(project.unsafe_import_url, refmap: refmap, forced: true)

fetch_as_mirror 默认 resolved_address: ""。Direct Transfer 的 repository_pipeline.rb 甚至调用了 validate! 却丢弃了返回值。

我搭建了原版 gitlab/gitlab-ce:19.4.1-ce.0。CE 的 import_sources 初始为空;实验环境启用了 GitHub。POST /api/v4/import/github 携带 github_hostname=http://ghe.lab:18080。GitLab netns 中的捕获器会响应伪造的 GHE JSON 以及 git http-backend。种子仓库 blob WITNESS 为 GITLAB-GITALY-FETCH-SSRF-WITNESS。

GET /api/v4/projects/1/repository/files/WITNESS/raw?ref=master 返回了该见证值。Gitaly 日志:FetchRemote 在 root/ghe-ssrf 上 grpc.code=OK。捕获器:git/2.55 的 info/refs 和 git-upload-pack。反向测试 github_hostname=http://127.0.0.1:18080 返回 400 Invalid URL。

已记录的弯路:种子 CveLabRoot9! 会被 WeakPasswords 拒绝(包含 root 子串);19.4 会在 64 字符处填充以绕过该检查;Faraday 无法连接到不是捕获器的公共 IP,因此测试框架将 1.1.1.1:18080 REDIRECT,而 UrlBlocker 仍看到公共 A 记录;git-HTTP 可能在 GET /repos/org/repo 翻转 DNS 之前就成功;GitLab 在导入中途返回 502,但之后文件仍然存在。一个反向 shell。纯属表演。判定依据是被导入的 blob 加上 Gitaly 的 FetchRemote。

实验环境

cd lab
./run.sh

目标仅限 http://127.0.0.1:18410。GitLab CE 需要数 GB 内存。仅限授权实验环境。

negative-loopback status=400 Invalid URL
witness-import status=201 import_status=scheduled
file-final http=200 body='GITLAB-GITALY-FETCH-SSRF-WITNESS'
SUCCESS GITLAB-GITALY-FETCH-SSRF imported-witness git-fetch-no-pin GITLAB-GITALY-FETCH-SSRF-WITNESS

遗留问题

def import_repository
  project.ensure_repository
  refmap = Gitlab::GithubImport.refmap
  project.repository.fetch_as_mirror(project.unsafe_import_url, refmap: refmap, forced: true)

像通过 URL 导入仓库已经做的那样,将 get_resolved_address 传入 fetch_as_mirror。也不要在 Direct Transfer 中丢弃 UrlBlocker.validate!。

参考资料

  • gitlab.com/gitlab-org/gitlab 标签 v19.4.1-ee
  • repository_importer.rb · repository.rb · import_service.rb
  • 同一产品:gitlab-gitea-import-ssrf · gitlab-webhook-0net-ssrf
  • CWE-918 · CWE-367

许可证

GNU Affero GPL v3.0。参见 LICENSE。仅限 loopback 实验环境。无任何担保。

下载工具