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这样的工具,都是必备的,不过多罗列。

相关推荐
Chockmans2 小时前
春秋云境CVE-2019-9618
安全·web安全·网络安全·系统安全·网络攻击模型·春秋云境·cve-2019-9618
少许极端2 小时前
算法奇妙屋(四十五)-CCPC备战之旅-1
java·开发语言·算法
songcream12 小时前
Spring Boot资料整理
java·spring boot·后端
源码宝2 小时前
新一代医院信息系统云HIS,多租户共享,java版HIS+EMR+LIS全套源码
java·大数据·源码·云his·his系统·源代码·医院信息系统
iiiiyu2 小时前
面向对象高级接口的综合案例
java·开发语言·数据结构·编程语言
wanhengidc2 小时前
流量清洗的作用是什么?
运维·服务器·网络·安全·web安全·智能手机
fzil0012 小时前
让 AI 自己协作 —— 多智能体(Swarm)系统的设计与实现
java·开发语言·人工智能·ubuntu
Mem0rin3 小时前
[Java/数据结构]二叉树练习题几则
java·开发语言·数据结构
lhbian3 小时前
PHP vs Java vs Go:编程语言终极对比
java·spring boot·后端·kafka·linq