
[CVE-2021-21972] VMware vSphere Client Unauthorized File Upload to Remote Code Execution (RCE)
[CVE-2021-21972] VMware vSphere Client Unauthorized File Upload to Remote Code Execution (RCE)
The vSphere Web Client (HTML5) is essentially an administrative interface that enables management of a vSphere installation. The vSphere Client provides an administrator with access to the key functions of vSphere without the need to access a vSphere server directly. It allows administrators to create new virtual machines and manage existing ones and their resources. As a cross-platform web application, it can be used on all supported operating systems through the supported versions of different web browsers.
CVE-2021-21972 is an unauthorized file upload vulnerability in vCenter Server that leads to remote code execution on remote server. The issue stems from a lack of authentication in the vRealize Operations vCenter Plugin. It received a critical CVSSv3 score of 9.8 out of 10.0. An unauthenticated, remote attacker could exploit this vulnerability by uploading a specially crafted file to a vulnerable vCenter Server endpoint that is publicly accessible. VMware vCenter Server versions 6.5, 6.7 and 7.0 are affected this vulnerability. Successful exploitation of this vulnerability would result in an attacker gaining unrestricted remote code execution (RCE) privileges in the underlying operating system of the vCenter Server. Despite the fact that this vulnerability stems from the vRealize Operations vCenter Plugin, the VMware advisory confirms that this plugin is included in all default installations of vCenter Server. This means that the vulnerable endpoint is available irrespective of the presence of vRealize Operations.
In original blogpost here, discovery of the vulnerability explained as detailed as possible as well as two separate paths to achieve RCE. For Windows systems, an attacker could upload a specially crafted .jsp file in order to gain NT AUTHORITY\SYSTEM privileges on the underlying operating system. For Linux systems, an attacker would need to generate and upload a public key to the server’s authorized_keys path and then connect to the vulnerable server via SSH in order to gain vsphere-ui user privileges. (if SSH service is running and accessible over network)
vropsplugin-service.jar is a java archive file of vropspluginui plugin and includes some of classes and other related functions and methods. Vulnerable part of the code is illustrated as below. In this code snippet belongs to the ServicesController.class in controller of vropsplugin-service.jar. As you can see in down below code snippet, the uploadOvaFile function is responsible for the endpoint/URL that /ui/vropspluginui/rest/services/uploadova
Full path of the vulnerable class: vropsplugin-service\com\vmware\vropspluginui\mvc\ServicesController.class
@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();
}
As an attacker perspective, the handler for this class is performing the following actions
uploadFile parameter with POST method request (line 2)uploadFile parameter and writing content of this parameter to inputStream variable (line 22)/tmp/unicorn_ova_dir + entry.getName() (line 42 and 47)Proof of Concept: In order to exploit this vulnerability, you can use the following steps
../..//statsreport/uploadedFileName.jspTo verify vulnerability, you can use the following request
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
If the response of above request is similar to down below responses, it means remote host is vulnerable to CVE-2021-21972
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"}
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