引言
我们知道已经多次提及,但为了新读者:Doyensec团队在地中海游轮上进行公司团建时,通过分析真实漏洞消磨时间,形成了!exploitable博客系列。
第一部分介绍了IoT ARM漏洞利用,第二部分尝试复现《黑客帝国2》中Trinity使用的漏洞。
本集将深入分析GitLab的CVE-2024-0402漏洞。如同洋葱般层层剥开,从YAML解析器差异到解压函数路径遍历,最终实现GitLab任意文件写入。
由于未公开PoC,我们决定扩展原作者的博客内容,提供完整的PoC信息闭环😉
背景知识
该漏洞影响GitLab Workspaces功能,该功能允许开发者快速启动包含所有依赖、工具和配置的集成开发环境(IDE)。
Workspaces功能依赖多个组件,包括运行的Kubernetes GitLab Agent和devfile配置:
- Kubernetes GitLab Agent:连接GitLab与Kubernetes集群,支持部署自动化和CI/CD流水线集成,同时启用Workspaces创建
- Devfile:定义容器化开发环境的开放标准,通过YAML文件配置项目所需的工具、运行时和依赖
示例devfile配置(需放置在GitLab仓库的.devfile.yaml中):
|
|
漏洞分析
绕过parent验证
GitLab使用devfile Gem(Ruby)调用外部devfile二进制文件(Go)处理.devfile.yaml。在Workspace创建过程中,PreFlattenDevfileValidator会调用validate_parent验证器:
|
|
parent选项允许devfile继承父配置,但该功能被明确阻止。
YAML解析器差异利用
通过YAML解析器差异(Ruby vs Go)绕过验证:
- Ruby的yaml库会处理
!binary
标签并进行base64解码 - Go的gopkg.in/yaml.v3会直接忽略该标签
测试示例:
|
|
Go输出:
|
|
Ruby输出:
|
|
通过此差异,可绕过validate_parent函数将parent选项传递至devfile二进制文件。
任意文件写入
在devfile二进制文件的decompress函数中发现路径遍历漏洞:
|
|
漏洞成因:
- header.Name来自远程tar包
- filepath.Clean无法处理相对路径(如
../../../../tmp/test
)
利用evilarc.py等工具可构造恶意tar包实现任意文件写入。
完整利用链
- 部署恶意devfile注册表:包含路径遍历tar包(位置:stacks/<STACK_NAME>/<STACK_VERSION>/archive.tar)
- 构造恶意.devfile.yaml:利用YAML解析差异指向恶意注册表
- 触发Workspace创建:GitLab服务器下载并解压恶意tar包,实现任意文件写入
利用要求:
- 具有代码提交权限的GitLab开发者账户
- 启用Workspace功能的GitLab实例(v16.8.0及以下)
环境配置提示
- 使用GitLab 16.8文档配置环境(新版已变更)
- 修补缺失的web-ide-injector容器镜像:
1 2
# 编辑/opt/gitlab/embedded/service/gitlab-rails/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:129 registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/gitlab-vscode-build:latest
- GitLab Agent需启用remote_development选项
漏洞利用
步骤1:部署恶意注册表
- 运行本地容器注册表:
1
docker run -d -p 5000:5000 --name local-registrypoc registry:2
- 构建并运行恶意devfile注册表(参考PoC仓库)
步骤2:构造恶意配置
在目标仓库的.devfile.yaml中添加:
|
|
步骤3:触发漏洞
通过GitLab Web UI创建新Workspace,系统将自动下载并解压恶意tar包。
权限提升
默认文件写入用户为git(GitLab核心用户),可通过覆盖以下文件实现权限提升:
/var/opt/gitlab/.ssh/authorized_keys
:添加无限制SSH密钥- 其他可写配置文件
示例SSH密钥替换:
|
|
成功后可通过SSH以git用户登录,并修改GitLab root用户密码:
|
|
结论
通过克服环境配置困难和有限连接,我们成功构建了CVE-2024-0402的完整PoC。这再次证明,优秀的漏洞往往存在于配置复杂、探索者稀少的领域。
感谢joernchen发现该漏洞链,以及他在研究中提供的详细路径描述。我们希望公开的PoC能帮助其他人节省时间!