Hessian、Spring、Groovy、Rhino反序列化浅析
字数 2264 2025-08-23 18:31:24

Hessian、Spring、Groovy、Rhino反序列化漏洞分析与利用

1. Hessian反序列化漏洞

1.1 Hessian协议概述

Hessian是一种用于远程调用的二进制协议,具有以下特点:

  • 广泛用于构建分布式系统中的跨平台通信
  • 特别适用于Java语言,基于RPC协议
  • 可以将Java对象序列化为二进制数据并通过网络传输
  • 使用二进制格式,比XML或JSON等文本协议更高效

1.2 Hessian反序列化机制

Hessian基于Field机制进行反序列化,直接对Field进行赋值,而不是基于Bean机制调用getter/setter方法。

反序列化流程分析:

  1. HessianInput#readObject()中通过Tag决定操作,序列化处理成Map形式,第一个code总是'M'(77)
  2. SerializerFactory#readMap获取反序列化器
  3. getDeserializer方法从缓存或_staticTypeMap获取反序列化器
  4. 通过sun.misc.Unsafe#allocateInstance初始化空对象
  5. _fieldMap中获取对应Deserializer进行值恢复

1.3 利用条件

  • 起始方法只能为hashCode/equals/compareTo
  • 利用链中成员变量不能为transient修饰
  • 不依赖类中readObject逻辑,也不依赖getter/setter逻辑

1.4 利用链示例

1.4.1 TemplatesImpl利用链

// 调用链
hessianinput.readObject()-> hashmap.put()-> EqualsBean.hashcode()-> ToStringBean.toString()-> 
SignedObject.getObject()-> hashmap.readObject()-> 后续利用链

1.4.2 JdbcRowSetImpl利用链

同样可以利用JNDI注入实现RCE。

1.5 特殊特性

Hessian支持反序列化任意类,无需实现Serializable接口,只需设置:

serializerFactory.setAllowNonSerializable(true);

2. Spring反序列化漏洞

2.1 Spring1反序列化链

2.1.1 关键类分析

  1. AnnotationInvocationHandler:

    • invoke()方法从memberValues中取值
    • 可通过动态代理控制返回值
  2. SerializableTypeWrapper$MethodInvokeTypeProvider:

    • readObject()中存在反射调用入口
    • 通过反射调用this.provider.getType().getClass()的方法
  3. ObjectFactoryDelegatingInvocationHandler:

    • invoke()方法从objectFactory调用getObject()
    • 通过method.invoke调用类中的方法

2.1.2 完整利用链

SerializableTypeWrapper$MethodInvokeTypeProvider.readObject()
SerializableTypeWrapper.TypeProvider(Proxy).getType()
AnnotationInvocationHandler.invoke()
ReflectionUtils.invokeMethod()
Templates(Proxy).newTransformer()
AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke()
ObjectFactory(Proxy).getObject()
TemplatesImpl.newTransformer()

2.2 Spring2反序列化链

2.2.1 关键类分析

  1. JdkDynamicAopProxy:

    • 继承InvocationHandler接口
    • invoke()方法从AdvisedSupport获取TargetSource
    • 最终调用AopUtils.invokeJoinpointUsingReflection()
  2. AopUtils:

    • invokeJoinpointUsingReflection()直接调用method.invoke()

2.2.2 完整利用链

SerializableTypeWrapper$MethodInvokeTypeProvider.readObject()
SerializableTypeWrapper.TypeProvider(Proxy).getType()
AnnotationInvocationHandler.invoke()
ReflectionUtils.invokeMethod()
Templates(Proxy).newTransformer()
JdkDynamicAopProxy.invoke()
AopUtils.invokeJoinpointUsingReflection()
TemplatesImpl.newTransformer()

3. Groovy反序列化漏洞

3.1 Groovy特性

Groovy是一种基于Java的动态语言,提供了execute()方法可直接执行命令:

"whoami".execute()

3.2 关键类分析

  1. MethodClosure:

    • doCall()方法可触发InvokerHelper.invokeMethod()
    • 构造函数接收Object对象和Method名
  2. ConvertedClosure:

    • 继承ConversionHandlerInvocationHandler
    • invokeCustom()方法触发call()方法

3.3 利用链

AnnotationInvocationHandler.readObject()
Map.entrySet() (Proxy)
ConversionHandler.invoke()
ConvertedClosure.invokeCustom()
MethodClosure.call()
ProcessGroovyMethods.execute()

4. Rhino反序列化漏洞

4.1 Rhino概述

Mozilla Rhino是基于Java的JavaScript引擎,可在JVM上运行JavaScript代码。

4.2 关键类分析

  1. NativeError:

    • toString()触发js_toString()getString()
  2. ScriptableObject:

    • getProperty()getImpl()方法链
    • 最终通过MemberBox.invoke()反射调用
  3. NativeJavaMethod:

    • call()方法查找并调用MemberBox数组
  4. NativeJavaObject:

    • unwrap()方法返回javaObject
    • 自定义read/writeObject()保存javaObject

4.3 利用链

