
CVE-2021-21972 – ᴠᴍᴡᴀʀᴇ ᴄʟɪᴇɴᴛ ɪɴᴊᴇᴄᴛɪᴏɴ ᴅᴇ ᴄᴏᴅᴇ ɴᴏɴ ᴀᴜᴛᴏʀɪséᴇ (ʀᴄᴇ)
[CVE-2021-21972] Client VMware vSphere - Téléchargement de fichier non autorisé menant à une exécution de code à distance (RCE)
Le vSphere Web Client (HTML5) est essentiellement une interface d'administration qui permet la gestion d'une installation vSphere. Le client vSphere offre à un administrateur l'accès aux fonctions clés de vSphere sans avoir besoin d'accéder directement à un serveur vSphere. Il permet aux administrateurs de créer de nouvelles machines virtuelles et de gérer les existantes ainsi que leurs ressources. En tant qu'application web multiplateforme, il peut être utilisé sur tous les systèmes d'exploitation supportés via les versions prises en charge des différents navigateurs web.
CVE-2021-21972 est une vulnérabilité de téléchargement de fichier non autorisé dans vCenter Server qui conduit à une exécution de code à distance sur le serveur distant. Le problème provient d'un manque d'authentification dans le plugin vRealize Operations vCenter. Cette vulnérabilité a reçu un score CVSSv3 critique de 9,8 sur 10,0. Un attaquant distant non authentifié pourrait exploiter cette vulnérabilité en téléchargeant un fichier spécialement conçu vers un point de terminaison vCenter Server vulnérable et accessible publiquement. Les versions 6.5, 6.7 et 7.0 de VMware vCenter Server sont affectées par cette vulnérabilité. L'exploitation réussie de cette vulnérabilité permettrait à un attaquant d'obtenir des privilèges illimités d'exécution de code à distance (RCE) dans le système d'exploitation sous-jacent du vCenter Server. Malgré le fait que cette vulnérabilité provienne du plugin vRealize Operations vCenter, l'avis de VMware confirme que ce plugin est inclus dans toutes les installations par défaut de vCenter Server. Cela signifie que le point de terminaison vulnérable est disponible indépendamment de la présence de vRealize Operations.
Dans l'article de blog original ici, la découverte de la vulnérabilité est expliquée de manière aussi détaillée que possible, ainsi que deux chemins distincts pour atteindre RCE. Pour les systèmes Windows, un attaquant peut télécharger un fichier .jsp spécialement conçu afin d'obtenir les privilèges NT AUTHORITY\SYSTEM sur le système d'exploitation sous-jacent. Pour les systèmes Linux, un attaquant devrait générer et télécharger une clé publique vers le chemin authorized_keys du serveur, puis se connecter au serveur vulnérable via SSH pour obtenir les privilèges de l'utilisateur vsphere-ui. (si le service SSH est en cours d'exécution et accessible via le réseau)
vropsplugin-service.jar est un fichier d'archive Java du plugin vropspluginui et inclut certaines classes ainsi que d'autres fonctions et méthodes associées. La partie vulnérable du code est illustrée ci-dessous. Cet extrait de code appartient à ServicesController.class dans le contrôleur de vropsplugin-service.jar. Comme vous pouvez le voir dans l'extrait de code ci-dessous, la fonction uploadOvaFile est responsable du point de terminaison/URL /ui/vropspluginui/rest/services/uploadova
Chemin complet de la classe vulnérable : 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();
}
Du point de vue d'un attaquant, le gestionnaire de cette classe effectue les actions suivantes
uploadFile avec une requête POST (ligne 2)uploadFile et écriture du contenu de ce paramètre dans la variable inputStream (ligne 22)/tmp/unicorn_ova_dir + entry.getName() (lignes 42 et 47)Preuve de concept : Pour exploiter cette vulnérabilité, vous pouvez suivre les étapes suivantes
../..//statsreport/uploadedFileName.jspPour vérifier la vulnérabilité, vous pouvez utiliser la requête suivante
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
Si la réponse à la requête ci-dessus est similaire aux réponses ci-dessous, cela signifie que l'hôte distant est vulnérable à 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"}