Spring4Shell vulnerability details and mitigations
Spring4Shell, also known as SpringShell, is a remote code execution vulnerability (CVSS 9.8) published at the end of March 2022 that impacts Spring Framework. Some Java-based applications that use the Spring library may be vulnerable to the CVE-2022-22965. If an application is vulnerable, an adversary can access internal data, including databases, escalate into the internal networks, or gain access to valuable assets.
Learn Vulnerability Management
Technical details
This flaw occurs when objects or classes are exposed to special conditions. In detail, Spring translates the data of a received request (body and its parameters) into a domain object. The Spring library itself specifically manages parts of the object, including Class, ProtectionDomain, and ClassLoader, but the flaw is then introduced by changes on the Class object in Java 9.
The Spring exposes every time the class member of the target object, for example:
http://localhost:8080/
path/targetapp?classThe Spring4Shell vulnerability occurs because the Spring framework exposes the class object and does not apply the best measures to restrict the access methods, namely the Java 9’s Class.getModule.
Looking at the Tomcat server as an example of exploration, the adversaries can use this flow to change the Tomcat logging directory, as shown below.
POST http://localhost:8080/path/targetapp?class.module.classLoader.resources.context.parent.pipeline.first.directory=
DIRECTORY_OF_CHOICE
By following this approach, the creation of a webshell on the server side is possible using the following commands:
class.module.classLoader.resources.context.parent.pipeline.first.directory=wtpwebapps/ROOT
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shellshell
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= <% out.println(System.getProperty("os.name")); %>
The result of the payload execution is a simple web shell; in this case, it writes the operating system name on the webpage.
Although this may seem like a simple scenario, adversaries can use it in the wild to deploy more sophisticated payloads, including web shells to execute arbitrary payloads, cobalt strike beacons and moving laterally over the internal network.
For instance, criminals are taking advantage of this vulnerability to attack IoT devices and spread the Mirai botnet. More details about this attack wave are here.
Vulnerable applications and affected versions
Some applications and software versions are vulnerable to the Spring4Shell vulnerability. This list should also be used to identify if specific services are vulnerable:
- Spring Framework versions before 5.2.20 and 5.3.18
- Java Development Kit (JDK) 9 or higher
- Spring-webmvc and Spring-webflux dependencies; and
- Use plain old Java objects (POJO) in Spring
Learn Vulnerability Management
How to mitigate the flaw
The best way to fix this vulnerability is to upgrade Spring Framework to 5.3.18 or 5.2.20 versions or higher. If upgrading is not possible, all the non-basic types, such as POJOs, must define what fields the application can use. You can find more information about this topic here.
Apache Tomcat should be upgraded to non-vulnerable versions 10.0.20, 9.0.62, and 8.5.78, as well. Also, using an older version of Java (up to Java 8) must be considered as a rule of thumb within this context.
More granulated conditions should be implemented, including:
- Changing the application code to include disallowedFields containing “class.*“, “Class.*“, “*.class.*“, “*.Class.*“
- Create new rules on WAFs to filter out requests containing the strings: “class.*“, “Class.*“, “*.class.*“, “*.Class.*“
Sources:
- Anatomy of the Spring4Shell, Dynatrace
- New SpringShell zero-day, ContrastSecurity
- CVE-2022-22965, TrendMicro