Springboot devtools <=2.6.4 rce

Devtools is a hot deployment tool of spring boot. It can automatically load projects without manually restarting the spring boot application. During the development process, if we modify some java files, we may need to restart the project to view the modified results. If spring boot devtools is used, devtools will automatically restart the server for you when there are file changes in the classpath (Baidu.com’s introduction, in fact, you can customize the path according to your own situation).

First, look at the configuration information of devtools:

image

Because all automatic configurations of springboot are performed by xxxautoconfiguration, it is known that:

jetbrains://idea/navigate/reference?project=spring-boot-demo&path=~\.m2\repository\org\springframework\boot\spring-boot-devtools\2.6.4\spring-boot-devtools-2.6.4.jar!\org\springframework\boot\devtools\autoconfigure\RemoteDevToolsAutoConfiguration.class

is the automatic configuration class of devtools

This is for spring devtools. remote. Implementation of secret configuration.

View the process, first pass the values of secretheadername and ‘secret’ into the httpheaderaccessmanager class for processing:

image

Follow up httpheaderaccessmanager class:

image

In this class, a parameter HeaderName in the request header will be obtained for comparison. If the value of HeaderName is inconsistent with expectedsecret, 403 will be reported:

image

image

return RemoteDevToolsAutoConfiguration

Follow up DevToolsPropertiesclass see SecretHeaderName、Secret:

image

jetbrains://idea/navigate/reference?project=spring-boot-demo&path=~\.m2\repository\org\springframework\boot\spring-boot-devtools\2.6.4\spring-boot-devtools-2.6.4.jar!\org\springframework\boot\devtools\autoconfigure\DevToolsProperties.class

image

Follow up RemoteDevToolsProperties,in the getsecretheadername method,x-auth-token is returned, that is, the HTTP header has an x-auth-token header.

image

the x-auth-token value

getsecret is obtained from the configuration file:

image

Returning to remotedevtoolsaccessmanager, the httpheaderaccessmanager object returns the verification result of x-auth-token: Secret.

Continue to see vulnerabilities trigger key locations.

This part belongs to the remoterestartconfiguration static class, which is the devtools configuration implementation class:

image

View the remoterestarthandlermapper method

First, see to properties.getRemote(),follow up the devtoolsproperties class:

jetbrains://idea/navigate/reference?project=spring-boot-demo&path=~\.m2\repository\org\springframework\boot\spring-boot-devtools\2.6.4\spring-boot-devtools-2.6.4.jar!\org\springframework\boot\devtools\autoconfigure\DevToolsProperties.class

image

The getremote method returns the remotedevtoolsproperties object

image

Follow up remotedevtoolsproperties object
This class returns various corresponding property values:

image

The getcontextpath method returns the URL in the remoterestarthandlermapper method:

image

The URL is /~~ spring-boot!~/ restart.
Then continue to watch httprestartserverhandler

image

Follow up HttpRestartServer class:

image

In this class’s Handle method, obtain the request encapsulated as ObjectInputStream object, and then use ObjectInputStream’s ReadObject method,since the request is controllable, the vulnerability is formed.

Verify it:

 

Construct the request based on the analysis:

Text
1
2
3
POST /.~~spring-boot!~/restart 
HOST: 127.0.0.1
X-AUTH-TOKEN: The value here is the user-defined password in the configuration file. According to the use tutorial of devtools, it is found that most of them are mysecret and secret(default password, weak password). If you don't know the password, you can use script to guess the password. According to the previous analysis, if the password is wrong, it will report 403. If the password is right, you will report an error when entering deserialization, so it will be prompted 500. You can guess the password according to these two mistakes.

Dependency:

Text
1
2
3
4
5
6
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

idea will import 2.6.4

image

Enable remote hot deployment in normal configuration
application.yml configuration:

Text
1
2
3
4
5
6
7
8
9
spring:
devtools:
restart:
enabled: false #Set hot deployment
additional-paths: src/main/java #Restart directory
exclude: WEB-INF/**
remote:
secret: mysecret

pom.xml configuration::

Text
1
2
3
4
5
6
7
8
9
 <plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- Set to include devtools when packaging the project. If set to true, devtools -- > will not be enabled after packaging the project-->
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>

There will be a prompt after the project is started

image

Python writes a PoC to send data (Java or burp will prompt “invalid stream header” if it is sent directly. I don’t know why).

Send the serialized malicious data to the target to trigger:

image

I found the vulnerability and contacted the spring, but the spring thought they explained the problem in the document, and suggested that the developer change <excludedevtools> false </excludedevtools> to true before releasing the formal environment, so that the production environment will not enable devtools, so it is not a vulnerability.

But I still think this is a risk. I suggest rewriting resolveclass and setting a deserialized object type of white list to avoid malicious deserialization.


声明:
本文章用于学习交流,严禁用于非法操作,出现后果一切自行承担,阅读此文章表示你已同意本声明。

Disclaimer:
This article is for study and communication. It is strictly forbidden to use it for illegal operations. All consequences shall be borne by yourself. Reading this article means that you have agreed to this statement.