【漏洞复现】3. Spring4Shell远程代码执行漏洞(CVE-2022-22965)复现与分析
文章目录
1. 预备知识
Spring是一个开源的Java框架,提供了一系列的中间件组件,用于构建企业级应用程序。Spring中间件是Spring框架的核心部分,它们提供了各种功能和服务,简化了企业级应用程序的开发和管理。
- Spring MVC:Spring MVC是Spring框架中的一个Web框架,用于构建基于MVC(Model-View-Controller)模式的Web应用程序。它提供了强大的请求处理机制、灵活的视图解析和表单处理功能,使开发者可以轻松构建可扩展和可维护的Web应用程序。
- Spring Boot:Spring Boot是Spring框架的一个子项目,旨在简化Spring应用程序的配置和部署。它提供了自动配置和约定优于配置的原则,可以快速构建独立运行的、生产级别的Spring应用程序。Spring Boot还集成了许多常用的中间件,如数据库访问、消息队列和安全性等,使开发者可以更加专注于业务逻辑的实现。
- Spring Data:Spring Data是一个用于简化数据访问的框架,它提供了统一的数据访问抽象层,使开发者可以以一种统一的方式访问不同类型的数据存储,如关系型数据库、NoSQL数据库和搜索引擎等。Spring Data提供了丰富的功能,如查询方法的自动生成、分页和排序支持等,大大简化了数据访问层的开发工作。
- Spring Security:Spring Security是一个功能强大的安全框架,用于保护应用程序的安全性。它提供了身份验证、授权、加密和会话管理等安全功能,可以轻松集成到Spring应用程序中。Spring Security还支持多种认证方式,如基于表单的身份验证、LDAP和OAuth等,满足了各种安全需求。
- Spring Cloud:Spring Cloud是用于构建分布式系统的框架,它提供了一组工具和组件,用于实现微服务架构中的常见模式,如服务注册与发现、负载均衡和断路器等。Spring Cloud还集成了其他开源项目,如Netflix Eureka、Ribbon和Hystrix等,为开发者提供了构建可伸缩和高可用的分布式系统的能力。
Spring中间件的优势在于它们的灵活性、可扩展性和易用性。通过使用Spring中间件,开发者可以快速构建可靠和高效的企业级应用程序,并且能够更好地应对日益复杂的业务需求。同时,Spring中间件的广泛社区支持和文档资源也为开
2. 漏洞复现
2.1 漏洞介绍
Spring框架(Framework)是一个开源的轻量级J2EE应用程序开发框架,提供了IOC、AOP及MVC等功能,解决了程序人员在开发中遇到的常见问题,提高了应用程序开发便捷度和软件系统构建效率。2022年3月31日,Spring官方发布安全公告,披露CVE-2022-22965 Spring Framework远程代码执行漏洞。由于Spring框架存在处理流程缺陷,攻击者可在远程条件下,实现对目标主机的后门文件写入和配置修改,继而通过后门文件访问获得目标主机权限。使用Spring框架或衍生框架构建网站等应用,且同时使用JDK版本在9及以上版本的,易受此漏洞攻击影响。阿里云应急响应中心提醒 Spring Framework 用户尽快采取安全措施阻止漏洞攻击。
漏洞名称 | Spring4Shell远程代码执行漏洞 |
---|---|
漏洞编号 | CVE-2022-22965 |
危害等级 | 高危 |
CVSS评分 | 9.8 |
漏洞厂商 | Spring |
受影响版本 | Spring Framework < 5.3.18/Spring Framework < 5.2.20/JDK ≥ 9 |
2.2 原理分析
2.2.1 Spring Framework
Spring Framework是Java最流行的一个框架,基于Spring可以直接调用实现一些简单的业务逻辑即可使用,同时也包含了许多高级的功能,比如面向切面的变成,也可以简单地与其他组件进行集成,比如说使用Spring访问数据库Redis等,Spring都提供了相应的接口。
2.2.2 Spring Boot
但是Spring的配置非常繁琐,因此后来出现了Spring Boot,其内置tomcat并内置默认的XML配置信息,从而方便了用户的使用,下图直观表现关系:
Spring MVC就是其中的一个MVC框架,主要用来开发Web应用和网络接口,但是使用之前需要配置大量的XML文件,比较繁琐,所以出现Spring Boot,其中内置tomcat并且内置默认的XML配置信息,从而方便用户的使用。
2.2.3 原理分析
Spring在进行参数绑定时支持嵌套绑定,使得形如class.module.classLoader这样的参数可以穿越修改AccessLogvlave的属性。漏洞通过请求传入的参数,利用SpringMVC参数绑定机制,控制了Tomcat AccessLogValve的属性,让Tomcat在webapps/ROOT目录输出定制的“访问日志”tomcatwar.jsp,该“访问日志”实际上为一个JSP webshell。
该漏洞发现处原本的需求是设置参数绑定功能,通过请求的参数改变对象的属性,包括对象中的对象的属性,通过获取当前的类,根据设置的属性,比如a.b.c.d=e,查找当前类的geta().getb.getc.getd,调用set(e)的方法进行实现,但是其中存在设计疏漏点,即需求没问题,实现方式也没问题,但是很容易想到是否可以跳出当前类、去设置其他属性。如果存在某个属性可以设置到当前类之外的其他对象的属性,那么可能造成漏洞。为利用漏洞,要寻找的就是这样一种跳出当前类的方法。具体利用流程如下图所示:
2.3 漏洞复现
2.3.1 靶场搭建
使用命令sudo docker pull vulfocus/spring-core-rce-2022-03-09下载vulfocus中的环境:
使用命令docker ps查看容器ID如图箭头标注所示:
随后启动对应docker环境
docker run -d -p 81:8080 -it vulfocus/spring-core-rce-2022-03-29
可以看到打开81端口对应网页,靶场已成功搭建:
2.3.2 脚本利用
下载github上开源的exp文件,使用命令git clone https://github.com/TheGejr/SpringShell.git
可以看到由exp给出漏洞检测结果,并给出url地址供访问:漏洞存在,shell地址为:http://192.168.71.128:81/tomcatwar.jsp?pwd=j&cmd=whoami,访问相应地址发现已经是root权限。
2.3.3 POC分析
该文件exp.py代码如下:
函数Exploit的作用是利用一个漏洞向一个URL发送一个POST请求,然后在服务器上创建一个设立shell文件,可以执行任意命令。函数的参数是url,也就是目标网站的地址。函数的步骤如下:
- 定义一个headers字典,包含一些HTTP头部信息,其中suffix, c1, c2是用来构造shell文件的内容的。
- 定义一个data字符串,包含一些POST数据,其中class.module.classLoader.resources.context.parent.pipeline.first.pattern是用来设置shell文件的内容的,它是一个JSP表达式,判断是否有pwd和cmd参数,如果有,就执行cmd参数的值,并输出结果。其他的POST数据是用来设置shell文件的名字、位置和格式的。
- 使用requests.post方法发送POST请求到url,传入headers和data作为参数,并设置timeout, allow_redirects和verify选项。
- 使用urljoin方法拼接出shell文件的完整地址,命名为shellurl。
- 使用requests.get方法发送GET请求到shellurl,并设置timeout, allow_redirects和verify选项。如果返回状态码是200,说明漏洞存在,并打印出shell地址和示例命令
下载后即可在下载好的文件内打开终端,输入以上访问地址进行检测:python3 exp.py --url http://192.168.71.128:81/。
接下来看主函数,如下图所示:
- 导入argparse模块,这是一个标准库模块,用于解析命令行参数1](https://docs.python.org/3/library/argparse.html)23。
- 创建一个argparse.ArgumentParser对象,可以传入一些描述信息作为参数。
- 使用add_argument方法向解析器添加两个可选参数,–file和–url,分别表示url文件和目标url。可以指定help信息和required选项。
- 使用parse_args方法解析命令行参数,并返回一个argparse.Namespace对象,可以通过属性访问参数的值。
- 根据参数的值判断是否调用Exploit函数,并传入相应的url或文件。
2.3.4 手动构造POC
除了脚本方法外也可以使用手动注入payload的方法,首先构造POC第一步:class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{content}i,调用class对象,通过ClassLoader取resources。context是Tomcat的StandardContext,parent拿到的是StandardEngine,pipeline拿到的是StandardPipeline,最终是给AccessLogValve对象的几个属性的赋值操作。%i 这个语法是从请求的header里面拿content,header的值目的是为了迎合tomcat日志的pattern。
构造POC第二步,日志会按照我们想要的方式,生成.jsp文件:suffix是日志文件的后缀,POC为:class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
传入构造的POC第三步,写入网站根目录:
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
传入构造的POC第四步:prefix修改日志文件的前缀,class.module.classLoader.resources.context.parent.pipeline.first.prefix=ganyu
传入构造的POC第五步,fileDateFormat是日期文件的时间格式,这里设置为空:
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
依次传入payload,就会在tomcat的webapps的Root目录下生成一个jsp文件。
2.4 漏洞修复
2.4.1 WAF规则(临时修复)
增加waf规则建立虚拟补丁,过滤"class.", “Class.”, “.class.”, and “.Class.”,在生产部署前验证测试不会影响正常业务运转
3.4.2 Spring框架控制器建议(临时修复)
使用Spring框架来禁止某些模式,需要重新编译部署项目。
import org.springframework.core.Ordered;
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 BinderControllerAdvice {
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
String[] denylist = new String[]{"class.", "Class.", ".class.", ".Class."};
dataBinder.setDisallowedFields(denylist);
}
}
2.4.3 升级框架,官方已发布最新版本
Spring Framework 5.3.18和5.2.20已经发布,已经发布。Spring Boot 2.5.12已经发布。
更多推荐
所有评论(0)