• Spring Rce 漏洞分析CVE-2022-22965


    0x01 漏洞介绍

    Spring Framework 是一个开源的轻量级J2EE应用程序开发框架。

    3月31日,VMware发布安全公告,修复了Spring Framework中的远程代码执行漏洞(CVE-2022-22965)。在 JDK 9 及以上版本环境下,可以利用此漏洞在未授权的情况下在目标系统上写入恶意程序从而远程执行任意代码。

    0x02 影响范围

    影响组件:org.springframework:spring-beans

    影响版本:< 5.3.18 和 < 5.2.20.RELEASE 的Spring框架均存在该漏洞

    JDK版本:JDK>=9

    部署方式:war包部署在TOMCAT中

    0x03 漏洞原理

    漏洞爆发之后,在学习大佬的分析之后发现,这个Spring最新0day漏洞其实不是全新的那种新洞,而是CVE-2010-1622这个漏洞的一种绕过情况。

    这个CVE-2010-1622漏洞的原因是Spring参数绑定时,可以注入一个Java pojo对象,这个对象可以是恶意的去注册一些敏感tomcat的属性,最后通过修改Tomcat的配置来执行危险操作。

    所以最新的CVE-2022-22965漏洞就是绕过了这个限制,可以说是Java 9的环境下坑了Spring一把,JDK9中存在可以绕过黑名单禁用的类,导致了这个漏洞,最后利用方式也就和之前一样了。

    下面部分细讲这个问题。

    0x04 Spring参数绑定

    首先就是先理一下Spring中的参数绑定

    简单来说,springmvc中可以自动的去给参数赋值。

    例如我们常见的穿参数的方式就是下面这种

    http://localhost:8080/spring4shell_war/?name=zzz&age=123
    
    • 1

    image-20220407110257145

    参数绑定的实现方式

    @Controller
    public class HelloController {
    
        @GetMapping("/")
        public String index(Person person)
        {
            Person person1 = new Person();
            person1.setName(person.getName());
            person1.setAge(person.getAge());
            return "hello";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这种方式就是直接传参数是一个Person对象,而不是以前的@RequestParam这种获取方式

    public String HelloController( @RequestParam(required=false) String name, @RequestParam ( "age" ) int age) {
    
    • 1

    这种参数绑定的实现方式方法就是如果用户传入name=zzz,则Spring框架会自动调用person.setName(‘zzz’)进行赋值。 如果提交的参数中出现了Person类的一个public字段或方法,就自动用户提交请求给他赋值。

    image-20220407111733457

    0x05 调试过程

    1)用户请求经过tomcat处理后,调用Spring总入口DispatcherServlet.java的doDispath方法来路由处理http请求:

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    image-20220407153554154

    方法具体实现数据绑定

    org.springframework.beans.AbstractPropertyAccessor#setPropertyValues(org.springframework.beans.PropertyValues, boolean, boolean)

    image-20220407154547642

    nestedPa = getPropertyAccessorForPropertyPath(propertyName);那么看一下里面是什么

    image-20220407155303997

    调用递归函数getPropertyAccessorForPropertyPath获取参数值,循环查看参数中是否包含"[" “]‘’ ‘’.”

    若存在则按分割赋值给nestedProperty,我这个是没有的所以返回-1了。

    image-20220407163904995

    然后换一个payload会怎么样class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

    这个时候pos就是5了,取出来第一个。后面class

    image-20220407164504628

    BeanWrapperImpl#getCachedIntrospectionResults().getPropertyDescriptor(propertyName)

    这里就是最开始我看到文章中分析的,会在缓存cache里去找我们输入的参数propertyName

    image-20220407165544156

    最终在org.springframework.beans.CachedIntrospectionResults#getPropertyDescriptor

    这里就可以看到都可以获取到什么了。 image-20220407165118281

    补丁的绕过的问题

    红色是原来的补丁,绿色是现在的修复

    image-20220407170706540

    所以原来是黑名单的判断逻辑,beanClass非Class或者属性name非(classLoader|protectionDomain),

    JDK8中没有只能用去class.classLoader调用

    但是最新的CVE-2022-22965 用的class.module.classLoader,这样就就是绕过了这个限制。

    原因是在Java 9以后,Class对象中多了一个Module类的属性,而Module类中也存在getClassLoader()方法,可以获取到一个class.module.classLoader

    这次修补的理解就是:如果其中的属性是ClassLoaderProtectionDomain,就直接continue跳过。

    利用

    这个漏洞的本质利用Java 9中的模块里一些内部对象的属性注入

    我们现在已知道的PAYLOAD就是更改Tomcat将一些全局配置

    就是修改保存在classLoader.resources.context这个context中日志的格式与文件名

    就是下面的这些

    class.module.classLoader.resources.context.parent.pipeline.first.pattern=xxx& 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=
    
    • 1

    最后写在webapps/ROOT这个目录的一个webshell

    0x06 坑点

    还有就是在调试的时候,如果是在idea里面调试部署tomcat,最终测试会找不到webshell。

    这是因为idea是映射,并不在这个目录,所以你访问原版的tomcat里面并没有,其实是在idea的一个目录下。

    image-20220407172208708
    image-20220407172416041

    还有就是每次写完shell会有缓存,如果发现没重复打payload没写成,就重启一下tomcat服务就好了。

    0x06 参考链接

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

    SpringMVC框架任意代码执行漏洞(CVE-2010-1622)分析 - Ruilin (rui0.cn)

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    网络安全(黑客)——2024自学
    Espresso Test 3: Fragment Test
    STM32单片机-BKP和RTC
    Win11怎么安装语音包?Win11语音包安装教程
    基于SkeyeVSS系统实现政府综合性视频监控平台管理解决方案
    Tomcat 启动闪退问题解决方法
    ROS 基础教程
    2022关键之年,国产奶粉「争霸之秋」
    m基于matlab的DQPSK调制解调技术的仿真
    Ladder Side-Tuning:预训练模型的“过墙梯”
  • 原文地址:https://blog.csdn.net/embelfe_segge/article/details/126114159