Apacha-Shiro PaddingOracle 分析
字数 1411 2025-08-26 22:11:45

Apache Shiro Padding Oracle漏洞分析与利用教学文档

一、漏洞背景

Apache Shiro是一个功能强大且易用的Java安全框架,提供认证、授权、加密和会话管理等功能。在Shiro的RememberMe功能实现中存在Padding Oracle漏洞(CVE-2019-12422,SHIRO-721),允许攻击者在特定条件下通过Padding Oracle攻击获取加密密钥,进而实现反序列化RCE。

二、环境搭建

  1. 获取漏洞版本代码:
git clone https://github.com/apache/shiro.git shiro-root
cd shiro-root
git checkout -f shiro-root-1.4.0
  1. 搭建环境可参考SHIRO-550的搭建方式

三、漏洞分析

1. SHIRO-550回顾

  • 触发点:cookie中的RememberMe字段
  • 漏洞触发流程:
    • Base64解码
    • 使用AES解密
    • 反序列化解密后的字符串
  • Shiro 1.2.5之前:AES密钥硬编码在源码中,可直接构造反序列化payload实现RCE
  • Shiro 1.2.5之后:采用随机密钥,需要新的攻击方式

2. SHIRO-721漏洞原理

通过Padding Oracle攻击获取AES密钥:

  1. Padding验证机制

    • 当修改padding值时:
      • padding正确但反序列化错误 → 抛出"deserialize error"
      • padding错误 → 抛出"padding error"
  2. 关键代码分析:

    • padding正确但反序列化错误的处理:

      try {
          ObjectInputStream ois = new ClassResolvingObjectInputStream(bis);
          @SuppressWarnings({"unchecked"})
          T deserialized = (T) ois.readObject();
          ois.close();
          return deserialized;
      } catch (Exception e) {
          String msg = "Unable to deserialize argument byte array.";
          throw new SerializationException(msg, e);
      }
      
    • padding错误的处理:

      try {
          return cipher.doFinal(bytes);
      } catch (Exception e) {
          String msg = "Unable to execute 'doFinal' with cipher instance [" + cipher + "].";
          throw new CryptoException(msg, e);
      }
      
  3. 关键问题

    • Shiro对所有解密错误统一处理为调用removeFrom,最终返回deleteMe
    • 这使得无法直接构造Padding Oracle所需的bool条件
  4. 解决方案

    • 利用Java反序列化的特性:ObjectOutputStream以队列方式读取数据,后面拼接无关内容不会影响反序列化
    • 在抓取的rememberMe值后附加新的IV和value,既能成功反序列化,又能验证padding正确性

3. 权限验证机制

Shiro接口验证有两种权限:

  • authc:需要认证通过
  • user:需要登录过(包括通过rememberMe登录)

如果开启了rememberMe功能:

  • user权限可以通过
  • authc权限无法通过

四、利用条件

  1. 可以登录系统(获取初始有效cookie)
  2. 找到使用rememberMe的接口(具有user权限的接口)
  3. 可以进行Padding Oracle攻击

五、本地测试

  1. 使用公开的PoC工具(如ysoserial)
  2. 测试URLDNS验证漏洞存在性

六、实战挖掘案例

以RuoYi CMS(使用Shiro 1.4.1)为例:

  1. 登录接口分析:
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) {
    UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
    Subject subject = SecurityUtils.getSubject();
    try {
        subject.login(token);
        return success();
    } ...
}
  1. 权限配置分析:
// 所有请求需要认证
filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  1. 确认所有接口都有user权限,满足利用条件

七、防御措施

  1. 升级到Shiro 1.4.2及以上版本
  2. 禁用rememberMe功能(如不需要)
  3. 使用自定义密钥而非随机密钥
  4. 实施严格的输入验证和过滤

八、参考资源

  1. Shiro Padding Oracle Attack分析
  2. 官方漏洞公告和补丁说明

附录:技术要点总结

  1. Padding Oracle攻击:利用服务器对不同padding状态的响应差异获取加密信息
  2. CBC模式特性:了解CBC模式的加密过程和IV的作用
  3. Java反序列化特性:理解ObjectOutputStream的队列式读取特性
  4. Shiro权限模型:清楚区分authc和user权限的区别
Apache Shiro Padding Oracle漏洞分析与利用教学文档 一、漏洞背景 Apache Shiro是一个功能强大且易用的Java安全框架,提供认证、授权、加密和会话管理等功能。在Shiro的RememberMe功能实现中存在Padding Oracle漏洞(CVE-2019-12422,SHIRO-721),允许攻击者在特定条件下通过Padding Oracle攻击获取加密密钥,进而实现反序列化RCE。 二、环境搭建 获取漏洞版本代码: 搭建环境可参考SHIRO-550的搭建方式 三、漏洞分析 1. SHIRO-550回顾 触发点:cookie中的RememberMe字段 漏洞触发流程: Base64解码 使用AES解密 反序列化解密后的字符串 Shiro 1.2.5之前:AES密钥硬编码在源码中,可直接构造反序列化payload实现RCE Shiro 1.2.5之后:采用随机密钥,需要新的攻击方式 2. SHIRO-721漏洞原理 通过Padding Oracle攻击获取AES密钥: Padding验证机制 : 当修改padding值时: padding正确但反序列化错误 → 抛出"deserialize error" padding错误 → 抛出"padding error" 关键代码分析: padding正确但反序列化错误 的处理: padding错误 的处理: 关键问题 : Shiro对所有解密错误统一处理为调用 removeFrom ,最终返回 deleteMe 这使得无法直接构造Padding Oracle所需的bool条件 解决方案 : 利用Java反序列化的特性: ObjectOutputStream 以队列方式读取数据,后面拼接无关内容不会影响反序列化 在抓取的rememberMe值后附加新的IV和value,既能成功反序列化,又能验证padding正确性 3. 权限验证机制 Shiro接口验证有两种权限: authc :需要认证通过 user :需要登录过(包括通过rememberMe登录) 如果开启了rememberMe功能: user 权限可以通过 authc 权限无法通过 四、利用条件 可以登录系统(获取初始有效cookie) 找到使用rememberMe的接口(具有 user 权限的接口) 可以进行Padding Oracle攻击 五、本地测试 使用公开的PoC工具(如ysoserial) 测试URLDNS验证漏洞存在性 六、实战挖掘案例 以RuoYi CMS(使用Shiro 1.4.1)为例: 登录接口分析: 权限配置分析: 确认所有接口都有 user 权限,满足利用条件 七、防御措施 升级到Shiro 1.4.2及以上版本 禁用rememberMe功能(如不需要) 使用自定义密钥而非随机密钥 实施严格的输入验证和过滤 八、参考资源 Shiro Padding Oracle Attack分析 官方漏洞公告和补丁说明 附录:技术要点总结 Padding Oracle攻击 :利用服务器对不同padding状态的响应差异获取加密信息 CBC模式特性 :了解CBC模式的加密过程和IV的作用 Java反序列化特性 :理解ObjectOutputStream的队列式读取特性 Shiro权限模型 :清楚区分authc和user权限的区别