Shiro-550 动调分析与密钥正确性判断
一、Shiro 简介
Apache Shiro是一个开源安全框架,用于构建 Java 应用程序,提供身份验证、授权、加密和会话管理等功能。
二、Shiro-550(CVE-2016-4437)
1、漏洞原理
Shiro 在用户登陆时提供可选项 RememberMe,若勾选则下次登陆会携带 cookie 中的 remember me 字段发起请求,就不需要重新输入用户名和密码,用户登录成功后会生成经过 AES 加密和 base64 编码的 cookie。攻击者可以使用 Shiro 的默认密钥构造恶意序列化对象进行编码来伪造用户的 cookie,服务端反序列化时触发漏洞,从而实现恶意代码执行。
AES 是对称加密,加解密是相同的密钥,Shiro 1.2.4 及之前的版本中,AES 加密的密钥默认硬编码是写在代码中的,我们便可使用公开密钥进行爆破。
2、环境搭建
简单的 Shiro Web 应用项目用的是 phith0n 师傅的:https://github.com/phith0n/JavaThings/tree/master/shirodemo
https://github.com/phith0n/JavaThings/tree/master/shirodemo
我用的 IDEA 来运行,当然你自己需要安装配置好 JDK、Tomcat 等


用户名和密码是:
root
secret


3、基本测试
我们勾选上 Remember me 进行登录,使用 burpsuite 抓包

响应包中包含特征字段:
rememberMe=deleteMerememberMe

在已经以记住我的方式登录后,后续的所有请求中 Cookie 都包含 rememberMe 字段,这个字段就是我们反序列化的利用点,但是我们可以看到,它的值是密文的形式存在的,我们就需要找到正确的密钥,对我们构造的 payload 进行加密后再传给 rememberMe 字段,从而让它解密后在反序列化时触发恶意代码执行。
4、漏洞利用
直接使用默认密钥进行检测,也可以爆破密钥,都会发现密钥就是:
kPH+bIxk5D2deZiIxcaaaA==

尝试命令执行,没有问题

5、源码分析
因为我们利用的点是 Cookie 里的 rememberMe 字段,因此我们搜一下 Cookie 相关的类和方法。
这里我们找的是 CookieRememberMeManager 类:

在这个类下面有一个叫 getCookie() 的方法
在这里下断点,动态调试

burpsuite 发包

进去后,我们来到了 getRememberedSerializedIdentity() 方法

往下走,可以看到我们 cookie 中 rememberMe 的值传给了一个名为 base64 的变量

if ("deleteMe".equals(base64))
先判断传入的内容是不是等于 "deleteMe",显然不等于
base64 = this.ensurePadding(base64);
接下来使用 ensurePadding 方法确保 base64 编码字符串的填充正确

之后对传入内容进行 base64 解密,解密结果作为返回值

将返回值存储在字节数组 bytes 中

之后调用 convertBytesToPrincipals() 函数,bytes 作为第一个参数传入
进函数去看看

如果 getCipherService() 返回非 null ,表示加密服务存在,就对字节数组 bytes 进行解密,再调用 deserialize() 函数,将解密后的字节数据反序列化成 Java 对象(PrincipalCollection 对象)。
我们来详细看一下这个加密服务:
使用的是 AES 的 CBC 模式加密,填充模式为 PKCS5Padding

跟进去看一下解密函数

decrypt() 函数有两个参数,第一个是 encrypted ,即前面的字节数组 bytes,也就是 base64 解密后的内容,第二个是 getDecryptionCipherKey() 函数,跟进看看:
该函数会返回一个 decryptionCipherKey

看看这个 decryptionCipherKey,发现它是一个变量

看看谁调用了它,首先是这个 setDecryptionCipherKey() 调用了

再看看谁调用了 setDecryptionCipherKey() ,发现是 setCipherKey() 调用了

继续看谁调用了 setCipherKey(),发现是 AbstractRememberMeManager() 方法

该方法里面有一个常量 DEFAULT_CIPHER_KEY_BYTES
其值为固定值,即 kPH+bIxk5D2deZiIxcaaaA== 经过base64解密的值

