什么是 Shiro-550 漏洞?——从原理到实践的完整指南
前言Shiro-550反序列化漏洞大约在2016年就被披露了但感觉直到近一两年在各种攻防演练中这个漏洞才真正走进了大家的视野Shiro-550反序列化应该可以算是这一两年最好用的RCE漏洞之一原因有很多:Shiro框架使用广泛漏洞影响范围广;攻击payload经过AES加密很多安全防护设备无法识别/拦截攻击...最初碰到Shiro反序列化漏洞应该是在2017或者2018年的一个CTF线下赛。一直到现在这个漏洞不断有新的知识出现因此打算开个系列笔记重新记录漏洞学习过程。环境搭建下载源码https://github.com/apache/shiro.git编辑 shiro/samples/web 目录下的 pom.xml, 将 jstl 的版本修改为 1.2dependency groupIdjavax.servlet/groupId artifactIdjstl/artifactId version1.2/version scoperuntime/scope /dependency漏洞概述Shiro-550CVE-2016-4437 是 Apache Shiro 框架中的一个 高危反序列化远程代码执行漏洞 。攻击者可以通过构造恶意的 rememberMe cookie在目标服务器上执行任意 Java 代码。漏洞原理在 Shiro 1.2.4 及之前版本 中 AbstractRememberMeManager 使用了 硬编码的默认加密密钥private static final byte[] DEFAULT_CIPHER_KEY Base64.decode(kPHbIxk5D2deZiIxcaaaA);这个密钥是公开的攻击者可以1. 使用该密钥加密恶意序列化对象包含 Gadget 链如 CommonsCollections2. 将加密结果作为 rememberMe cookie 发送给目标服务器3. 服务器解密后反序列化恶意对象 → 执行任意代码RememberMe 机制流程在 CookieRememberMeManager 中身份信息的处理流程如下序列化加密流程 用户登录勾选记住我 ↓ PrincipalCollection用户身份 ↓ serialize() → Java 序列化对象 ↓ encrypt() → AES 加密 ↓ Base64.encodeToString() → Base64 编码 ↓ 写入 rememberMe cookie反序列化解密流程 读取 rememberMe cookie ↓ Base64.decode() → Base64 解码 ↓ decrypt() → AES 解密 ↓ deserialize() → Java 反序列化 ↓ 获取 PrincipalCollection → 自动登录漏洞分析代码层面代码分析思路如何找到关键方法从功能入口找线索当我们要分析 Shiro 的 RememberMe 功能时首先要问 这个功能是怎么触发的1. 用户登录时勾选记住我 → 服务端写入 rememberMe cookie2. 用户下次访问 → 服务端读取 rememberMe cookie → 自动登录所以我们应该从 cookie 的读写 入手。搜索 rememberMe 关键字找到 CookieRememberMeManager.java 。加密流程详解用户登录时入口 rememberSerializedIdentity 方法这个方法接收的 serialized 参数已经是加密后的字节数组了。追溯谁调用了 rememberSerializedIdentity查看父类 AbstractRememberMeManager.java核心加密 convertPrincipalsToBytes 方法这里就是漏洞的关键位置 先序列化再加密。序列化 serialize 方法这里实际调用的是 DefaultSerializer.java#L45-L65这是标准的 Java 序列化任何实现了 Serializable 接口的对象都能被序列化。加密 encrypt 方法AbstractRememberMeManager.java#L523-L531AES 加密核心 AesCipherService.encrypt实际调用的是父类 JcaCipherService.java#L306-L317继续看 JcaCipherService.java#L319-L348最终加密 crypt 方法底层调用 cipher.doFinal(bytes) 完成 AES 加密。解密流程详解用户下次访问时入口 getRememberedSerializedIdentity 方法CookieRememberMeManager.java#L196-L249protected byte[] getRememberedSerializedIdentity(SubjectContext subjectContext) { if (!WebUtils.isHttp(subjectContext)) { if (LOGGER.isDebugEnabled()) { String msg SubjectContext argument is not an HTTP-aware instance. This is required to obtain a servlet request and response in order to retrieve the rememberMe cookie. Returning immediately and ignoring rememberMe operation.; LOGGER.debug(msg); } return null; } WebSubjectContext wsc (WebSubjectContext) subjectContext; if (isIdentityRemoved(wsc)) { return null; } HttpServletRequest request WebUtils.getHttpRequest(wsc); HttpServletResponse response WebUtils.getHttpResponse(wsc); String base64 getCookie().readValue(request, response); // Browsers do not always remove cookies immediately (SHIRO-183) // ignore cookies that are scheduled for removal if (Cookie.DELETED_COOKIE_VALUE.equals(base64)) { return null; } if (base64 ! null) { base64 ensurePadding(base64); if (LOGGER.isTraceEnabled()) { LOGGER.trace(Acquired Base64 encoded identity [ base64 ]); } byte[] decoded; try { decoded Base64.decode(base64); } catch (RuntimeException rtEx) { /* * https://issues.apache.org/jira/browse/SHIRO-766: * If the base64 string cannot be decoded, just assume there is no valid cookie value. * */ getCookie().removeFrom(request, response); LOGGER.warn(Unable to decode existing base64 encoded entity: [ base64 ]., rtEx); return null; } if (LOGGER.isTraceEnabled()) { LOGGER.trace(Base64 decoded byte array length: decoded.length bytes.); } return decoded; } else { //no cookie set - new site visitor? return null; } }追溯谁调用了 getRememberedSerializedIdentity查看父类 AbstractRememberMeManager.java#L416-L432核心解密 convertBytesToPrincipals 方法这里就是漏洞利用的关键 如果攻击者能控制解密后的数据就能执行任意代码。解密 decrypt 方法AbstractRememberMeManager.java#L539-L547AES 解密核心 JcaCipherService.decryptInternal反序列化 deserialize 方法AbstractRememberMeManager.java#L567-L569实际调用的是 DefaultSerializer.java#L75-L92危险就在这里 ois.readObject() 会执行对象的反序列化如果数据是恶意构造的就会触发 Gadget 链执行任意代码。代码流程图总结加密流程登录时用户身份 (PrincipalCollection) ↓ AbstractRememberMeManager.rememberIdentity() ↓ convertPrincipalsToBytes() ↓ serialize() → DefaultSerializer.serialize() → ObjectOutputStream.writeObject() ↓ encrypt() → JcaCipherService.encrypt() ↓ AES/GCM/NoPadding 加密带随机 IV ↓ IV 密文 拼接 ↓ Base64.encodeToString() ↓ CookieRememberMeManager.rememberSerializedIdentity() ↓ 写入 rememberMe cookie解密流程访问时读取 rememberMe cookie ↓ CookieRememberMeManager.getRememberedSerializedIdentity() ↓ Base64.decode() ↓ AbstractRememberMeManager.getRememberedPrincipals() ↓ convertBytesToPrincipals() ↓ decrypt() → JcaCipherService.decryptInternal() ↓ 提取 IV → AES/GCM/NoPadding 解密 ↓ deserialize() → DefaultSerializer.deserialize() → ObjectInputStream.readObject() ↓ 获取 PrincipalCollection → 自动登录漏洞利用这里的话我直接用工具就进行测试了这里的话也可以伪造cookie去进行命令执行测试时候记得删除cookie里面的jsessionid利用流程攻击者构造恶意序列化对象含 Gadget 链 ↓ 使用默认密钥 AES 加密 ↓ Base64 编码 ↓ 发送 rememberMe cookie 给目标服务器 ↓ 服务器读取 cookie → Base64 解码 ↓ 使用默认密钥 AES 解密 ↓ Java 反序列化 → 触发 Gadget 链 ↓ 执行任意代码如反弹 Shell防御建议措施优先级说明升级 Shiro 版本 高使用 1.2.5 版本默认使用随机密钥自定义密钥 高通过配置文件设置自己的 cipherKey禁用 RememberMe 中如果业务不需要直接禁用此功能审计依赖 中移除不必要的包含 Gadget 的库使用安全序列化 低考虑使用白名单机制或替换 Java 原生序列化

