Spring Rce 漏洞分析CVE-2022-22965

2023-11-03 03:40

本文主要是介绍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

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";}
}

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

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

这种参数绑定的实现方式方法就是如果用户传入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=

最后写在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)

这篇关于Spring Rce 漏洞分析CVE-2022-22965的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/335325

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有