盘点JDK下的动态代理在反序列化链中的利用原理
字数 2639 2025-08-22 12:23:35

JDK动态代理在反序列化链中的利用原理分析

一、动态代理基础概念

动态代理是Java提供的一种在运行时动态创建代理类和对象的技术,主要涉及以下核心类:

  1. java.lang.reflect.Proxy:用于创建动态代理类和实例
  2. java.lang.reflect.InvocationHandler:代理实例的调用处理器接口

在反序列化漏洞利用中,动态代理主要被用来:

  • 控制方法调用的行为
  • 拦截特定方法的调用
  • 返回精心构造的对象
  • 实现方法调用的分流处理

二、关键动态代理类分析

1. CompositeInvocationHandlerImpl

特性

  • JDK自带类
  • 能够根据不同的方法所属的类选择不同的InvocationHandler
  • 可以看作InvocationHandler的代理

核心作用

  • 对Method方法调用进行分流处理
  • 维护一个classToInvocationHandler映射表,存储不同类对应的InvocationHandler
  • 提供默认的defaultHandler处理未被特殊代理的类

处理流程

  1. 获取待调用方法所属的类:method.getDeclaringClass()
  2. classToInvocationHandler中查找对应的InvocationHandler
  3. 如果存在特殊代理的InvocationHandler,则将方法调用传递给它的invoke方法
  4. 如果不存在且defaultHandler存在,则交由默认Handler处理

2. AnnotationInvocationHandler

特性

  • JDK自带类
  • 常用于反序列化gadget
  • 可以指定方法返回特定的对象

核心作用

  • 对特定Method方法的返回进行预定义
  • 避免某些方法调用导致的错误(如getCompositeType调用抛异常)

实现原理

  • 通过memberValues属性存储预定义的方法名-返回值映射
  • 在invoke方法中,根据方法名从memberValues中返回预定义的对象

限制

  • 在JDK8u71-b12之后,无法再代理非注解的接口方法
  • 高版本中需要寻找替代方案

3. JdkDynamicAopProxy

来源

  • spring-aop依赖

核心作用

  • 进行方法的反射调用
  • AdvisedSupport.targetSource获取目标对象
  • 通过反射调用目标对象的方法

关键属性

  • advised:保存AdvisedSupport对象
  • advised.targetSource:包含恶意对象(如TemplateImpl)

4. AutowireUtils$ObjectFactoryDelegatingInvocationHandler

来源

  • spring-beans依赖

核心作用

  • 进行方法的反射调用
  • objectFactory.getObject()获取目标对象
  • 通过反射调用目标对象的方法

三、典型利用链分析

1. JSON1链

调用栈

...

