首页 > 其他分享 >CVE-2023-2825-GitLab目录穿越poc

CVE-2023-2825-GitLab目录穿越poc

时间:2023-06-05 21:55:39浏览次数:56  
标签:gitlab group GitLab upload send proxy file 2023 poc

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

图片1添加项目附件

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

下载文件

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

图片3

成功读取文件

漏洞分析

这个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状态码 请求也不会转发到后端

/a/b/../../../

但是如果我们把目录穿越的部分进行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

图片4

因此,我们不能仅仅依赖简单的编码方式来绕过这个限制。相反,我们需要构造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)
  end
end

漏洞深入利用

漏洞利用的时候注意要足够数量的group 才能从储存目录穿越到根目录 5层可能不够
图片5
读取文件时会作为git 用户组的权限进行读取
gitlab 的文件权限十分严格
redis pg数据库的文件无法访问
但是可以访问一些配置文件 部分私钥凭据 全部的git仓库数据 等

利用条件

存在可以达到根目录的嵌套可公开访问到的group项目 而且存在附件(issus 评论 等)

普通用户权限 手动创建 多层group和项目

影响范围

gitlab-ee/ce == 16.0.0

修复方法

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

文章转自Gitlab CVE-2023-2825 一个罕见的目录穿越漏洞 - 白帽酱の博客 (rce.moe)

标签:gitlab,group,GitLab,upload,send,proxy,file,2023,poc
From: https://www.cnblogs.com/mt0u/p/17459012.html

相关文章

  • 2023-06-05:Redis官方为什么不提供 Windows版本?
    2023-06-05:Redis官方为什么不提供Windows版本?答案2023-06-05:Redis官方没有提供Windows版本有几个原因。1.Redis的开发团队规模较小,由三四名核心开发者组成。他们更加熟悉和习惯Unix-like系统,在这些系统上进行开发和测试可以更高效地进行。然而,提供Windows版本会消耗较多资源,可......
  • 2023-06-05:Redis官方为什么不提供 Windows版本?
    2023-06-05:Redis官方为什么不提供Windows版本?答案2023-06-05:Redis官方没有提供Windows版本有几个原因。1.Redis的开发团队规模较小,由三四名核心开发者组成。他们更加熟悉和习惯Unix-like系统,在这些系统上进行开发和测试可以更高效地进行。然而,提供Windows版本会消耗较多资源,可能会......
  • 2023年最新sentinel-dashbord部署安装(保姆级别)
    目录Sentinel-dashboard安装下载前景提要一、构建环境二、下载安装与配置1、进入百度搜索:Sentinel或访问地址:面向云原生微服务的高可用流控防护组件2、进入git主界面,然后找到如图位置(此处为各个发布版本)。3、看到版本信息,找到下载的位置进行下载就可以了。4、下载后在本地的盘中......
  • 考研数学⭐每天几道题:偏导数和偏积分(2023年5月20日)
    1️⃣逆向解题:由偏导数求解偏积分关注荒原之梦⭐考研数学的博客园频道,让梦想茁壮成长......
  • 考研数学⭐每天几道题:偏微分和全微分(2023年5月21日)
    1️⃣用偏微分的定义计算全微分的特值问题(一)2️⃣用偏微分的定义计算全微分的特值问题(二)3️⃣由全微分反向积分求解原函数4️⃣对于有特值的题目一定要及时代入特值进行化简5️⃣对隐函数计算全微分6️⃣复合函数和隐函数联合求偏导:能代入的值先代入关注荒原之梦⭐考研数学的博客......
  • phpstudy小皮面板2023版RCE
    复现过程:绕过随机码-->堆叠注入-->计划任务-->命令执行环境版本:Linux版phpstudy=x.1.291-随机码绕过已知某站点使用phpstudy服务器搭建,使用默认端口访问phpstudy后台运维系统页面,返回404NotFound:加上user/login也依然如故:192.168.8.135:9080/user/login抓包添加一行:......
  • 2023-06-05 hexo 修改默认端口号(2种方案)
    前言:我又新建了一个hexo博客,运行时报错,提示4000端口已被占用,下面提供两钟解决方案:1.暂时修改端口号:修改package.json文件里的server,修改前:"server":"hexoserver"修改后:"server":"hexoserver-p4001"注意:这时候你需要用【npmrunserver】来开启服务。2.永久修改端......
  • 工作日记20230605
    要想使零部件在SOLIDWORKSRouting中用为偏心变径管,以下项为可选项。您可以在偏心变径管中生成一个轴(Vertical)来控制变径管在线路子装配体中的角度方位。当您插入变径管时,此竖直轴将与3D草图插入点(连接点)处绘制的第一条构造线对齐。如果偏心大小头没有共线,删除末端自动......
  • 2023-06-05 hexo 分页图标不显示,显示的是【<i class="iconfont icon-arrow-left"></i>
    问题描述:如题。注意:我使用的主题为next。解决方案:全局搜索:navclass="pagination"或者找到路径:你的博客\themes\hexo-theme-next\layout\_partials里的【pagination.swig】文件,对其进行修改;修改前:{%ifpage.prevorpage.next%}<navclass="pagination">{{p......
  • 欧奈儿行业 RPS 排名,一图览全貌 2023-06-05 ,继续跟踪总结
    自动复盘2023-06-05k线图是最好的老师,点击详情图可以看到行业20日RPS的排名,最底下子图是行业rps走势线跟踪板块总结:成交额超过100亿排名靠前,macd柱由绿转红公众hao:醉卧梦星河欧奈尔行业RPS排名天天更新追踪主力行业趋势更容......