相关新闻

ComfyUI-VideoHelperSuite终极指南:5个技巧让你轻松掌握AI视频处理

ComfyUI-VideoHelperSuite终极指南:5个技巧让你轻松掌握AI视频处理

ComfyUI-VideoHelperSuite终极指南:5个技巧让你轻松掌握AI视频处理 【免费下载链接】ComfyUI-VideoHelperSuite Nodes related to video workflows 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-VideoHelperSuite 你知道吗?将AI生成的图…

2026/7/6 6:49:36阅读更多 →
c语言预备知识

c语言预备知识

一、一元二次方程#include <stdio.h> #include <math.h>int main(void) {//三个系数int a 1, b 2, c 3;// 全部改为 double 匹配 sqrt 返回值double d, x1, x2;d b * b - 4 * a * c;if (d > 0) {x1 (-b sqrt(d)) / (2 * a);x2 (-b - sqrt(d)) / (2 * a);…

2026/7/6 6:49:36阅读更多 →
工业4-20mA电流环设计与STM32 DAC校准实战

工业4-20mA电流环设计与STM32 DAC校准实战

1. 4-20mA电流环技术背景与XTR116特性解析工业现场最头疼的问题莫过于长距离信号传输中的干扰和衰减。我在化工厂做自动化改造时&#xff0c;曾遇到过传感器信号传输300米后误差高达15%的案例。这正是4-20mA电流环技术诞生的背景——电流信号相比电压信号具有天然的抗干扰优势&…

