JAVA反序列化学习--shiro反序列化详解
字数 1556 2025-08-10 12:18:01

Shiro反序列化漏洞详解

一、Shiro反序列化漏洞概述

Shiro反序列化漏洞主要分为两种类型:

  1. Shiro-550:影响Shiro版本<1.2.5,由于AES密钥硬编码导致
  2. Shiro-721:影响Shiro版本≥1.2.5,由于Padding Oracle攻击导致

二、漏洞环境搭建

1. 环境准备

  • 下载Shiro 1.2.4源码:

    https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4
    
  • 修改shiro/samples/web/pom.xml

    • 添加或修改jstl依赖版本为1.2
  • 使用IDEA内置Tomcat服务启动

三、Shiro-550漏洞分析

1. 加密流程分析

  1. 登录流程入口AbstractShiroFilter.class第151行

    • 创建Subject对象
    • 处理Cookie信息
  2. 登录成功处理

    • AuthenticatingFilter.class处理登录
    • 登录成功后触发onLoginSuccess
  3. RememberMe处理

    • DefaultSecurityManager.classrememberMeSuccessfulLogin函数
    • RememberMeManager不为空时继续处理
  4. Cookie操作

    • CookieRememberMeManager.class处理rememberMedeleteMe字段
    • 通过addCookieHeader写入Cookie
  5. 序列化与加密

    • convertPrincipalsToBytes将身份信息序列化为字节
    • 使用AES/CBC/PKCS5Padding模式加密
    • 密钥为硬编码的DEFAULT_CIPHER_KEY_BYTESkPH+bIxk5D2deZiIxcaaaA==
  6. Cookie设置

    • 加密后数据Base64编码
    • 加入Cookie中返回给客户端

2. 解密流程分析

  1. 请求处理入口AbstractShiroFilter.class#doFilterInternal

    • 创建Subject对象
    • 解析身份信息
  2. RememberMe处理

    • RememberMeManager获取Cookie值
    • getRememberedSerializedIdentity函数:
      • 获取Cookie中的值
      • Base64解码生成二进制数据
  3. 解密与反序列化

    • convertBytesToPrincipals函数:
      • 获取解密服务
      • 解密二进制数据
      • 调用deserialize(bytes)反序列化
    • deserialize(bytes)中包含readObject(),触发反序列化漏洞

四、漏洞利用原理

Shiro-550利用流程

  1. 攻击者构造恶意序列化数据
  2. 使用硬编码AES密钥加密
  3. Base64编码后放入Cookie的rememberMe字段
  4. 服务端处理流程:
    • 读取Cookie中rememberMe值
    • Base64解码
    • AES解密
    • 反序列化触发漏洞

关键点

  1. 硬编码密钥kPH+bIxk5D2deZiIxcaaaA==
  2. 加密模式:AES/CBC/PKCS5Padding
  3. 触发点readObject()反序列化

五、Shiro-721漏洞简介

Shiro 1.2.5及之后版本:

  • 使用随机密钥替代硬编码密钥
  • 但由于Padding Oracle攻击仍可导致反序列化漏洞

六、防御建议

  1. 升级到最新版本Shiro
  2. 禁用RememberMe功能(如不需要)
  3. 自定义加密密钥(替换默认密钥)
  4. 实施反序列化过滤器

七、总结

Shiro反序列化漏洞的核心在于:

  1. 身份信息的序列化/反序列化机制
  2. 加密密钥的管理问题(硬编码或Padding Oracle)
  3. 反序列化时的安全控制不足

理解这些流程对于安全研究和漏洞防护至关重要。

Shiro反序列化漏洞详解 一、Shiro反序列化漏洞概述 Shiro反序列化漏洞主要分为两种类型: Shiro-550 :影响Shiro版本 <1.2.5,由于AES密钥硬编码导致 Shiro-721 :影响Shiro版本≥1.2.5,由于Padding Oracle攻击导致 二、漏洞环境搭建 1. 环境准备 下载Shiro 1.2.4源码: 修改 shiro/samples/web/pom.xml : 添加或修改jstl依赖版本为1.2 使用IDEA内置Tomcat服务启动 三、Shiro-550漏洞分析 1. 加密流程分析 登录流程入口 : AbstractShiroFilter.class 第151行 创建Subject对象 处理Cookie信息 登录成功处理 : AuthenticatingFilter.class 处理登录 登录成功后触发 onLoginSuccess RememberMe处理 : DefaultSecurityManager.class 的 rememberMeSuccessfulLogin 函数 RememberMeManager 不为空时继续处理 Cookie操作 : CookieRememberMeManager.class 处理 rememberMe 和 deleteMe 字段 通过 addCookieHeader 写入Cookie 序列化与加密 : convertPrincipalsToBytes 将身份信息序列化为字节 使用AES/CBC/PKCS5Padding模式加密 密钥为硬编码的 DEFAULT_CIPHER_KEY_BYTES : kPH+bIxk5D2deZiIxcaaaA== Cookie设置 : 加密后数据Base64编码 加入Cookie中返回给客户端 2. 解密流程分析 请求处理入口 : AbstractShiroFilter.class#doFilterInternal 创建Subject对象 解析身份信息 RememberMe处理 : RememberMeManager 获取Cookie值 getRememberedSerializedIdentity 函数: 获取Cookie中的值 Base64解码生成二进制数据 解密与反序列化 : convertBytesToPrincipals 函数: 获取解密服务 解密二进制数据 调用 deserialize(bytes) 反序列化 deserialize(bytes) 中包含 readObject() ,触发反序列化漏洞 四、漏洞利用原理 Shiro-550利用流程 攻击者构造恶意序列化数据 使用硬编码AES密钥加密 Base64编码后放入Cookie的rememberMe字段 服务端处理流程: 读取Cookie中rememberMe值 Base64解码 AES解密 反序列化触发漏洞 关键点 硬编码密钥 : kPH+bIxk5D2deZiIxcaaaA== 加密模式 :AES/CBC/PKCS5Padding 触发点 : readObject() 反序列化 五、Shiro-721漏洞简介 Shiro 1.2.5及之后版本: 使用随机密钥替代硬编码密钥 但由于Padding Oracle攻击仍可导致反序列化漏洞 六、防御建议 升级到最新版本Shiro 禁用RememberMe功能(如不需要) 自定义加密密钥(替换默认密钥) 实施反序列化过滤器 七、总结 Shiro反序列化漏洞的核心在于: 身份信息的序列化/反序列化机制 加密密钥的管理问题(硬编码或Padding Oracle) 反序列化时的安全控制不足 理解这些流程对于安全研究和漏洞防护至关重要。