Cyberwar Bulletin: Iran and Albania

Spring4Shell (CVE-2022-22965): Are you vulnerable to this Zero Day?

Posted on Mar 31, 2022 | Updated on Apr 26, 2022 | By Priya Ravindran

A zero-day RCE vulnerability, CVE-2022-22965, in Java Spring Core library is predicted to be the next Log4j. Are you prepared for the impending Spring4Shell threat?

 

On March 30, 2022, a now-deleted Twitter post detailing the proof-of-concept of a zero-day vulnerability in Java Spring Core, set security wheels rolling across the world. The vulnerability, now tagged as CVE-2022-22965, can be exploited to execute custom code remotely (RCE) by attackers, and has started to see exploitation in the wild. Its vendor, Spring by VMWare, assigns the vulnerability a critical severity.

 

<button>schedule_btn</button> <button>watchSpring4ShellWebcast</button>

Get CSW's Detection Script | Get PoC Exploit Script | Vulnerable Products | IoCs

 

Update: Incidents of CVE-2022-22965 being exploited are slowly materializing day by day. Microsoft detected a low volume of exploitation attempts across its cloud services. The Spring4Shell exploit is leveraged by the Mirai malware to infect vulnerable web servers to launch DDoS attacks. Research shows that one of out six organizations impacted by Spring4Shell are falling victim to threat actors.

 

Spring Core is an open source application framework and an inversion of control container, whose core features can be used by Java applications. The lightweight library is a popular tool of choice as it allows developers to build robust applications on existing infrastructure, quickly and with reduced effort, without having to worry about deployment environments. Over 500 companies reportedly use Spring in their tech stacks.

 

With organizations still reeling under the aftermath of the Apache Log4Shell incident, CSW’s researchers predict that the Spring Core exploit, being dubbed as Spring4Shell, has the potential to be the next Log4j. The Spring4Shell vulnerability affects Spring Core versions <=5.3.17, and our research is underway to understand the true magnitude of the weakness. The vulnerability is believed to be a bypass for CVE-2010-1622, a code injection weakness in Spring framework and Oracle Fusion Middleware.

 

The Spring4Shell is not to be confused with CVE-2022-22963, an RCE in Spring Cloud component, which was also trending recently and is believed to be significantly less harmful.

Spring4Shell is now part of CISA's Known Exploited Vulnerabilities list as well, re-affirming the need for all organizations to patch this highly trending vulnerability on priority.


Detection Script

The issue with exposures of this nature is that it is difficult to comprehend if an organization is vulnerable to the exploit. In order to overcome this, CSW researchers have put together a detection script to identify exposure to the Spring4Shell attacks. 

import argparse
import sys
import requests
import time
from urllib.parse import urljoin

requests.packages.urllib3.disable_warnings()

def VersionCheck(url,debug=False,ver=False):
    if ver:
        print("[<>] Performing Version Detection...!\n")
        try:
            check = requests.head(url,timeout=15,allow_redirects=False, verify=False)
            if check.status_code == 200:
                if "X-Powered-By" in check.headers:
                    if check.headers['X-Powered-By'] == 'ASP.NET':
                        print("Runs on ASP.NET")
                    if 'X-AspNet-Version' in check.headers:
                        print('Version: ' + check.headers['X-AspNet-Version'])
                else:
                    print('Banner Grabbing did not work\n')
            else:
                print('Status code: ' + check.status_code + '\n Exiting!')
                exit(0)
        except:
            if debug:
                print("[-] Some error occured. Detection Failed...!")
                print("Error: " + str(e))
            else:
                print("[-] Some error occured. Detection Failed...! Use --debug to print the error.\n")
            pass

def Detect(url,post=True,get=False,debug=False,json=False):
    proxies = {
        'http':'http://127.0.0.1:8080',
        'https':'http://127.0.0.1:8080'
        }
    if json:

        headers = {
        "Content-Type": "application/json"
        }
        data = '{"class.module.classLoader.URLs[0]"="0"}'
        
        try:
            print("[<>] Testing for Spring4Shell...!\n")
            # if get:
            #     print("Using GET Method")
            #     post = False
            #     response = requests.get(url, headers=headers, data=data,
            #                          timeout=15, allow_redirects=False, verify=False)

            # if response.status_code == 400:
            #     print("[+] Vulnerable!")
            # else:
            #     print("[-] Not likely")
            if post:
                print("Using POST Method")
                response = requests.post(url, headers=headers, data=data,
                                     timeout=15, allow_redirects=False, verify=False, proxies=proxies)

                if response.status_code == 400:
                    print("[+] Vulnerable!")
                else:
                    print("[-] Not likely")
                    
    
        except Exception as e:
            if debug:
                print("[-] Some error occured. Detection Failed...!")
                print("Error: " + str(e))
            else:
                print("[-] Some error occured. Detection Failed...! Use --debug to print the error.\n")
            pass
    else:
        print(json)
        headers = {
        "Content-Type": "application/x-www-form-urlencoded"
        }
        data = "class.module.classLoader.URLs[0]=0"
        try:
            print("[<>] Testing for Spring4Shell...!\n")
            if get:
                print("Using GET Method")
                post = False
                response = requests.get(url, headers=headers, data=data,
                                     timeout=15, allow_redirects=False, verify=False)

                if response.status_code == 400:
                    print("[+] Vulnerable!")
                else:
                    print("[-] Not likely")
            if post:
                print("Using POST Method")
                response = requests.post(url, headers=headers, data=data,
                                     timeout=15, allow_redirects=False, verify=False, proxies=proxies)

                if response.status_code == 400:
                    print("[+] Vulnerable!")
                else:
                    print("[-] Not likely")
                    
    
        except Exception as e:
            if debug:
                print("[-] Some error occured. Detection Failed...!")
                print("Error: " + str(e))
            else:
                print("[-] Some error occured. Detection Failed...! Use --debug to print the error.\n")
            pass