2026/7/6 6:49:36阅读更多 →
数据库备份最佳实践:分层策略与原生备份核心指南

数据库备份最佳实践:分层策略与原生备份核心指南

1. 项目概述&#xff1a;备份不是选择题&#xff0c;而是生存底线在运维和开发一线干了十多年&#xff0c;我亲手处理过从单台物理服务器到跨三地数据中心的上百套数据库系统。最深的体会只有一条&#xff1a;备份不是“要不要做”的问题&#xff0c;而是“怎么做才不会在凌晨三…

2026/7/6 10:30:50阅读更多 →
AI系统安全实战:异常流量熔断与对抗样本实时防御

AI系统安全实战:异常流量熔断与对抗样本实时防御

1. 项目概述&#xff1a;当AI系统遭遇“紧急情况”最近和几个负责线上AI服务的同行聊天&#xff0c;大家不约而同地提到了一个词&#xff1a;“惊心动魄”。不是业务增长带来的兴奋&#xff0c;而是面对突发异常流量或恶意攻击时&#xff0c;那种系统濒临崩溃、手忙脚乱的无力感…

2026/7/6 10:30:50阅读更多 →
Plone Deco布局引擎与tiles架构实战解析

Plone Deco布局引擎与tiles架构实战解析

1. 项目概述&#xff1a;一场海边的Plone技术攻坚实录2012年9月下旬&#xff0c;北卡罗来纳州奥克岛的海风里飘着咖啡香和键盘敲击声。这不是度假&#xff0c;而是一场名为“Sea Sprint”的Plone开发者集中攻坚——十位来自不同背景的开发者&#xff0c;在四天时间里&#xff0…

2026/7/6 10:30:50阅读更多 →
OpenSSL心脏滴血漏洞复现:从原理到实战的完整靶场搭建与利用指南

OpenSSL心脏滴血漏洞复现:从原理到实战的完整靶场搭建与利用指南

1. 项目概述与核心价值CVE-2014-0160&#xff0c;这个在信息安全史上留下浓墨重彩一笔的漏洞编号&#xff0c;背后是那个让全球互联网为之震颤的名字——“心脏滴血”&#xff08;Heartbleed&#xff09;。即便到了2025年&#xff0c;这个诞生于2014年的OpenSSL高危漏洞&#x…

2026/7/6 10:30:50阅读更多 →
PostgreSQL 9.2 的 Search 与 JSON 原生协同实践

PostgreSQL 9.2 的 Search 与 JSON 原生协同实践

