The Spring Framework is an application framework and inversion of the control container for the Java platform developed by VMware. Detected vulnerability with CVE-2022-22965 affects Spring Core and allows an attacker to send a specially crafted HTTP request to bypass protections in the library’s HTTP request parser, leading to remote code execution. Multiple proof of concepts (POCs) have been published and are being used for active exploitation. The vulnerability is called “Spring4Shell” or “SpringShell”.
The developers of Spring have stated that for successful exploitation to happen, the following conditions have to be met:
- Spring MVC and Spring WebFlux applications running on Java version JDK9+
- The applications are running on Tomcat as a WAR deployment
While the above two conditions are what’s required, the scope of the exploit is more general. This implies that there is a chance for other exploit vectors to be present.
Root Cause Analysis(CVE-2022-22965)
The Spring4Shell is caused by the
getCachedIntrospectionResults method of the Spring framework, wrongly exposing the class object when binding the parameters. The default Spring data binding mechanism allows developers to bind HTTP request details to application-specific objects. Back in 2010, CVE-2010-1622 was discovered and it allowed the class loader to modify the search path of the system’s class loader and cause the program to invoke remote Java code. This was patched by the developers by introducing a blocklist to exclude two methods. But later on, with the release of a new feature in JDK version 9, this blocklist could be bypassed, leading to Spring4Shell exploit.
Technical Details and Exploit
In the actively exploited POC following properties are sent in an HTTP POST to construct the filename on the local filesystem:
class.module.classLoader.resources.context.parent.pipeline.first.pattern property is used to specify what template name can be passed in the next step to specify the Object that will be written to the file and executed.
The next step of the attack is for the attacker to send the template name as an HTTP Header that then includes the Java code to be executed.
Details regarding the below URL Encoded String:
request.getParameter(%22cmd%22)– The URL parameter is used by the web shell to get commands from the attacker machine and execute it.
- suffix and c2(some POCs use prefix) headers are used with the web shell contents to make them executable in the Tomcat environment.
first.prefix=tomcatwar– This is the name of the web shell that will be deployed.
first.suffix=.jsp– File extension for the web shell. JSP is used as these file types can be executed in the Tomcat environment.
directory=webapps/ROOT– Directory to be created where web shell will be written under tomcat directory.
NOTE: The prefix and suffix values in the URL encoded string and those in the header are not to be treated as the same.
Once the class is loaded into the server, the ‘cmd’ parameter can be passed to run the remote commands.
Spring Framework versions 5.3.0 to 5.3.17 and versions 5.2.0 to 5.2.19
A malicious user could exploit this Spring4Shell vulnerability to gain unauthorized access to the server, steal user data, and cause undesirable side effects on the vulnerable machine.
The Spring Developers have released the patch for this vulnerability in versions 5.2.20+ and 5.3.18+. It is recommended that all users upgrade to the latest applicable patched versions ASAP. For users who cannot upgrade their Spring framework, the developers have suggested the following workarounds:
- Upgrading Tomcat – Provides adequate protection, but is only a temporary fix until users upgrade their Spring Frameworks.
- Downgrading to Java 8 – Internal research has shown that this mitigation provides no guaranteed results. If users opt for this, it is suggested to check for the vulnerability once Java 8 is up and running.
- Set disallowed Fields – Set
WebDataBinderglobally. This works generally, but as a centrally applied workaround fix, may leave some loopholes, in particular, if a controller sets
disallowedFieldslocally through its own
@InitBindermethod, which overrides the global setting.
- Set disallowed Fields – Set