理清调用流程后,我们发现 decryptionCipherKey 其实就是默认密钥: 即 kPH+bIxk5D2deZiIxcaaaA== 经过 base64 解码的值。
密钥值作为 getDecryptionCipherKey() 函数的返回值,作为第二个参数传入到 decrypt() 函数,对前面的字节数组 bytes 进行 AES 解密。
但是 AES 解密除了密钥还需要一个偏移量 IV,也在 decrypt() 函数里:
可以看到 iv = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 即 16 个字节全是 0

解密完成后,调用 deserialize 函数进行反序列化

跟进看看

反序列化调用 readObject() 位置

至此,我们理清了 cookie 的 rememberMe 内容传入后解密的整个过程,即:
cookie密文-> base64 解码 -> AES 解密(CBC 模式,PKCS5Padding,默认密钥 kPH+bIxk5D2deZiIxcaaaA== ,偏移量 IV 这里全是 0) -> 反序列化
首先在 CookieRememberMeManager.getRememberedSerializedIdentity 中进行 base64 解码,然后调用 AbstractRememberMeManager.convertBytesToPrincipals 进行 AES 解密和反序列化。
三、密钥正确性判断
代码中,当捕获到异常会调用 onRememberedPrincipalFailure 方法

跟进,会找到一个叫 removeFrom() 的方法:
当传入的 cookie 在解密或者反序列化失败时,就会触发这个方法,在 HTTP 响应中添加一个 Set-Cookie 头部,并且带上 deleteMe 字段。

对于正确的 key,回显不会存在 Set-Cookie:rememberMe=deleteMe 字段

对于不正确的 key,回显会出现 Set-Cookie:rememberMe=deleteMe 字段

