【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

admin 2022年4月1日00:34:26评论744 views字数 3990阅读13分18秒阅读模式
漏洞信息

Spring是目前全球最受欢迎的Java轻量级开源框架。近日网上爆出Spring核心框架存在RCE漏洞(编号CVE-2022-22965)。在野曝光一段时间后,与近几年流行的高危漏洞命名方式类似(比如ProxyShell、log4jShell等),这个漏洞被称为Spring4Shell。3月31日官方终于发布了漏洞信息,并在新版本v5.3.18和v5.2.20中修复了漏洞。(官方不发补丁我也不敢公开发布文章呀!【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

分析后发现漏洞结合了JDK9及以上版本一个新的属性,成功绕过历史漏洞CVE-2010-1622修复补丁,同时结合Tomcat容器的一些操作属性,可以实现GetShell。当然Weblogic、Jetty等其他Java中间件或应用程序也可能构建出完整利用链,但从目前研究进度来看,漏洞触发需要至少满足以下条件:

  • JDK9或以上版本系列

  • Spring框架或衍生的SpringBoot等框架,版本小于v5.3.18或v5.2.20

  • Spring JavaBean表单参数绑定需要满足一定条件

  • 部署在Tomcat容器中,且日志记录功能开启(默认状态)

环境搭建


新建SpringBoot工程:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


添加实体类`User`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


添加`LoginController`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


生成war包并部署到Tomcat容器中启动。


JavaBean参数绑定分析


JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中。比如在`User`类中再添加一个新类`Test`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


构建如上所示的研究环境,当我们发送如下请求时:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


Spring会将参数用`.`进行分割,前面的参数会自动调用`get***`,最后一个参数会自动调用`set***`,依次执行为:


...User->getTest    Test->setT...


通过上面这种链式的参数解析规则,我们可以`set***`实现修改Spring框架中某些类的属性。通过深入分析,发现当在`Controller`的参数前加上注解之类,比如`@RequestBody`,将不会进行链式解析,这也是限制适用范围的其中一个关键因素。


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

CVE-2010-1622漏洞补丁分析


Spring历史上曾经爆出一个漏洞CVE-2010-1622,原理就是基于上面的JavaBean赋值规则。可以通过提交`class.classLoader`参数,最终执行`getClassLoader`函数获取`ClassLoader`对象,从而可以导致RCE。CVE-2010-1622漏洞补丁位于`CachedIntrospectionResults`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


CVE-2010-1622补丁通过将`classLoader`加入黑名单,导致无法加入解析属性列表。

JDK 9 Module分析


在JDK9及以上版本的JDK中,`java.lang.Class`类中新增了一个私有变量`module`以及函数`getModule`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


进入`Module`类,发现存在`loader`变量和函数`getClassLoader`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


也就是说,通过`Module`可以获取Web Context上下文环境的`ClassLoader`对象。

漏洞分析


通过前面的分析,我们在Tomcat+Spring+JDK11环境中构建研究环境,提交`class.module.classLoader`参数同样可以获取`ClassLoader`对象,调试发现在对BeanInfo赋值过程中,`CachedIntrospectionResults`中会加载`class org.apache.catalina.loader.ParallelWebappClassLoader`对象,可以绕过黑名单检查:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


`ParallelWebappClassLoader`位于Tomcat环境中,获取`ParallelWebappClassLoader`对象后,就可以在此基础上继续寻找可利用链。


可以尝试采用递归方式搜索所有满足`class.module.classLoader`条件的链式调用的属性,加入一个`help.jsp`文件(脚本参考只考虑int、string与boolean这些基本属性)。访问后,可以获取所有潜在可操控的属性,结果如下:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


一共找到300个符合条件的属性可以操控(实际应该更多)。其中的`class.module.classLoader.resources.context.parent.pipeline.first.*`对应于`AccessLogValve`类,主要存放Tomcat日志操作的相关属性:


...class.module.classLoader.resources.context.parent.pipeline.first.directory         //日志保存目录默认为logsclass.module.classLoader.resources.context.parent.pipeline.first.prefix            //日志文件名前缀默认为localhost_access_logclass.module.classLoader.resources.context.parent.pipeline.first.suffix            //日志文件名后缀默认为.txtclass.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat    //日志文件名日期格式默认为.yyyy-mm-dd...


链式调用过程如下:


getClass()->LoginControllergetModule()->ModulegetClassLoader()->ParallelWebappClassLoadergetResources()->StandardRootgetContext()->StandardContextgetParent()->StandardEnginegetPipeline()->PipelinegetFirst()->AccessLogValve...


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


默认情况下日志目录为`logs`,文件名称为`localhost_access_log.yyy-mm-dd.txt`,可以通过构造请求修改日志存储路径、日志文件名称、后缀名属性值。


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


通过修改日志后缀名、文件名称、存放位置等属性,可以写入jsp的webshell。需要注意的是,由于Tomcat稍微新一点的版本出于安全性考虑,无法直接在URL中携带`<`、`{`等特殊字符(否则返回400),我们可以通过`class.module.classLoader.resources.context.parent.pipeline.first.pattern`属性来修改日志记录的格式,从而变向写入webshell。


参考`AbstractAccessLogValve`类使用说明:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

比如,可以将敏感字符放到HTTP请求头中(格式:`%{xxx}i`)。最终实现在`webapps`目录下写入webshell,名称为`localhost_access_log123.jsp`:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

修复方式


在官方没有发布新版本前,可以通过在WAF中加入对`Class.*`等恶意字符串的过滤,或者在Spring应用程序中新建一个全局类实现对恶意字符串的过滤,同时保证这个类被Spring加载到(推荐在Controller所在的包中添加)。完成类添加后,需对项目进行重新编译打包,并重新发布项目:


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 a{ @InitBinder public void setAllowedFields(WebDataBinder dataBinder) { String[] abd = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"}; dataBinder.setDisallowedFields(abd); }}


3月31日,官方在`v5.3.18`和`v5.2.20`版本中修复了漏洞,我们看下关键补丁:


【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析


相比CVE-2010-1622漏洞补丁,新补丁对类型限制更为严格,只允许所有类中的`name`属性合法通过。

小结


漏洞通过`class.module.classLoader`在Web Context上下文环境中找到合适的类属性进行控制从而实现Getshell,理论上漏洞利用链不局限于Tomcat,类似Weblogic、Jetty等其他的Java中间件是否可以利用不好下结论,可以尝试利用`help.jsp`来寻找潜在的利用点,这方面感兴趣的小伙伴可以关注公众号后与本人深入交流【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析



由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,且听安全团队及文章作者不为此承担任何责任。



点关注,不迷路!

【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

原文始发于微信公众号(且听安全):【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月1日00:34:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【最新漏洞预警】CVE-2022-22965 Spring核心框架Spring4Shell远程命令执行漏洞原理与修复方式分析https://cn-sec.com/archives/860681.html

发表评论

匿名网友 填写信息