Java序列化和反序列化
字数 2121 2025-08-29 08:31:53

Java序列化与反序列化安全漏洞深度解析

一、序列化与反序列化基础概念

1.1 基本定义

  • 序列化(Serialization): 将对象转换为字节序列的过程
  • 反序列化(Deserialization): 把字节序列恢复为对象的过程

1.2 Java中的API实现

  • ObjectOutputStream: 对象输出流,writeObject(Object obj)方法可对指定对象进行序列化
  • ObjectInputStream: 对象输入流,readObject()方法从输入流读取字节序列并反序列化为对象

1.3 序列化数据特征

  • 数据开头为"AC ED 00 05"(十六进制)
  • 包含包名、类名、变量名称、类型及变量值
  • ObjectStreamConstants类定义:
    • STREAM_MAGIC: 0xaced
    • STREAM_VERSION: 5(JDK 1.5-1.8均为此值)

二、反序列化漏洞原理

2.1 漏洞本质

当Java应用对不可信数据直接进行反序列化处理时,攻击者可构造恶意输入,在反序列化过程中产生非预期对象,可能导致任意代码执行。

2.2 关键组件:Apache Commons Collections

  • 扩展了Java标准库的Collection结构
  • 提供了强大的数据结构类型和集合工具类
  • 广泛应用于各种Java应用开发

2.3 漏洞根源

Commons Collections中对集合操作存在可进行反射调用的方法,且反序列化时未进行校验。

三、关键类分析

3.1 Transformer接口

将对象转换为另一个对象的接口实现类:

  1. InvokerTransformer

    • 通过反射创建新对象实例
    • 关键方法参数可控:方法名、参数类型、参数值
  2. ChainedTransformer

    • 将多个Transformer连接成链
    • 对对象依次通过链中每个Transformer进行转换
  3. ConstantTransformer

    • 将对象转化为常量并返回

3.4 POC构造原理

  1. 构建innerMap键值对并赋值
  2. 利用TransformedMap.decorate()方法对Map的value进行transform
  3. 当value执行完整转换链时完成命令执行

3.5 触发机制

  • 重写readObject()方法的类在反序列化时会被优先调用
  • AnnotationInvocationHandler类的memberValues是Map类型
  • readObject()中对memberValues的每一项调用setValue()

四、WebLogic相关漏洞

4.1 漏洞列表

  • CVE-2015-4852
  • CVE-2016-0638
  • CVE-2016-3510
  • CVE-2017-3248

4.2 T3协议特点

  • Weblogic使用T3协议传输序列化数据
  • 数据包分为6部分,前4字节为总长度
  • 必须先发送T3协议头再发送序列化数据才能触发漏洞

4.3 各漏洞特点

CVE-2015-4852

  • 黑名单过滤:
    org.apache.commons.collections.functors*
    com.sun.org.apache.xalan.internal.xsltc.trax*
    javassist*
    org.codehaus.groovy.runtime.ConvertedClosure
    org.codehaus.groovy.runtime.ConversionHandler
    org.codehaus.groovy.runtime.MethodClosure
    
  • 反序列化点:
    • weblogic.rjvm.InboundMsgAbbrev.class::ServerChannelInputStream
    • weblogic.rjvm.MsgAbbrevInputStream.class
    • weblogic.iiop.Utils.class

CVE-2016-0638

  • 将反序列化对象封装进weblogic.corba.utils.MarshalledObject
  • 不在黑名单中,可正常反序列化
  • 反序列化时再次反序列化封装对象,绕过黑名单

CVE-2017-3248

  • 利用黑名单外的反序列化类
  • 通过JRMP协议(Java远程消息交换协议)执行任意payload

五、漏洞利用方法

5.1 利用步骤

  1. 找到接受外部输入的序列化对象接收点
  2. 确认应用Class Path包含漏洞组件(如Commons Collections)
  3. 使用ysoserial生成payload
  4. 通过对象注入方式触发反序列化

5.2 关键点

  • 用恶意序列化数据替换正常数据
  • 利用反射调用Runtime.getRuntime().exec()

5.3 JRMP利用

  • 使用JRMPListener.java payload
  • 序列化RemoteObjectInvocationHandler
  • 使用UnicastRef对象建立TCP连接获取RMI registry
  • 通过JRMP协议实现未授权远程代码执行

六、防御措施

  1. 升级受影响组件版本
  2. 实施严格的反序列化白名单机制
  3. 对输入数据进行严格验证
  4. 使用安全框架如SerialKiller
  5. 在反序列化前进行签名验证

七、检测与验证

7.1 检测方法

  1. 检查应用是否使用受影响组件
  2. 查找反序列化入口点
  3. 尝试发送测试payload观察响应

7.2 验证POC示例

# 示例检测代码框架
import socket
import time