BadAttributeValueExpException.readObject()
NativeError.toString()
ScriptableObject.getProperty()
ScriptableObject.getImpl()
NativeJavaMethod.call()
NativeJavaObject.unwrap()
MemberBox.invoke()
TemplatesImpl.newTransformer()

5. 防御措施

  1. 升级相关组件到最新安全版本
  2. 使用白名单机制限制反序列化的类
  3. 对输入数据进行严格验证和过滤
  4. 使用安全的序列化替代方案,如JSON
  5. 启用Java安全管理器限制权限

6. 总结

本文详细分析了Hessian、Spring、Groovy和Rhino四种反序列化漏洞的利用原理和技术细节,包括:

  1. Hessian的Field机制反序列化特性
  2. Spring框架中复杂的动态代理利用链
  3. Groovy语言特有的命令执行特性
  4. Rhino引擎中JavaScript与Java的交互机制

理解这些漏洞的利用原理有助于开发人员更好地防范反序列化攻击,构建更安全的应用程序。

Hessian、Spring、Groovy、Rhino反序列化漏洞分析与利用 1. Hessian反序列化漏洞 1.1 Hessian协议概述 Hessian是一种用于远程调用的二进制协议,具有以下特点: 广泛用于构建分布式系统中的跨平台通信 特别适用于Java语言,基于RPC协议 可以将Java对象序列化为二进制数据并通过网络传输 使用二进制格式,比XML或JSON等文本协议更高效 1.2 Hessian反序列化机制 Hessian基于Field机制进行反序列化,直接对Field进行赋值,而不是基于Bean机制调用getter/setter方法。 反序列化流程分析: HessianInput#readObject() 中通过Tag决定操作,序列化处理成Map形式,第一个code总是'M'(77) SerializerFactory#readMap 获取反序列化器 getDeserializer 方法从缓存或 _staticTypeMap 获取反序列化器 通过 sun.misc.Unsafe#allocateInstance 初始化空对象 从 _fieldMap 中获取对应 Deserializer 进行值恢复 1.3 利用条件 起始方法只能为 hashCode/equals/compareTo 利用链中成员变量不能为 transient 修饰 不依赖类中 readObject 逻辑,也不依赖getter/setter逻辑 1.4 利用链示例 1.4.1 TemplatesImpl利用链 1.4.2 JdbcRowSetImpl利用链 同样可以利用JNDI注入实现RCE。 1.5 特殊特性 Hessian支持反序列化任意类,无需实现 Serializable 接口,只需设置: 2. Spring反序列化漏洞 2.1 Spring1反序列化链 2.1.1 关键类分析 AnnotationInvocationHandler : invoke() 方法从 memberValues 中取值 可通过动态代理控制返回值 SerializableTypeWrapper$MethodInvokeTypeProvider : readObject() 中存在反射调用入口 通过反射调用 this.provider.getType().getClass() 的方法 ObjectFactoryDelegatingInvocationHandler : invoke() 方法从 objectFactory 调用 getObject() 通过 method.invoke 调用类中的方法 2.1.2 完整利用链 2.2 Spring2反序列化链 2.2.1 关键类分析 JdkDynamicAopProxy : 继承 InvocationHandler 接口 invoke() 方法从 AdvisedSupport 获取 TargetSource 最终调用 AopUtils.invokeJoinpointUsingReflection() AopUtils : invokeJoinpointUsingReflection() 直接调用 method.invoke() 2.2.2 完整利用链 3. Groovy反序列化漏洞 3.1 Groovy特性 Groovy是一种基于Java的动态语言,提供了 execute() 方法可直接执行命令: 3.2 关键类分析 MethodClosure : doCall() 方法可触发 InvokerHelper.invokeMethod() 构造函数接收Object对象和Method名 ConvertedClosure : 继承 ConversionHandler 和 InvocationHandler invokeCustom() 方法触发 call() 方法 3.3 利用链 4. Rhino反序列化漏洞 4.1 Rhino概述 Mozilla Rhino是基于Java的JavaScript引擎,可在JVM上运行JavaScript代码。 4.2 关键类分析 NativeError : toString() 触发 js_toString() 和 getString() ScriptableObject : getProperty() 和 getImpl() 方法链 最终通过 MemberBox.invoke() 反射调用 NativeJavaMethod : call() 方法查找并调用 MemberBox 数组 NativeJavaObject : unwrap() 方法返回 javaObject 自定义 read/writeObject() 保存 javaObject 4.3 利用链 5. 防御措施 升级相关组件到最新安全版本 使用白名单机制限制反序列化的类 对输入数据进行严格验证和过滤 使用安全的序列化替代方案,如JSON 启用Java安全管理器限制权限 6. 总结 本文详细分析了Hessian、Spring、Groovy和Rhino四种反序列化漏洞的利用原理和技术细节,包括: Hessian的Field机制反序列化特性 Spring框架中复杂的动态代理利用链 Groovy语言特有的命令执行特性 Rhino引擎中JavaScript与Java的交互机制 理解这些漏洞的利用原理有助于开发人员更好地防范反序列化攻击,构建更安全的应用程序。