快来跟我一起看看这次spring的大漏洞是咋回事

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

漏洞说明

这次spring的漏洞在哪能看到呢?我们直接上spring官网。早blog模块就能看见spring的官方说明了。

iShot2022-04-05 10.18.56

​ 2022年3月30日,Spring框架曝出RCE 0day漏洞,国家信息安全漏洞共享平台(CNVD)已收录了Spring框架远程命令执行漏洞(CNVD-2022-23942),考虑到Spring框架的广泛应用,漏洞被评级为危险。

​ 通过该漏洞可写入webshell以及命令执行。在Spring框架的JDK9版本(及以上版本)中,远程攻击者可在满足特定条件的基础上,通过框架的参数绑定功能获取AccessLogValve对象并诸如恶意字段值,从而触发pipeline机制并写入任意路径下的文件。有的小伙伴不知道这个AccessLogValve对象是啥,其实我们都经常使用。只是没注意:

image-20220405102829278

就在tomcat的server.xml文件中,AccessLogValve就是用来记录容器访问请求的日志处理类。Valve,本意是阀门的意思,AccessLogValve是处理生成访问日志的。其原理就是动态修改这个对象的参数值,之后向容器中写入指定的文件(比如jsp文件)之后再通过写入的文件写入shell脚本命令进行执行。

漏洞条件

image-20220405104013384

  1. Apache Tomcat作为Servlet容器;

  2. 使用JDK9及以上版本的Spring MVC框架;

  3. Spring框架以及衍生的框架spring-beans-*.jar文件或者存在 CachedIntrospectionResults.class

影响范围

jdk

​ JDK 9+

Spring

​ 5.3.0 to 5.3.17

​ 5.2.0 to 5.2.19

​ 更老的版本

尝试复现

我们先尝试一下能否复现,之后在说一下怎么解决:

  1. 看一下环境

image-20220405104622455

image-20220405104738339

  1. 构建一个基于maven的web项目,框架用的spring-mvc,就是常规的工程没有什么特殊的。主要是要注意maven打包为war包。并独立部署外部tomcat中,不要直接在idea中进行部署启动。

image-20220405104855123

主要注意协议对应spring的版本:

				<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.10</version>
        </dependency>
复制代码

定义一个简单的controller

@Controller
public class IndexController {
    @RequestMapping("/test1")
    @ResponseBody
    public String index(User user) {
        user = new User();
        user.setAddress("123");
        return user.getAddress();
    }

}
复制代码
  1. 访问对应的路径,注意加上下面的参数。

image-20220405105338542

说明一下以上的参数的含义

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=文件日期格式(实际构造为空值即可)
复制代码
  1. 结果在root根目录就会生成你要写入的jsp文件。

image-20220405105852739

这个文件在root目录下,当然就可以在外面直接进行访问。之后就可以通过这个文件进行写入各种shell命令。

自查漏洞

  1. 排查是否使用了Spring框架(包括但不限于以下方法)

(1) 排查项目中是否使用了Spring框架指定版本:

可遍历项目文件查找是否包含spring-beans-*.jar

(2) 排查war包中是否存在Spring框架:

检查war包内是否存在spring-beans-*.jar文件,若存在则表示使用spring开发框架;若不存在,则进一步确认是否存在CachedIntrospectionResults.class文件,若存在则表示使用Spring开发框架或衍生框架。

  1. 排查包含Spring框架的项目使用的JDK版本,如果JDK版本>=9则存在风险。

漏洞修复

spring官方建议最好通过升级spring版本来解决,不过也提供了其他集中修复的方法

image-20220405110311888

  1. 将spring版本升级到5.3.18和5.2.20或者以上版本
  2. 升级tomcat
  3. 降低jdk版本
  4. 禁止请求时带指定参数

咱们说一下最后一种方案:需要增加controller拦截

@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public class BinderControllerAdvice {
    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
         String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
         dataBinder.setDisallowedFields(denylist);
    }

}
复制代码

不过spring官方墙裂建议升级spring版本,因为目前版本还可能存在未知的问题。

The preferred response is to update to Spring Framework 5.3.18 and 5.2.20 or greater. If you have done this, then no workarounds are necessary. However, some may be in a position where upgrading is not possible to do quickly. For that reason, we have provided some workarounds below.

漏洞现状

目前spring官方已经对该漏洞修复,现在拉取最新spring的jar包通过上面我的的复现步骤进行试验发现结果:

image-20220405112912657

欢迎关注『IT技术小栈』分享求职、工作、技术干货。

猜你喜欢

转载自juejin.im/post/7082958114240069669