1. 项目概述&#xff1a;一场穿越十年的技术回溯——重读 PostgreSQL 9.2 的真实价值你可能正盯着 PostgreSQL 15 或 16 的新特性公告&#xff0c;心里盘算着 JSONB 索引优化、向量搜索集成、逻辑复制增强这些“当下刚需”。但今天我想拉你坐下来&#xff0c;一起打开一个被很多…

2026/7/6 10:30:50阅读更多 →
Plone无代码主题切换:Diazo静态主题Web界面配置全指南

Plone无代码主题切换:Diazo静态主题Web界面配置全指南

1. 项目概述&#xff1a;把静态HTML主题“活”进Plone后台&#xff0c;不碰代码也能换皮肤 你手头有一套设计精美的静态HTML/CSS网站模板——可能是UI设计师给的交付物&#xff0c;也可能是从ThemeForest买来的响应式主题&#xff0c;甚至是你自己用Figma导出的纯前端页面。现在…

2026/7/6 10:25:49阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述&#xff1a;从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目&#xff0c;叫 skills4/skills &#xff0c;它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景&#xff1a;一个旨在展示或教授某种技能的仓库&#xff0c;本身却成了安…

2026/7/6 4:26:20阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示&#xff1a;因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战&#xff1a;从“黑箱预测”到“可信推理”2026年6月&#xff0c;第7届机器学习与趋势国际会议&#xff08;MLT 2026&#xff09;将在悉尼召开。会议议程中&#xff0c;“因果与可解释机器学习…

2026/7/6 2:48:33阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时&#xff0c;通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中&#xff0c;是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/6 0:10:35阅读更多 →
Seraphine:基于LCU API的英雄联盟智能游戏助手技术解析与应用指南

Seraphine:基于LCU API的英雄联盟智能游戏助手技术解析与应用指南

Seraphine&#xff1a;基于LCU API的英雄联盟智能游戏助手技术解析与应用指南 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine 技术架构先行&#xff1a;官方接口的合规应用 你是否曾在BP阶段手忙脚乱&#x…

2026/7/6 0:03:39阅读更多 →
多协议远程连接管理工具mRemoteNG:告别混乱,统一你的远程桌面管理

多协议远程连接管理工具mRemoteNG:告别混乱,统一你的远程桌面管理

多协议远程连接管理工具mRemoteNG&#xff1a;告别混乱&#xff0c;统一你的远程桌面管理 【免费下载链接】mRemoteNG mRemoteNG is the next generation of mRemote, open source, tabbed, multi-protocol, remote connections manager. 项目地址: https://gitcode.com/gh_m…

2026/7/6 0:03:39阅读更多 →
COUNT(DISTINCT) 与 GROUP BY 去重统计:5 亿数据量下的性能实测与选型指南

COUNT(DISTINCT) 与 GROUP BY 去重统计:5 亿数据量下的性能实测与选型指南

COUNT(DISTINCT) 与 GROUP BY 去重统计&#xff1a;5 亿数据量下的性能实测与选型指南在数据分析和处理领域&#xff0c;去重统计是最基础也是最频繁使用的操作之一。当数据量达到亿级规模时&#xff0c;不同的去重统计方法在性能上可能产生天壤之别。本文将基于 5 亿行数据的实…

2026/7/6 0:03:39阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时&#xff0c;发现推理速度只有可怜的 1-2 FPS&#xff0c;而别人的演示视频却能跑到 30 FPS 以上&#xff0c;那么问题很可能不在模型本身&#xff0c;而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后&#xff0c;会直接使用官方示例…

2026/7/6 4:45:01阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一&#xff1a;为什么你需要了解 Coze 和 Dify&#xff1f;如果你对 AI 应用开发感兴趣&#xff0c;但一看到“大模型”、“智能体”、“工作流”这些词就头疼&#xff0c;觉得门槛太高&#xff0c;那这篇文章就是为你准备的。很多开发者&#xff0c;包括我自己&#…

2026/7/6 4:45:01阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会&#xff1a;配图一直是个让人头疼的问题。2026年&#xff0c;AI生图工具已经非常成熟了&#xff0c;但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1&#xff1a;速度之王2026年6月11日&#xff0c…

2026/7/6 4:45:03阅读更多 →