利用原理

  1. 在JSONObject中包裹cdsProxy(CompositeData代理对象)
  2. 通过Gadgets.createProxy创建代理对象,使用CompositeInvocationHandlerImpl作为InvocationHandler
  3. 代理多个接口(如CompositeDataTemplateImpl
  4. 反序列化时触发所有代理类中的getter方法

关键处理

  • 对于CompositeData.getCompositeType()调用:
    • 使用Gadgets.createMemoizedInvocationHandler创建特殊InvocationHandler
    • 避免调用抛异常导致利用失败
  • 对于其他类的getter方法:
    • 使用JdkDynamicAopProxy进行反射调用

2. Spring1链

调用栈

...

利用原理

  1. 入口在SerializableTypeWrapper$MethodInvokeTypeProvider.readObject
  2. 创建AnnotationInvocationHandler代理TypeProvider接口
  3. 调用getType方法时返回另一个代理对象(ObjectFactoryDelegatingInvocationHandler
  4. 该代理对象实现了TypeTemplates接口
  5. 反射调用newTransformer时触发命令执行

关键步骤

  1. 第一个AnnotationInvocationHandler
    • 代理TypeProvider接口
    • 控制getType方法返回ObjectFactoryDelegatingInvocationHandler代理对象
  2. ObjectFactoryDelegatingInvocationHandler
    • 代理TypeTemplates接口
    • 通过objectFactory.getObject()获取恶意TemplateImpl对象
  3. 第二个AnnotationInvocationHandler
    • 代理ObjectFactory接口
    • 控制getObject方法返回恶意TemplateImpl对象

四、高版本绕过技术

在JDK8u71-b12之后,AnnotationInvocationHandler无法代理非注解接口,需要替代方案:

  1. 使用JdkDynamicAopProxy代理CompositeData接口的子类
  2. 选择JDK自带的CompositeData实现类:
    • javax.management.openmbean.CompositeDataSupport
    • 要求实现Serializable接口

五、防御建议

  1. 升级JDK到最新版本
  2. 对反序列化操作进行严格限制
  3. 使用白名单机制控制可反序列化的类
  4. 对动态代理的使用进行监控和审计
  5. 避免使用不安全的JSON处理库

六、总结

动态代理在反序列化利用链中扮演着关键角色,主要通过:

  1. 方法调用的拦截和控制
  2. 特定对象的构造和返回
  3. 调用流程的分发和路由
  4. 反射调用的最终触发

理解这些动态代理类的特性和交互方式,对于分析和防御反序列化漏洞至关重要。

JDK动态代理在反序列化链中的利用原理分析 一、动态代理基础概念 动态代理是Java提供的一种在运行时动态创建代理类和对象的技术,主要涉及以下核心类: java.lang.reflect.Proxy :用于创建动态代理类和实例 java.lang.reflect.InvocationHandler :代理实例的调用处理器接口 在反序列化漏洞利用中,动态代理主要被用来: 控制方法调用的行为 拦截特定方法的调用 返回精心构造的对象 实现方法调用的分流处理 二、关键动态代理类分析 1. CompositeInvocationHandlerImpl 特性 : JDK自带类 能够根据不同的方法所属的类选择不同的InvocationHandler 可以看作InvocationHandler的代理 核心作用 : 对Method方法调用进行分流处理 维护一个 classToInvocationHandler 映射表,存储不同类对应的InvocationHandler 提供默认的 defaultHandler 处理未被特殊代理的类 处理流程 : 获取待调用方法所属的类: method.getDeclaringClass() 从 classToInvocationHandler 中查找对应的InvocationHandler 如果存在特殊代理的InvocationHandler,则将方法调用传递给它的invoke方法 如果不存在且 defaultHandler 存在,则交由默认Handler处理 2. AnnotationInvocationHandler 特性 : JDK自带类 常用于反序列化gadget 可以指定方法返回特定的对象 核心作用 : 对特定Method方法的返回进行预定义 避免某些方法调用导致的错误(如 getCompositeType 调用抛异常) 实现原理 : 通过 memberValues 属性存储预定义的方法名-返回值映射 在invoke方法中,根据方法名从 memberValues 中返回预定义的对象 限制 : 在JDK8u71-b12之后,无法再代理非注解的接口方法 高版本中需要寻找替代方案 3. JdkDynamicAopProxy 来源 : spring-aop依赖 核心作用 : 进行方法的反射调用 从 AdvisedSupport.targetSource 获取目标对象 通过反射调用目标对象的方法 关键属性 : advised :保存 AdvisedSupport 对象 advised.targetSource :包含恶意对象(如TemplateImpl) 4. AutowireUtils$ObjectFactoryDelegatingInvocationHandler 来源 : spring-beans依赖 核心作用 : 进行方法的反射调用 从 objectFactory.getObject() 获取目标对象 通过反射调用目标对象的方法 三、典型利用链分析 1. JSON1链 调用栈 : 利用原理 : 在JSONObject中包裹 cdsProxy (CompositeData代理对象) 通过 Gadgets.createProxy 创建代理对象,使用 CompositeInvocationHandlerImpl 作为InvocationHandler 代理多个接口(如 CompositeData 和 TemplateImpl ) 反序列化时触发所有代理类中的getter方法 关键处理 : 对于 CompositeData.getCompositeType() 调用: 使用 Gadgets.createMemoizedInvocationHandler 创建特殊InvocationHandler 避免调用抛异常导致利用失败 对于其他类的getter方法: 使用 JdkDynamicAopProxy 进行反射调用 2. Spring1链 调用栈 : 利用原理 : 入口在 SerializableTypeWrapper$MethodInvokeTypeProvider.readObject 创建 AnnotationInvocationHandler 代理 TypeProvider 接口 调用 getType 方法时返回另一个代理对象( ObjectFactoryDelegatingInvocationHandler ) 该代理对象实现了 Type 和 Templates 接口 反射调用 newTransformer 时触发命令执行 关键步骤 : 第一个 AnnotationInvocationHandler : 代理 TypeProvider 接口 控制 getType 方法返回 ObjectFactoryDelegatingInvocationHandler 代理对象 ObjectFactoryDelegatingInvocationHandler : 代理 Type 和 Templates 接口 通过 objectFactory.getObject() 获取恶意TemplateImpl对象 第二个 AnnotationInvocationHandler : 代理 ObjectFactory 接口 控制 getObject 方法返回恶意TemplateImpl对象 四、高版本绕过技术 在JDK8u71-b12之后, AnnotationInvocationHandler 无法代理非注解接口,需要替代方案: 使用 JdkDynamicAopProxy 代理 CompositeData 接口的子类 选择JDK自带的 CompositeData 实现类: javax.management.openmbean.CompositeDataSupport 要求实现 Serializable 接口 五、防御建议 升级JDK到最新版本 对反序列化操作进行严格限制 使用白名单机制控制可反序列化的类 对动态代理的使用进行监控和审计 避免使用不安全的JSON处理库 六、总结 动态代理在反序列化利用链中扮演着关键角色,主要通过: 方法调用的拦截和控制 特定对象的构造和返回 调用流程的分发和路由 反射调用的最终触发 理解这些动态代理类的特性和交互方式,对于分析和防御反序列化漏洞至关重要。