In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Jonathan Lein and Dusan Stevanovic of the Trend Micro Research Team detail a recently patched remote code execution vulnerability in VMware Aria Operations for Logs (formerly vRealize). This bug was originally submitted to the ZDI program by an anonymous researcher. The issue results from the lack of proper validation of user-supplied data, which can result in deserialization of untrusted data. An attacker can leverage this vulnerability to execute code in the context of root. Similar bugs are reported as being exploited in the wild. The following is a portion of their write-up covering CVE-2023-24941, with a few minimal modifications
An insecure deserialization vulnerability has been reported in VMware Aria Operations for Logs. The vulnerability is due to improper validation of user data in the
InternalClusterController class. A remote unauthenticated attacker could exploit this vulnerability by sending a crafted request to the target server. Successful exploitation could result in arbitrary code execution under the security context of the root user.
VMware Aria Operations for Logs is a log management solution, formerly developed under the name vRealize Log Insight. It can be used to collect log files from remote machines to a central server for storage and processing. Administrators can then access a web-based user interface to create dashboards to visualize the data, create reports, and manage the log data. In addition to the web user interface, the application contains an API to manage the server. The API is accessible on port 9000/TCP through HTTP, or port 9543/TCP via HTTPS.
Aria Operations for Logs can be run as a stand-alone appliance running on a single node, or multiple instances can be configured together to run in a cluster. The APIs impacted by this vulnerability are designed to be used between two instances of Aria Operations for Logs during setup to add the application to the cluster. The API “applyMembership” is used by a server to send a request to join a cluster. If the primary server accepts the request to join the cluster, it will use the API “approveMembership” to send configuration data to the server needed to join the cluster, and the API “setToken” to send a token to apply to the server. The HTTP POST request body for each API call will contain a serialized Java object containing data to pass to the API. Each serialized object will have a different class, depending on which API it was sent to. Java allows the serialization of objects, enabling them to be represented as a compact and portable byte stream. This byte stream can then be transferred via the network and deserialized for use by the corresponding servlet or applet. The following example illustrates how a class is serialized and then later extracted:
All Java Objects that are serializable implement the Serializable interface. This interface enforces the
readObject() methods, which are called when serializing and deserializing objects respectively. These methods can be modified to implement custom behavior during the serialization and deserialization of Java Objects. A serialized Java object begins with the following structure:
An insecure deserialization vulnerability has been reported in VMware Aria Operations for Logs. The vulnerability is due to improper validation of user data in multiple methods in the
InternalClusterController class. Aria Operation for Logs defines three API functions in the file “routes” to assist in the management of clusters: “applyMembership”, “setToken”, and “approveMembership”. When the server receives a call to any of these APIs, a method corresponding to the API name will be called in the class
InternalClusterController. Regardless of the API used, the method will first pass the body of the HTTP request to the method
SerializationUtils.deserialize() as a byte array. The
deserialize() method will then convert the byte array to a
ByteArrayInputStream object and then pass it to
deserialize() again. The method will then convert the user data to an
ObjectInputStream object and call
readObject() on it to deserialize it. After the user data has been deserialized, it will be passed to another method to finish handling the user’s request to the API. However, the serialized objects in the body of requests to the APIs are not validated before they are deserialized. A remote, unauthenticated attacker could exploit this vulnerability by sending an API request containing a crafted serialized object. Such a crafted object can be created with the ysoserial tool using the “CommonsBeanutils1” gadget chain. Successful exploitation could result in arbitrary code execution under the security context of the root user.
Source Code Walkthrough
The following code snippet was taken from VMware Aria Operation for Logs version 8.10.2. Comments have been added by Trend Micro researchers.
From decompiled Java class /usr/lib/loginsight/application/lib/api-play-service_2.13-1.0.jar!controllers/InternalClusterController.class:
From decompiled Java class /usr/lib/loginsight/application/lib/lib/commons-lang3.jar!org/apache/commons/lang3/SerializationUtils.class:
From decompiled Java class /usr/lib/loginsight/application/lib/lib/commons-lang3-3.1.jar!org/apache/commons/lang3/SerializationUtils.class:
To detect an attack exploiting this vulnerability, the detection device must monitor and parse traffic on TCP ports 9000 and 9543. Note that traffic may be encrypted and will need to be decrypted prior to applying this detection guidance. The detection device must parse Java serialized objects in HTTP requests. Java allows the serialization of objects, enabling them to be represented as a compact and portable byte stream. This byte stream can then be transferred via the network and deserialized for use by the corresponding servlet or applet. A serialized Java object begins with the structure shown above.
The detection device must inspect incoming HTTP POST requests to the following URIs:
If found, the detection device must inspect the request body for a Java serialized object. The detection device can inspect the request for the magic bytes “\xac\xed” followed by a 2-byte stream version “\x00\x05” to find a serialized object. The detection device must then inspect the serialized object beginning at offset
0x04 and look for the following bytes, corresponding to
TC_CLASSDESC, and then the length of the Class Name, immediately followed by a Class Name depending on which API endpoint the request to going to:
If the Class Name in the serialized object in the request does not match the expected Class Name, the traffic should be considered suspicious and an attack exploiting this vulnerability is likely underway. Note that it is possible the expected class name for each API could change in future versions of the software.
VMware patched this bug in April with VMSA-2023-0007. To date, we have not seen any evidence this bug is being used in active attacks. However, similar bugs have reportedly been detected in the wild. It is recommended that Aria users test and deploy this update quickly.
Special thanks to Jonathan Lein and Dusan Stevanovic of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.
The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the team on Twitter, Mastodon, LinkedIn, or Instagram for the latest in exploit techniques and security patches.