def t3handshake(sock, server_addr):
    # T3协议握手实现
    pass

def buildT3RequestObject(sock, port):
    # 构建T3请求对象
    pass

def sendEvilObjData(sock, data):
    # 发送恶意序列化对象
    pass

def checkVul(res, server_addr, index):
    # 检查漏洞是否存在
    pass

八、总结

Java反序列化漏洞危害严重,影响范围广,攻击者可利用此漏洞实现远程代码执行。理解其原理和利用方式对安全防护至关重要,建议开发和安全人员深入掌握相关技术细节,采取有效措施防范此类风险。

Java序列化与反序列化安全漏洞深度解析 一、序列化与反序列化基础概念 1.1 基本定义 序列化(Serialization) : 将对象转换为字节序列的过程 反序列化(Deserialization) : 把字节序列恢复为对象的过程 1.2 Java中的API实现 ObjectOutputStream : 对象输出流, writeObject(Object obj) 方法可对指定对象进行序列化 ObjectInputStream : 对象输入流, readObject() 方法从输入流读取字节序列并反序列化为对象 1.3 序列化数据特征 数据开头为"AC ED 00 05"(十六进制) 包含包名、类名、变量名称、类型及变量值 ObjectStreamConstants 类定义: STREAM_MAGIC : 0xaced STREAM_VERSION : 5(JDK 1.5-1.8均为此值) 二、反序列化漏洞原理 2.1 漏洞本质 当Java应用对不可信数据直接进行反序列化处理时,攻击者可构造恶意输入,在反序列化过程中产生非预期对象,可能导致任意代码执行。 2.2 关键组件:Apache Commons Collections 扩展了Java标准库的Collection结构 提供了强大的数据结构类型和集合工具类 广泛应用于各种Java应用开发 2.3 漏洞根源 Commons Collections中对集合操作存在可进行反射调用的方法,且反序列化时未进行校验。 三、关键类分析 3.1 Transformer接口 将对象转换为另一个对象的接口实现类: InvokerTransformer 通过反射创建新对象实例 关键方法参数可控:方法名、参数类型、参数值 ChainedTransformer 将多个Transformer连接成链 对对象依次通过链中每个Transformer进行转换 ConstantTransformer 将对象转化为常量并返回 3.4 POC构造原理 构建 innerMap 键值对并赋值 利用 TransformedMap.decorate() 方法对Map的value进行transform 当value执行完整转换链时完成命令执行 3.5 触发机制 重写 readObject() 方法的类在反序列化时会被优先调用 AnnotationInvocationHandler 类的 memberValues 是Map类型 其 readObject() 中对 memberValues 的每一项调用 setValue() 四、WebLogic相关漏洞 4.1 漏洞列表 CVE-2015-4852 CVE-2016-0638 CVE-2016-3510 CVE-2017-3248 4.2 T3协议特点 Weblogic使用T3协议传输序列化数据 数据包分为6部分,前4字节为总长度 必须先发送T3协议头再发送序列化数据才能触发漏洞 4.3 各漏洞特点 CVE-2015-4852 黑名单过滤: 反序列化点: weblogic.rjvm.InboundMsgAbbrev.class::ServerChannelInputStream weblogic.rjvm.MsgAbbrevInputStream.class weblogic.iiop.Utils.class CVE-2016-0638 将反序列化对象封装进 weblogic.corba.utils.MarshalledObject 不在黑名单中,可正常反序列化 反序列化时再次反序列化封装对象,绕过黑名单 CVE-2017-3248 利用黑名单外的反序列化类 通过JRMP协议(Java远程消息交换协议)执行任意payload 五、漏洞利用方法 5.1 利用步骤 找到接受外部输入的序列化对象接收点 确认应用Class Path包含漏洞组件(如Commons Collections) 使用ysoserial生成payload 通过对象注入方式触发反序列化 5.2 关键点 用恶意序列化数据替换正常数据 利用反射调用 Runtime.getRuntime().exec() 5.3 JRMP利用 使用 JRMPListener.java payload 序列化 RemoteObjectInvocationHandler 使用 UnicastRef 对象建立TCP连接获取RMI registry 通过JRMP协议实现未授权远程代码执行 六、防御措施 升级受影响组件版本 实施严格的反序列化白名单机制 对输入数据进行严格验证 使用安全框架如SerialKiller 在反序列化前进行签名验证 七、检测与验证 7.1 检测方法 检查应用是否使用受影响组件 查找反序列化入口点 尝试发送测试payload观察响应 7.2 验证POC示例 八、总结 Java反序列化漏洞危害严重,影响范围广,攻击者可利用此漏洞实现远程代码执行。理解其原理和利用方式对安全防护至关重要,建议开发和安全人员深入掌握相关技术细节,采取有效措施防范此类风险。