四、小结
Shiro-550 的根本原因:Shiro 1.2.4 及之前的版本中,AES加密的密钥默认硬编码在代码里,Shiro 1.2.4 以上版本官方移除了代码中的默认密钥,要求开发者自己设置,如果开发者没有设置,则默认动态生成,降低了固定密钥泄漏的风险。
对于漏洞的利用,我们反着代码的处理过程构造 poc 即可:
构造序列化后的 payload -> AES 加密 -> base64 加密 -> 传递给 cookie
相关文章:
Shiro-550 动调分析与密钥正确性判断
一、Shiro 简介 Apache Shiro是一个开源安全框架,用于构建 Java 应用程序,提供身份验证、授权、加密和会话管理等功能。 二、Shiro-550(CVE-2016-4437) 1、漏洞原理 Shiro 在用户登陆时提供可选项 RememberMe,若勾选…...
Python制作简易PDF查看工具PDFViewerV1.0查找功能优化
原文说明 为不破坏原文结构,因此功能优化不在原文中维护了。关于这款工具原文请通过下面链接访问。Python制作简易PDF查看工具PDFViewerV1.0 这款小工具基本功能已经可以作为一款文档浏览器使用,但还有一些美中不足的地方,本文将介绍对文本查…...
20250419将405的机芯由4LANE的LVDS OUT配置为8LANE的步骤
20250419将405的机芯由4LANE的LVDS OUT配置为8LANE的步骤 2025/4/19 15:38 查询格式YUV/RGB 81 09 04 24 60 FF 90 50 00 00 FF 查询辨率帧率 81 09 04 24 72 FF 90 50 01 03 FF 查询LVDS mode : Singel output/Dual output 81 09 04 24 74 FF 90 50 00 00 FF 配置405的机…...
从0开发一个unibest+vue3项目,使用vscode编辑器开发,总结vue2升vue3项目开始,小白前期遇到的问题
开头运行可看官网 链接: unibest官网 一:vscode中vue3代码显示报错标红波浪线 去查看扩展商店发现一些插件都弃用了,例如h5的插件以及vue老插件 解决办法:下载Vue - Official插件(注意:横杠两边是要加空格的ÿ…...
Jinja2模板引擎SSTI漏洞
1. 引入 再研究大模型相关应用的漏洞CVE-2025-25362时(参考1),看到作者给了比较详细的分析(参考2)。下面对这个漏洞做个介绍。 2. 漏洞类型 这个漏洞属于CWE-1336,它主要关注在使用模板引擎进行脚本化处…...
HTML5好看的水果蔬菜在线商城网站源码系列模板4
文章目录 1.设计来源1.1 主界面1.2 关于我们1.3 商品信息1.4 新闻资讯1.5 联系我们1.5 登录注册 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/147264262 HTML5好看的水果…...
Python语法系列博客 · 第6期[特殊字符] 文件读写与文本处理基础
上一期小练习解答(第5期回顾) ✅ 练习1:字符串反转模块 string_tools.py # string_tools.py def reverse_string(s):return s[::-1]调用: import string_tools print(string_tools.reverse_string("Hello")) # 输出…...
多人五子棋联机对战平台 测试报告
目录 项目介绍 测试用例设计 部分功能测试示例 自动化测试 测试范围 排除范围 自动化测试目录编辑 执行全部自动化测试用例 性能说明 总结 性能测试 结果分析 测试总结 项目介绍 该项目基于WebSocket实现实时通信,采用SSM框架构建在线五子棋多人联机…...
docker基本使用命令
一、镜像 1、拉取镜像 docker pull busybox docker pull nginx:1.26-alpine 2、查看本地镜像 [rootRocky-1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 4e1b6bae1e48 18 hours ago 192MB busybox lates…...
欣佰特携数十款机器人相关前沿产品,亮相第二届人形机器人和具身智能行业盛会
2025年4月15日至16日,备受关注的第二届中国人形机器人与具身智能产业大会已在北京成功举行。作为国内前沿科技及产品服务领域的重要参与者,欣佰特科技携众多前沿产品精彩亮相,全方位展示了其在人形机器人与具身智能领域的创新产品。 在本次大…...
windows安装hadoop-3.3.5(图文教程)
本章教程,记录在Windows操作系统上安装hadoop-3.3.5的整个过程。 一、基础环境准备 JDK版本:java version “1.8.0_431” ,并且配置JAVA_HOME系统环境变量 hadoop版本:3.3.5,配置HADOOP_HOME系统环境变量。 下载地址:https://archive.apache.org/dist/hadoop/common/hado…...
【eNSP实验】OSPF单区域配置
简介 OSPF(开放最短路径优先)是一种基于链路状态算法的内部网关协议(IGP),用于自治系统内部动态路由。其核心机制为:各路由器通过泛洪链路状态通告(LSA)同步网络拓扑,构…...
从 SQL2API 到 Text2API:开启数据应用开发的新征程
在技术革新浪潮的席卷下,数据应用开发领域正经历着深刻变革。曾经,构建数据 API 需要开发者具备扎实的数据库知识和编程技能,手动编写复杂的 SQL 查询与 API 代码,这一过程不仅耗时费力,还将众多非技术人员阻挡在数据应…...
4月18日日记(补)
昨天玩的太疯狂了最后也没来得及写日记,补上() 正常的早八微积分,英语,下午的思政课非常的疯狂啊,因为是代课老师,她给我们很多机会强大加分,大家都知道这是一个追分的好机会&#x…...
手撕 简易HashMap
put()、get()、remove() 方法 计算存储数组位置和k-vNode节点 public int indexOf(K key){return key.hashCode() & (table.length - 1);}static class Node<K, V>{K key;V value;Node<K, V> next;public Node(K key, V value){this.key key;this.value val…...
【技术派后端篇】ElasticSearch 实战指南:环境搭建、API 操作与集成实践
1 ES介绍及基本概念 ElasticSearch是一个基于Lucene 的分布式、高扩展、高实时的基于RESTful 风格API的搜索与数据分析引擎。 RESTful 风格API的特点: 接受HTTP协议的请求,返回HTTP响应;请求的参数是JSON,返回响应的内容也是JSON…...
鸿蒙语言基础
准备工作 去鸿蒙官网下载开发环境 点击右侧预浏览,刷新和插销按钮,插销表示热更新,常用按钮。 基础语法 string number boolean const常量 数组 let s : string "1111"; console.log("string", s);let n : number …...
在 Amazon Graviton 上运行大语言模型:CPU 推理性能实测与调优指南
引言 在生成式 AI 浪潮中,GPU 常被视为大模型推理的唯一选择。然而,随着 ARM 架构的崛起和量化技术的成熟,CPU 推理的性价比逐渐凸显。本文基于 Amazon Graviton 系列实例与 llama.cpp 工具链,实测了 Llama 3、DeepSeek 等模型的…...
每日定投40刀BTC(14)20250409 - 20250419
定投 坚持 《磨剑篇》浮生多坎壈,志业久盘桓。松柏凌霜易,骅骝涉险难。砺锋临刃缺,淬火取金残。但使精魂在,重开万象端。...
详解反射型 XSS 的后续利用方式:从基础窃取到高级组合拳攻击链
在网络安全领域,反射型跨站脚本攻击(Reflected Cross-Site Scripting,简称反射型 XSS)因其短暂的生命周期和临时性,常被视为“低危”漏洞,威胁性不如存储型或 DOM 型 XSS。然而,这种看法低估了它…...
服务治理-服务注册
一个服务在真实项目部署的时候,如果压力较大,会做多实例部署。 在IDEA里面做多实例部署的话,只需要配置多个启动项。...
NestJS——多环境配置方案(dotenv、config、@nestjs/config、joi配置校验)
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
MongoDB导出和导入数据
安装mongodump工具 参考文章mongodump工具安装及使用详解_mongodump安装-CSDN博客 MongoDB导入导出和备份的命令工具从4.4版本开始不再自动跟随数据库一起安装,而是需要自己手动安装。 官方网站下载链接:Download MongoDB Command Line Database Tools …...
数据从辅存调入主存,页表中一定存在
在虚拟内存系统中,数据从辅存调入主存时,页表中一定存在对应的页表项,但页表项的「存在状态」会发生变化。以下是详细分析: 关键逻辑 页表的作用 页表是虚拟内存的核心数据结构,记录了虚拟地址到物理地址的映射关系…...
Serving入门
ServingHelloWorld Serverless 一个核心思想就是按需分配,那么 Knative 是如何实现按需分配的呢?另外在前面已经了解到 Knative Serving 在没有流量的时候是可以把Pod 缩容到零的。接下来就通过一些例子体验一下 Knative 缩容到零和按需自动扩缩容的能力…...
硬件操作指南——ATK-MD0430 V20
使用CC2530控制正点原子ATK-MD0430 V20显示的完整指南 本文将详细介绍如何使用CC2530单片机控制正点原子ATK-MD0430 V20显示屏,包括IAR开发环境的配置、硬件连接、程序编写和调试等完整步骤。 一、开发环境准备 1. IAR开发环境安装与配置 首先需要安装IAR Embed…...
【HDFS入门】HDFS数据冗余与容错机制解析:如何保障大数据高可靠存储?
目录 1 HDFS冗余机制设计哲学 1.1 多副本存储策略的工程权衡 1.2 机架感知的智能拓扑算法 2 容错机制实现原理 2.1 故障检测的三重保障 2.2 数据恢复的智能调度 3 关键场景容错分析 3.1 数据中心级故障应对 3.2 数据损坏的校验机制 4 进阶优化方案 4.1 纠删码技术实…...
UE学习记录part19
231 insect: insect enemy type 创建dead动画资源 往insect head上添加socket 创建攻击root motion动画。motion warping需要与root motion合作使用 为buff_blue创建物理资产 设置simulate physic使sinsect死亡后能落到地板上而不是漂浮在空中,要将die函数设置为 -…...
运行后allure报告没有自动更新(已解决)
pycharm直接运行run.py文件, allure生成的报告都没有更新,需要手动删除旧报告后再次运行才可以 pytest.ini [pytest]testpaths testcases/ addopts --alluredir ./report/result --clean-alluredir run.py主要代码 if __name__ "__main__&qu…...
深度学习在语音识别中的应用
引言 语音识别技术是人工智能领域中的一个重要分支,它使得机器能够理解和转换人类的语音为文本。深度学习的出现极大地推动了语音识别技术的发展。本文将介绍如何使用深度学习构建一个基本的语音识别系统,并提供一个实践案例。 环境准备 在开始之前&a…...
