从JDK内省机制&Spring属性注入浅析Spring-beans变量覆盖问题
字数 1257 2025-08-29 08:32:24

Spring Beans 变量覆盖漏洞分析与利用教学文档

漏洞概述

该漏洞本质是变量覆盖漏洞,利用Spring框架的属性注入机制修改Tomcat配置,通过修改日志位置和格式实现恶意JSP文件写入。这是CVE-2010-1622的绕过版本。

影响范围

  • Spring Beans 5.3.0 ~ 5.3.17
  • Spring Beans 5.2.0 ~ 5.2.19
  • JDK 9+
  • 使用参数绑定且参数为非基础数据类型的Apache Tomcat

核心机制分析

JDK内省机制

JavaBean规范

  1. 所有属性为private
  2. 提供默认无参构造方法
  3. 提供setter/getter方法
  4. 方法命名规则:去掉set/get前缀后剩余部分为属性名

内省API

// 获取Bean信息
BeanInfo beanInfo = Introspector.getBeanInfo(Class<?> beanClass);
// 获取属性描述器
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

关键特性

  • 会继承Object类的getClass()方法,导致出现"class"属性
  • 即使没有对应字段,只要有getter方法就会识别为属性

Spring属性注入

参数绑定类型

  1. 基本类型/包装类型
  2. 对象类型(支持多层级)
  3. 数组类型
  4. 集合类型(List/Map需要特殊处理)

嵌套属性注入

beanWrapper.setAutoGrowNestedPaths(true);
beanWrapper.setPropertyValue("director.name", "director");
beanWrapper.setPropertyValue("employees[0].name", "t4r");

关键类

  1. BeanWrapperImpl:提供JavaBean内省功能
  2. AbstractNestablePropertyAccessor:处理嵌套属性注入
  3. PropertyHandler:封装PropertyDescriptor,提供底层操作

漏洞原理分析

利用链构造

class.module.classLoader.resources.context.parent.pipeline.first.pattern
  1. 通过class属性访问Object.getClass()
  2. JDK9+通过Module访问ClassLoader
  3. 最终操作Tomcat的AccessLogValve

关键绕过点

  1. 传统class.classLoader被拦截
  2. JDK9+新增module中间层:
    Class.getModule().getClassLoader()
    

漏洞复现

环境搭建

  1. Spring MVC项目配置
  2. 添加spring-beans 5.3.17依赖
  3. 创建接受对象的Controller

利用步骤

  1. 构造恶意请求修改Tomcat日志配置:

    POST /hello HTTP/1.1
    Host: localhost:8082
    Content-Type: application/x-www-form-urlencoded
    
    class.module.classLoader.resources.context.parent.pipeline.first.pattern=恶意JSP代码
    class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
    class.module.classLoader.resources.context.parent.pipeline.first.directory=web目录
    
  2. 日志配置参数说明:

    • pattern:日志内容格式(可插入JSP代码)
    • suffix:日志文件后缀(设为.jsp)
    • directory:日志存放目录(设为web目录)
    • prefix:日志文件名前缀
    • fileDateFormat:禁用日期后缀
  3. 使用%{prefix}i%{suffix}i引用请求头构造完整JSP

检测方法

POST /hello HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded

class.module.classLoader.resources.context.configFile=http://dnslog.cn

漏洞防御

  1. 升级Spring Beans到安全版本
  2. 限制参数绑定类型
  3. 过滤特殊属性名(如class.*)
  4. 使用@InitBinder限制绑定范围

技术要点总结

  1. 内省机制:JavaBean属性推断方式导致class属性暴露
  2. 嵌套注入:Spring对嵌套属性的递归处理
  3. JDK9特性:module层绕过classLoader限制
  4. Tomcat日志:通过AccessLogValve实现文件写入

参考链接

Spring Beans 变量覆盖漏洞分析与利用教学文档 漏洞概述 该漏洞本质是变量覆盖漏洞,利用Spring框架的属性注入机制修改Tomcat配置,通过修改日志位置和格式实现恶意JSP文件写入。这是CVE-2010-1622的绕过版本。 影响范围 Spring Beans 5.3.0 ~ 5.3.17 Spring Beans 5.2.0 ~ 5.2.19 JDK 9+ 使用参数绑定且参数为非基础数据类型的Apache Tomcat 核心机制分析 JDK内省机制 JavaBean规范 所有属性为private 提供默认无参构造方法 提供setter/getter方法 方法命名规则:去掉set/get前缀后剩余部分为属性名 内省API 关键特性 会继承Object类的getClass()方法,导致出现"class"属性 即使没有对应字段,只要有getter方法就会识别为属性 Spring属性注入 参数绑定类型 基本类型/包装类型 对象类型(支持多层级) 数组类型 集合类型(List/Map需要特殊处理) 嵌套属性注入 关键类 BeanWrapperImpl :提供JavaBean内省功能 AbstractNestablePropertyAccessor :处理嵌套属性注入 PropertyHandler :封装PropertyDescriptor,提供底层操作 漏洞原理分析 利用链构造 通过class属性访问Object.getClass() JDK9+通过Module访问ClassLoader 最终操作Tomcat的AccessLogValve 关键绕过点 传统 class.classLoader 被拦截 JDK9+新增 module 中间层: 漏洞复现 环境搭建 Spring MVC项目配置 添加spring-beans 5.3.17依赖 创建接受对象的Controller 利用步骤 构造恶意请求修改Tomcat日志配置: 日志配置参数说明: pattern :日志内容格式(可插入JSP代码) suffix :日志文件后缀(设为.jsp) directory :日志存放目录(设为web目录) prefix :日志文件名前缀 fileDateFormat :禁用日期后缀 使用 %{prefix}i 和 %{suffix}i 引用请求头构造完整JSP 检测方法 漏洞防御 升级Spring Beans到安全版本 限制参数绑定类型 过滤特殊属性名(如class.* ) 使用 @InitBinder 限制绑定范围 技术要点总结 内省机制 :JavaBean属性推断方式导致class属性暴露 嵌套注入 :Spring对嵌套属性的递归处理 JDK9特性 :module层绕过classLoader限制 Tomcat日志 :通过AccessLogValve实现文件写入 参考链接 CVE-2010-1622分析 Spring官方安全公告 Tomcat AccessLogValve文档