def main():
    parser = argparse.ArgumentParser(description='Spring-Core Rce.')
    parser.add_argument('--file',help='File containing Form Endpoints',required=False)
    parser.add_argument('--url',help='target Form Endpoints',required=True)
    parser.add_argument('--debug',help='Print errors',action="store_true",required=False)
    parser.add_argument('--get',help='Use Get Method',action="store_true",required=False)
    parser.add_argument('--post',help='Use Post Method',action="store_true",required=False)
    parser.add_argument('--ver',help='Perform Version Detection',action="store_true",required=False)
    parser.add_argument('--json',help='Use JSON Object',action="store_true",required=False)
    args = parser.parse_args()

    if len(sys.argv) < 2:
        parser.print_help()
        exit(0)

    if args.url:
        if not(args.get) and not(args.post):
            print('Enter Request Method..!')
            parser.print_help()
            exit(0)           
        else:
            VersionCheck(args.url,args.debug,args.ver)
            Detect(args.url,args.post,args.get,args.debug,args.json)
    if args.file:
        with open (args.file) as f:
            for i in f.readlines():
                i = i.strip()
                Detect(i,args.url,args.post,args.get,args.debug,args.json)
                VersionCheck(i,args.url,args.debug,args.ver)

if __name__ == '__main__':
    main()

Complete details about the script can be obtained here. The enhanced version can handle JSON responses as well.

Organizations now have a way of predicting and addressing the Spring4Shell exposure before the issue gets out of hand.

 

Exploit Script

The CSW research team has also put together a code that can exploit CVE-2022-22965. The script includes a local authenticated check as well!

Check out the script here. Understand the impact an attacker can create, if the vulnerability is exploited.

Here is a video that demonstrates how to execute the exploit code.

 

Vulnerable Products {Updated till Apr 26, 2022}

The Spring4Shell vulnerability affects versions 5.3.17 and below of the Spring Core library, running JDK version 9.0. The vulnerability is further believed to potentially affect products that are directly or indirectly dependent on the Spring Core framework including SpringCore, SpringBoot, Spring MVC and Spring WebFlux.

Java JDK 9.0 was released in 2017, implying that exploits are now surfacing for a weakness that has been around for five years!

An endpoint with DataBinder and specific container configurations are required to exploit the Spring core framework. However, JDK versions  >9 can allow remote attackers to easily gain access into execution pipelines, thereby giving them the ability to rewrite arbitrary fields and change system functionality. 

 

Our ML and AI based predictive vulnerability intelligence has already picked up chatter about Spring4Shell exploitation by Russian and Chinese threat actors. 

The screenshot shows two Russians discussing the vulnerability and exchanging the Chinese Exploit. The post saw 27 downloads within 10 hours of being added.

Our CSW analysts are constantly monitoring the vulnerable products and updating the following list.

 

Table: Spring4Shell Affected Products

Global Exposure

While there is currently no technique to understand the accurate global exposure of Spring4Shell, Shodan reflects 180,636 devices as running Spring Boot, which is a component of the Spring Framework. Based upon the internal structure, configuration and JDK version, these devices could be potentially exposed to Spring4Shell. In China and the United States, over a thousand instances of Spring applications each are connected to the Internet.

Indicators of Compromise {Updated till Apr 26, 2022}

 

Table: Spring4Shell IoCs

Recommendation

While we are yet to ascertain the true capability of the vulnerability, organizations are advised to apply the below mitigation methods to protect their systems from unwelcome attacks.

  • Spring Core users must switch to frameworks 5.3.18+, or 5.2.20+.

  • Users of Spring Boot should upgrade to version 2.6.6 released on March 31, 2022, which includes a fix for CVE-2022-22965.

  • Users of VMware products must upgrade to the latest product versions or workarounds as published in their advisory.

  • Organizations using network protection devices such as WAF must implement rule filtering for strings such as "class.*", "Class.*", "*.class.*", and "*.Class.*" based on the inbound traffic peaks of deployed services.

  • Declare a WebMvcRegistrations bean (Spring MVC) or a WebFluxRegistrations bean (Spring WebFlux) using SpringBoot in order to update the WebDataBinder at the end after all other initialization via the RequestMappingHandlerAdapter.

  • Any leaks can be temporarily repaired by applying two steps simultaneously - 

    • Add  {"class.*","Class.* to the original blacklist ","*.class.*", "*.Class.*"} if dataBinder.setDisallowedFields methods is called in the @InitBinder annotation.
    • All Spring project packages must be recompiled with the addition of the below global class.

 import org.springframework.core.annotation.Order;

           import org.springframework.web.bind.WebDataBinder;

           import org.springframework.web.bind.annotation.ControllerAdvice;

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

           @ControllerAdvice

           @Order(10000)

           public class GlobalControllerAdvice {

                         @InitBinder

                         public void setAllowedFields(WebDataBinder dataBinder) {

                         String[ ]abd=new String[ ]{"class.*", "Class.*", "*.class.*", "*.Class.*"};

                         dataBinder.setDisallowedFields(abd);

                         }

           }


Note: Our team is constantly working on this story and we will update the blog as and when we get new information. Stay tuned!

 

Warding off such threats demands continuous discovery and agile patching driven by priority and trends.

Are you ready for the drill? Connect with us!

Never miss a patch or an update with CSW’s Patch Watch Newsletter. Subscribe now!

csw

Secure your environment from cyber-attacks!

Know How

incognito