
Guía paso a paso de explotación para CVE-2017-11610 (Supervisord XML-RPC RCE) con análisis de superficie de ataque, descubrimiento de recorrido de espacios de nombres y técnicas de post-explotación en un entorno de laboratorio Docker.
Comenzando con lo que se está ejecutando en el entorno. Listo todos los contenedores activos:``` docker ps-a

**La víctima expone un único puerto: `9001`**.
El puerto 9001 no es una aplicación web estándar. Consultar la **base de datos de puertos** muestra que este puerto podría estar asociado con **Supervisord** (ETL Service Manager según IANA), proxy Tor, o algún otro servicio interno. Sin embargo, no podemos sacar una conclusión basándonos únicamente en el número de puerto.
⇒ Hago curl directamente para leer la respuesta y también accedo a la interfaz web GUI para recopilar más información```
curl -i http://192.168.3.137:9001/


Análisis de la respuesta:
Server: Medusa/1.12 y el título Supervisor Status→ Confirmado que es Supervisord, no Tor ni ningún otro servicio.
REFRESH, RESTART ALL, STOP ALLSupervisord es un administrador de procesos en Linux. Si port 9001 está expuesto a la red sin contraseña, esta es una configuración peligrosa. Un atacante podría ver servicios, reiniciar/detener procesos y, bajo ciertas configuraciones, explotarlo para ejecutar comandos si tiene privilegios para modificar o controlar los programas gestionados.
Conclusión del análisis: Podemos confirmar que el objetivo está exponiendo la interfaz de administración de Supervisord a la red en el puerto 9001. Este no es un servicio web estándar, sino una interfaz de gestión utilizada para monitorear y controlar procesos. La capacidad de acceder a esta interfaz sin autenticación crea un riesgo de que un atacante pueda ver el estado de los servicios gestionados o interactuar con ellos.
Sin embargo, debemos distinguir entre la interfaz de usuario visible y el mecanismo de control subyacente. Botones como REFRESH, RESTART ALL y STOP ALL no procesan solicitudes de forma independiente en el frontend; en su lugar, deben llamar a una interfaz/backend de Supervisord para obtener el estado o enviar comandos de control de procesos. Por lo tanto, después de confirmar que la interfaz web está expuesta, el siguiente paso del análisis es determinar si la interfaz de control subyacente existe detrás de la interfaz web y si requiere autenticación.
⇒ Reflexión: Es necesario comprobar si la interfaz de control detrás de la interfaz web existe y si requiere autenticación.

Según la documentación de Supervisor, [inet_http_server] es un servidor HTTP que escucha en un socket TCP. Esta interfaz no está habilitada por defecto, solo debe usarse en entornos de confianza, no admite cifrado y no tiene autenticación predeterminada a menos que se configure username/password.
La documentación también indica que el puerto de [inet_http_server] se utiliza para recibir solicitudes HTTP/XML-RPC; supervisorctl utiliza XML-RPC para comunicarse con supervisord a través de este puerto. Esto coincide con nuestra observación en el laboratorio: el contenedor expone 0.0.0.0:9001->9001/tcp, la interfaz web es accesible sin autenticación y la versión mostrada es Supervisor 3.3.2.
Por lo tanto, después de confirmar la interfaz web en el puerto 9001, el siguiente paso es inspeccionar el endpoint XML-RPC /RPC2. Basado en el mecanismo oficial de Supervisord, necesitamos verificar estos objetivos:
/RPC2.supervisor.getState o system.listMethods.Verificar si el endpoint está activo:```
curl -i -s -X POST -H "Content-Type: text/xml"
-d 'supervisor.getState'
http://192.168.3.137:9001/RPC2

El resultado devuelve `HTTP/1.1 200 OK`, no `401 Unauthorized` ni `403 Forbidden`, lo que demuestra que la solicitud fue aceptada por el servidor sin credenciales. La respuesta está en el formato XML-RPC `<methodResponse>` y contiene `statename=RUNNING` y `statecode=1`, lo que prueba que el endpoint `/RPC2` está activo y que el método `supervisor.getState` se ejecutó exitosamente.
**⇒ Pensando:** La superficie de ataque ya no se limita a la interfaz web, sino que se ha expandido a la API XML-RPC, donde se manejan comandos de control de demonios/procesos. A partir de aquí, la siguiente dirección de análisis es **verificar cómo maneja Supervisor** `methodName` en **XML-RPC**, para determinar si el objetivo actual **exhibe el comportamiento de CVE-2017-11610**, que reside en el mecanismo de despacho/búsqueda de este método. Necesitamos verificar esto para concluir si se trata de **CVE-2017-11610**.
### **Analizando el procesamiento de nombres de métodos en XML-RPC**
En el paso anterior, llamamos exitosamente al método `supervisor.getState` a través del endpoint `/RPC2`. Esto plantea la siguiente pregunta: cuando se recibe un `methodName` basado en cadenas, ¿cómo asigna Supervisord esa cadena a la función Python interna?
En XML-RPC, los métodos típicamente utilizan espacios de nombres, por ejemplo:
- `supervisor.getState`
- `supervisor.stopProcess`
- `supervisor.getAllProcessInfo`
Lógicamente, el servidor recibe la cadena `methodName`, la divide por el punto `.` y busca el objeto/función correspondiente dentro del manejador registrado.
El pseudocódigo se puede entender de la siguiente manera:```python
# Pseudo-code simulating the dispatch method concept in XML-RPC
def dispatch(method_name, params):
parts = method_name.split(".") # ["supervisor", "getState"]
obj = registered_handlers[parts[0]] # get namespace "supervisor"
for attr in parts[1:]:
obj = getattr(obj, attr) # lookup the next attribute
return obj(*params) # call the final function
Para métodos estándar como supervisor.getState, este mecanismo funciona normalmente: el servidor recupera el supervisor handler, luego llama a la función getState. Sin embargo, el problema central de CVE-2017-11610 es que este mecanismo de búsqueda no restringe suficientemente los atributos a los que se permite acceder. Si un atacante controla el methodName, puede no solo llamar métodos públicos como getState, sino también adentrarse más en los objetos/módulos internos accesibles desde el supervisor handler.
En otras palabras, el punto . en methodName no solo se usa para invocar métodos válidos, sino que puede abusarse para recorrer atributos de objetos.
Esto establece nuestra ruta de explotación:
supervisor → supervisord → options → warnings → linecache → os → system