Shiro 反序列化漏洞原理(小白零基础详解)

新做的海报,比较精简了这个。

文章目录

      • 0、前言
      • [1、什么是 Apache Shiro?](#1、什么是 Apache Shiro?)
      • [2、什么是 Java 序列化与反序列化?](#2、什么是 Java 序列化与反序列化?)
      • [3、什么是 Java 反序列化漏洞?](#3、什么是 Java 反序列化漏洞?)
      • [4、Shiro 反序列化漏洞核心原理](#4、Shiro 反序列化漏洞核心原理)
        • [1、正常的 RememberMe 免登录流程](#1、正常的 RememberMe 免登录流程)
        • 2、两个致命的漏洞核心
        • [缺陷 2:反序列化无任何安全校验](#缺陷 2:反序列化无任何安全校验)
      • 5、完整的攻击流程
      • 6、漏洞家族与影响范围
      • 7、小结

0、前言

这是 Java Web 安全领域最经典、最常见的远程代码执行(RCE)漏洞之一,攻击者可通过该漏洞直接控制目标服务器。

虽然知识比较基础,但是依旧要声明,保护网络安全,是网络知识的正确用法。

1、什么是 Apache Shiro?

Apache Shiro 是 Java 生态里应用最广泛的轻量级安全框架,比 Spring Security 更简单易用,绝大多数 Java Web 项目都会用它来实现:

  • 用户登录身份认证
  • 页面 / 接口权限控制
  • 会话管理
  • 加密功能

其中,记住我(RememberMe)免登录功能,就是这个漏洞的唯一入口。

2、什么是 Java 序列化与反序列化?

  • 序列化:将 Java 对象转换成字节流,用于网络传输、文件存储、数据库保存。
  • 反序列化:将字节流还原成 Java 对象,在内存中恢复对象的所有信息。

而这个漏洞之所以是反序列化漏洞,是因为Java 在反序列化一个对象时,会自动执行这个对象里的readObject()方法。如果这个方法里写了恶意代码,反序列化的瞬间就会被执行!

3、什么是 Java 反序列化漏洞?

如果攻击者能完全控制反序列化的输入(也就是那个字节流),就能构造一个恶意的 Java 对象,在里面写入要执行的系统命令(比如创建管理员、打开远程控制、删除文件)。

目标服务器拿到这个恶意字节流,反序列化的时候,就会自动执行恶意代码,服务器直接被攻击者控制,这就是远程代码执行(RCE)漏洞。

4、Shiro 反序列化漏洞核心原理

最经典的核心漏洞编号为CVE-2016-4437(俗称 Shiro-550),后续所有的 Shiro 反序列化漏洞,都是基于这个核心原理的补丁绕过。

1、正常的 RememberMe 免登录流程

漏洞完全是围绕 RememberMe 功能的流程展开的,必须先看懂正常业务的完整步骤:

1、用户登录网站,勾选「记住我」,输入账号密码登录成功。

2、Shiro 把用户的身份信息(用户名、权限等)序列化成字节流。

3、用AES 对称加密算法对字节流加密(加密和解密用同一个密钥)。

4、把加密后的字节流做 Base64 编码,变成一串可读的字符串。

5、把这个字符串放到 Cookie 中,命名为rememberMe,下发给用户浏览器。

6、用户下次访问网站,浏览器自动携带这个rememberMe Cookie。

7、Shiro 收到 Cookie 后,执行反向操作:Base64 解码 → AES 解密 → 反序列化,还原出用户身份,实现免密登录。

2、两个致命的漏洞核心

Shiro 的设计缺陷,让攻击者可以完美模仿这个流程,构造恶意请求:

缺陷 1:硬编码的全局默认密钥(最核心)

Shiro 1.2.4 及更早的版本,把 AES 加密的密钥直接写死在了开源源码里,全世界所有人都能拿到这个密钥:

python 复制代码
kPH+bIxk5D2deZiIxcaaaA==

这意味着,任何人都能用这个密钥,加密自己构造的恶意数据,让服务器完美解密通过。

缺陷 2:反序列化无任何安全校验

Shiro 拿到解密后的数据,直接无脑执行反序列化,没有任何校验:

  • 不检查数据是不是合法的用户身份信息
  • 不限制只能反序列化哪些可信的类
  • 不校验数据有没有被篡改

只要数据能解密成功,就直接反序列化,攻击者构造的恶意对象会被完美执行。

5、完整的攻击流程

攻击者利用漏洞的完整步骤,完全对应正常的业务流程,只是把用户身份信息换成了恶意代码:

  • 1、构造恶意 Payload:用工具(ysoserial)生成恶意序列化对象(也叫「利用链 / Gadget Chain」,比如常用的 CC 链、CB 链),里面写入要执行的系统命令(比如反弹 shell、执行 ping 命令)。
  • 2、加密恶意数据:用 Shiro 的默认密钥,对恶意序列化对象进行 AES 加密(和 Shiro 的加密模式完全一致:AES-CBC,PKCS5Padding 填充)。
  • 3、编码生成 Cookie:把加密后的字节流做 Base64 编码,生成最终的rememberMe Cookie 值。
  • 4、发送恶意请求:把构造好的 Cookie 放到 HTTP 请求中,发送给目标网站。
  • 5、服务器触发漏洞:Shiro 按正常流程处理:Base64 解码 → AES 解密(密钥正确,解密成功) → 反序列化恶意对象。
  • 6、获得服务器控制权:反序列化时,恶意对象的readObject()方法被执行,攻击者的命令在服务器上运行,目标服务器被完全控制。

6、漏洞家族与影响范围

除了核心的 Shiro-550,官方修复后又出现了多次补丁绕过,形成了完整的漏洞家族:

漏洞编号 俗称 影响版本 核心原理
CVE-2016-4437 Shiro-550 Shiro ≤ 1.2.4 默认硬编码 AES 密钥,无反序列化校验,最核心的基础漏洞
CVE-2019-12422 Shiro-721 1.2.5 ≤ Shiro ≤ 1.4.1 修复了硬编码密钥,但 AES-CBC 模式存在填充提示攻击,可通过合法 Cookie 爆破出密钥
CVE-2020-1957 Shiro ≤ 1.5.3 绕过官方的类黑名单校验,可利用新的利用链触发反序列化
CVE-2021-41303 Shiro ≤ 1.7.1 再次绕过补丁,通过特定加密模式和利用链触发漏洞

无论 Shiro 版本多新,只要 AES 密钥泄露(默认密钥、弱密钥、配置文件泄露等),就一定存在反序列化漏洞! 版本升级只是修复了默认硬编码的问题,解决不了密钥泄露后的根本风险。

不是所有用 Shiro 的网站都能被攻击,必须同时满足:

1、目标开启了 RememberMe 功能。

2、攻击者获取到了 AES 加密密钥(默认密钥、弱密钥爆破、密钥泄露等)。

3、目标项目里存在可用的反序列化利用链(比如引入了 Commons-Collections、Commons-Beanutils 等依赖包)。

7、小结

学习复现环境建议是Vulhub。

工具比较推荐

  • ShiroAttack2
  • ysoserial

至于Burp Suite这样的工具,都是必备的,不过多罗列。

相关推荐
chuan.bai1 分钟前
Java RAG 实战附录:qwen3 与 bge-m3 模型切换指南
java·人工智能·算法
SL_staff3 分钟前
销售知识管理的断点分析与技术解法:从3天找话术到秒级检索
java·开源·github
荣码4 分钟前
向量数据库选型:4种方案全测了,选错重来成本最高
java·python
rannn_1116 分钟前
【力扣hot100】二叉树专题+总结
java·算法·leetcode·二叉树
摇滚侠31 分钟前
《Docker技术入门与实战 第4版》阅读笔记 6 使用 Dockerfile 创建镜像 2
java·笔记·docker
余额瞒着我当琳1 小时前
C++--vector第二讲:手写 C++ STL:vector 源码剖析与迭代器失效分析
android·java·c++
资源大佬星 课it1 小时前
黑马 Java+AI新版V16零基础就业班视频课程百度网盘下载
java·开发语言·人工智能
二十雨辰1 小时前
[Java]-微服务面试题
java·开发语言·微服务
我命由我123451 小时前
Compose Codelab 学习 - Compose 中的基本布局
android·java·java-ee·kotlin·android studio·android-studio·android runtime
云水一下1 小时前
零基础玩转bWAPP靶场(六十五):SQLiteManager XSS
web安全·xss·bwapp·sqlitemanager·cve-2012-5105·bee-box