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

相关推荐
你不是我我12 小时前
【Java 开发日记】HTTP3 性能更好,为什么内网微服务依然多用 HTTP2?HTTP2 内网优势是什么?
java·开发语言·微服务
雪碧聊技术13 小时前
大模型爆火!Java后端如何抓住Agent全栈开发的风口
java·大模型·agent·全栈开发
逻辑驱动的ken14 小时前
Java高频面试场景题25
java·开发语言·深度学习·面试·职场和发展
AI人工智能+电脑小能手15 小时前
【大白话说Java面试题】【Java基础篇】第32题:Java的异常处理机制是什么
java·开发语言·后端·面试
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ16 小时前
通过java后端代码来实现给word内容补充格式文本内容控件,以及 设置控件的标记和标题
java·c#·word
無限進步D17 小时前
Java 面向对象高级 接口
java·开发语言
逸Y 仙X18 小时前
文章二十七:ElasticSearch ES查询模板(Search Template)高效复用实战
java·大数据·数据库·elasticsearch·搜索引擎·全文检索
m0_7381207218 小时前
应急响应(重点)——记一次某公司流量应急溯源分析(附带下载链接)
服务器·前端·数据库·安全·web安全·网络安全
二哈赛车手18 小时前
新人笔记---Spring AI的Advisor以及其底层机制讲解(涉及源码),包含一些遇见的Spring AI的Advisor缺陷问题的解决方案
java·人工智能·spring boot·笔记·spring