In October 2023, a critical vulnerability named CVE-2023-46604 was disclosed in the Java OpenWire protocol, used by Apache ActiveMQ and its clients. This flaw allows remote attackers to execute arbitrary code on brokers or clients just by sending malicious data over the network. If you're running ActiveMQ—especially any version before 5.15.16, 5.16.7, 5.17.6, or 5.18.3—you're at risk.

Let’s break down what this means, how it works, and what you can do to fix it.

What is the OpenWire Protocol Marshaller?

OpenWire is a wire protocol used by Apache ActiveMQ for communication between brokers and clients. Its "marshaller" is the part that converts Java objects to binary for network transit, then turns that binary back into Java objects when received.

What Went Wrong: The Vulnerability

CVE-2023-46604 happens because the marshaller doesn't strictly control what class types are being deserialized. If a remote attacker can send crafted binary data to your ActiveMQ broker or client, the attacker can "trick" it into deserializing a dangerous class from the application's own classpath. Often (but not always), this ends up being a class with side effects—like one that can execute shell commands on your server.

Key point: The attacker does not need to authenticate. Just network access to the server or client is enough.

Exploit Details (with Example Code)

Attackers can craft a malicious payload using the OpenWire protocol so that the broker or client side tries to deserialize a user-controlled class. If there is a gadget class on the classpath (think: a class that runs a command when constructed or serialized), they can trigger code execution. This attack is very similar to past Java deserialization exploits.

Example Attack (Python Proof-of-Concept)

Researchers found example code using Python and the marshalsec tool to generate the payload.

Here’s a *simplified* example of how this kind of attack works

import socket

# Replace with the broker's IP and port
BROKER_IP = '10.10.10.10'
BROKER_PORT = 61616

# Malicious serialized OpenWire payload (use ysoserial/marshalsec to generate)
payload = b'<BINARY MALICIOUS PAYLOAD>'

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((BROKER_IP, BROKER_PORT))
    s.sendall(payload)
    print("Payload sent!")

Payload generation is commonly done with marshalsec or ysoserial targeting namespaces known to allow code execution, like org.apache.commons.collections.

In Real Life: Attack Scenarios

1. Direct to Broker: Attacker sends crafted OpenWire traffic directly to a broker. The broker loads (instantiates) the malicious class and executes commands (like spawning a reverse shell).
2. Targeting a Client: If a client uses OpenWire to connect to a rogue (attacker-controlled) broker, the client is tricked into deserializing a bad class and running commands on the client machine.

Any Java-serialized class present on disk can be targeted if the protocol isn’t locked down.

Mitigation and Fix

Don't wait to patch!

References and Further Reading

- Apache ActiveMQ Security Advisory: CVE-2023-46604
- NVD CVE-2023-46604 Entry
- marshalsec GitHub (payload generator)
- Rapid7 Analysis & Proof-of-Concept

Final Advice

CVE-2023-46604 is a serious, remote shell access bug. If you run ActiveMQ or use OpenWire in Java, you MUST patch all your systems—clients too!

Be sure to limit network exposure of all message brokers. Regularly check for updates and subscribe to vendor security advisories.

Timeline

Published on: 10/27/2023 15:15:14 UTC
Last modified on: 11/20/2023 22:15:07 UTC