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

1,596 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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技术小栈』分享求职、工作、技术干货。