
Writeup de exploração passo a passo para CVE-2017-11610 (Supervisord XML-RPC RCE) com análise de superfície de ataque, descoberta de travessia de namespace e técnicas de pós-exploração em um ambiente de laboratório Docker.
Começando pelo que está em execução no ambiente. Listo todos os containers ativos:``` docker ps-a

**A vítima expõe uma única porta: `9001`**.
A porta 9001 não é um aplicativo web padrão. Consultar o **banco de dados de portas** mostra que essa porta pode estar associada ao **Supervisord** (ETL Service Manager de acordo com a IANA), ao proxy Tor ou a algum outro serviço interno. No entanto, não podemos tirar uma conclusão com base apenas no número da porta.
⇒ Eu faço curl diretamente para ler a resposta e também acesso à GUI web para coletar mais informações.```
curl -i http://192.168.3.137:9001/


Análise da resposta:
Server: Medusa/1.12 e o título Supervisor Status→ Confirmado que é o Supervisord, não Tor nem qualquer outro serviço.
REFRESH, RESTART ALL, STOP ALLSupervisord é um gerenciador de processos no Linux. Se a port 9001 estiver exposta à rede sem senha, essa é uma configuração perigosa. Um atacante poderia visualizar serviços, reiniciar/parar processos e, sob certas configurações, explorá-lo para executar comandos se tiver privilégios para modificar ou controlar os programas gerenciados.
Conclusão da Análise: Podemos confirmar que o alvo está expondo a interface de administração do Supervisord à rede na porta 9001. Isso não é um serviço web padrão, mas uma interface de gerenciamento usada para monitorar e controlar processos. A capacidade de acessar essa interface sem autenticação cria o risco de um atacante visualizar o status ou interagir com os serviços gerenciados.
No entanto, devemos distinguir entre a UI visível e o mecanismo de controle subjacente. Botões como REFRESH, RESTART ALL e STOP ALL não processam requisições de forma independente no frontend; em vez disso, eles devem chamar uma interface/backend do Supervisord para recuperar o status ou enviar comandos de controle de processos. Portanto, após confirmar que a Web UI está exposta, o próximo passo da análise é determinar se a interface de controle subjacente existe por trás da Web UI e se exige autenticação.
⇒ Pensamento: É necessário verificar se a interface de controle por trás da Web UI existe e se exige autenticação.

De acordo com a documentação do Supervisor, [inet_http_server] é um servidor HTTP que escuta em um socket TCP. Essa interface não é habilitada por padrão, só deve ser usada em ambientes confiáveis, não suporta criptografia e não possui autenticação padrão, a menos que username/password seja configurado.
A documentação também indica que a porta de [inet_http_server] é usada para receber requisições HTTP/XML-RPC; o supervisorctl usa XML-RPC para se comunicar com o supervisord por meio dessa porta. Isso corresponde à nossa observação no laboratório: o contêiner expõe 0.0.0.0:9001->9001/tcp, a Web UI está acessível sem autenticação, e a versão exibida é o Supervisor 3.3.2.
Assim, após confirmar a Web UI na porta 9001, o próximo passo é inspecionar o endpoint XML-RPC /RPC2. Com base no mecanismo oficial do Supervisord, precisamos verificar estes objetivos:
/RPC2 existe.supervisor.getState ou system.listMethods.Verificar se o endpoint está ativo:```
curl -i -s -X POST -H "Content-Type: text/xml"
-d 'supervisor.getState'
http://192.168.3.137:9001/RPC2

O resultado retorna `HTTP/1.1 200 OK`, não `401 Unauthorized` ou `403 Forbidden`, mostrando que a solicitação foi aceita pelo servidor sem credenciais. A resposta está no formato XML-RPC `<methodResponse>` e contém `statename=RUNNING` e `statecode=1`, provando que o endpoint `/RPC2` está ativo e que o método `supervisor.getState` foi executado com sucesso.
**⇒ Pensando:** A superfície de ataque não está mais limitada à Interface Web, mas expandiu-se para a API XML-RPC, onde os comandos de controle de daemon/processos são manipulados. A partir daqui, a próxima direção de análise é **verificar como o Supervisor** lida com `methodName` em **XML-RPC**, para determinar se o alvo atual **apresenta o comportamento do CVE-2017-11610**, que reside no mecanismo de despacho/consulta (dispatch/lookup) desse método. Precisamos verificar isso para concluir se é **CVE-2017-11610**.
### **Analisando o Processamento de Nomes de Métodos no XML-RPC**
Na etapa anterior, chamamos com sucesso o método `supervisor.getState` por meio do endpoint `/RPC2`. Isso levanta a próxima questão: ao receber um `methodName` baseado em string, como o Supervisord mapeia essa string para a função Python interna?
Em XML-RPC, os métodos normalmente utilizam namespaces, por exemplo:
- `supervisor.getState`
- `supervisor.stopProcess`
- `supervisor.getAllProcessInfo`
Logicamente, o servidor recebe a string `methodName`, divide-a pelo ponto `.`, e procura pelo objeto/função correspondente dentro do handler registrado.
O pseudocódigo pode ser entendido da seguinte forma:```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 padrão como supervisor.getState, esse mecanismo funciona normalmente: o servidor recupera o manipulador supervisor e então chama a função getState. No entanto, o problema central de CVE-2017-11610 é que esse mecanismo de busca não restringe suficientemente os atributos que podem ser acessados. Se um atacante controlar o methodName, ele pode não apenas chamar métodos públicos como getState, mas também percorrer mais fundo nos objetos/módulos internos acessíveis a partir do manipulador supervisor.
Em outras palavras, o ponto . em methodName não é usado apenas para invocar métodos válidos, mas pode ser abusado para percorrer atributos de objetos.
Isso estabelece nosso caminho de exploração:
supervisor → supervisord → options → warnings → linecache → os → system
O conceito é começar pelo manipulador supervisor, seguir os atributos até os objetos internos do daemon e então aproveitar módulos Python pré-importados para alcançar os.system. Se os.system puder ser chamado, o atacante poderá executar comandos do sistema com os privilégios do processo supervisord.
Assim, a cadeia de ataque segue esta lógica: