漏洞复现
01-环境搭建
02-Tomcat
03-Nginx
04-Apache
05-JBoss
06-WebLogic
07-Nacos
08-Struts2
09-Spring
10-Log4j2
11-Shiro
12-FastJson
13-RuoYi
14-ThinkPHP
-
+
11-Shiro
浏览
1
# 一、Shiro ## 概述  Shiro 是一款轻量级的 Java 安全框架,提供了身份认证、授权、加密和会话管理等功能。 Shiro 的目标是简化 Java 安全编程,并提供更好的开发体验。 官网地址:https://shiro.apache.org/ Shiro 的主要特点如下: - 易于学习和使用:Shiro 设计简单,易于学习和使用。 - 灵活性高:Shiro 可以适用于任何应用场景,支持多种应用程序类型。 - 安全性高:Shiro 的安全性能比较优越,提供了多种方式来保护应用程序的安全性。 - 扩展性好:Shiro 框架提供了可扩展性插件机制,可以方便地扩展框架的功能,满足不同的需求。 - 企业级支持:Shiro 是从 Apache 基金会获得支持的框架,拥有众多企业用户。  Shiro有三大核心组件,即Subject、SecurityManager 和 Realm。 > Subject Subject 代表当前用户,是 Shiro 框架中最重要的组件之一。Subject 封装了用户的所有信息,包括身份(用户名和密码)和角色等。在一个应用程序中,可能有多个 Subject,每个 Subject 可以访问应用程序中的资源。 用户可以通过 Subject 登录应用程序,并执行诸如访问资源、修改个人配置等操作。Shiro 提供了简单易用的方法来管理用户的登录和退出行为,以及 Session 管理等。 > SecurityManager SecurityManager 是 Shiro 的核心组件,负责管理和协调整个应用程序的安全机制。它的主要职责是认证、授权、加密和会话管理等。 SecurityManager 将应用程序中的所有安全操作委托给适当的 Realms 进行处理,并存储和管理有关用户身份、角色和权限等信息。 SecurityManager 还可以配置多个 Realms,以便应用程序可以集成不同的认证和授权方案。 > Realm Realm 是 SecurityManager 中负责处理用户身份认证和授权的组件。Shiro 支持多种不同类型的 Realm,包括 JDBC Realm、LDAP Realm、Active Directory Realm 等。 每个 Realm 负责验证用户的身份,并获取用户的权限信息,以便 SecurityManager 可以根据这些信息进行访问控制和授权。Realm 还可以实现缓存机制,提高系统性能。 ## 特征 > 核心特征:RememberMe Cookie Shiro 的 “记住我”(RememberMe)功能会生成特定格式的 Cookie,这是识别 Shiro 应用的最核心、最直接的特征。 | 特征细节 | 具体表现 | 探测价值 | | ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | Cookie 名称 | 固定为 rememberMe(首字母小写,无空格或特殊字符)。 | 浏览器 F12 查看 Cookie 列表,若存在rememberMe Cookie,大概率是 Shiro 应用。 | | Cookie 值格式 | 1. 未勾选 “rememberMe”:值为deleteMe(登录后未勾选时,Shiro 会设置此值清除旧 Cookie);<br />2. 勾选 “rememberMe”:值为Base64 编码后的序列化数据(长度较长,通常几百到几千字符,如dGltZXN0YW1wOi8vMTIzLjQ1LjY3Ljg5OjE2...)。 | 若存在deleteMe或长 Base64 格式的rememberMe,可 100% 初步判定为 Shiro 应用;<br />Base64 值是 Shiro-550 漏洞探测的关键载体(需解码分析序列化格式)。 | | Cookie 属性 | 通常携带Path=/(作用域为全站)、HttpOnly(防 XSS 窃取)属性,部分配置会加Secure(仅 HTTPS 传输)。 | 结合rememberMe名称 +Path=/+HttpOnly,可进一步确认 Shiro 框架。 | > 响应头特征(未授权 / 认证场景) 当访问 Shiro 保护的资源(未登录或权限不足)时,服务器返回的响应头会带有 Shiro 的权限控制痕迹,是漏洞探测的重要辅助特征。 | 特征类型 | 具体表现 | 探测价值 | | ------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | WWW-Authenticate 头 | 未认证访问受保护资源时,响应头会返回 WWW-Authenticate: Basic realm="Shiro Realm" 或 Bearer realm="Shiro Realm"(取决于 Shiro 的认证策略配置)。 | “Shiro Realm” 关键字直接暴露框架身份,是无rememberMe Cookie 时的核心识别依据。 | | 状态码与跳转 | 1. 未认证时,可能返回 401 Unauthorized(无权限访问);2. 配置了登录页跳转时,返回 302 Found,Location 头指向登录页(如/login.jsp、/auth/login)。 | 401 状态码 +WWW-Authenticate头,可快速定位 Shiro 的权限拦截逻辑;302 跳转的登录页路径可作为后续探测的入口(如测试登录表单的 RememberMe 参数)。 | # 二、Shiro550 ## 漏洞描述 名字来源于 Apache Shiro 官方 JIRA 问题跟踪系统的漏洞工单编号:SHIRO-550,安全圈内习惯直接取编号数字部分,简称为「Shiro550」,它对应的官方通用漏洞编号是 CVE-2016-4437。 ## 影响范围 - Shiro <= 1.2.4 ## 漏洞原理 核心原因是 Shiro 1.2.4及以下版本中,登录表单中有一个“记住我(Remember Me)” 功能的加密密钥为硬编码,且序列化数据的解密与反序列化过程缺乏安全校验: 1. 硬编码密钥:Shiro 对 “Remember Me” 的用户身份信息(序列化数据)采用 AES 加密,但其加密 / 解密密钥(decryptionCipherKey)在源码中是固定值(默认密钥:kPH+bIxk5D2deZiIxcaaaA==,Base64 编码后的 AES 密钥),所有使用默认配置的 Shiro 应用均共用该密钥。 2. 当用户勾选 “记住我” 登录后,Shiro流程:将用户身份信息序列化→AES 加密→Base64 编码,最终存储在rememberMe Cookie 中。 3. 后续访问时,Shiro首先读取该 Cookie,经过 Base64 解码→AES 解密→反序列化,恢复用户身份。 若攻击者伪造包含恶意代码的序列化数据,用默认密钥加密后构造RememberMe Cookie,目标服务器解密后反序列化时,会触发恶意代码执行(RCE)。  设置加密的Key相关方法:  cipherKey参数,在shiro.ini中,找到cipherKey值。  实现的方法是在CookieRememberMeManagerTest类中:  默认的Key(也被称为硬编码) 是:kPH+bIxk5D2deZiIxcaaaA== ## 漏洞复现 进入靶场环境,启动容器 ```linux root@ubuntu:~/vulhub# cd ./shiro/CVE-2016-4437/ root@ubuntu:~/vulhub/shiro/CVE-2016-4437# docker compose up -d ```  访问8080端口,使用admin:vulhub进行登录   直接使用Shiro反序列化利用工具:添入默认密钥和目标地址,直接一键  一键利用工具建议选择GitHub中Star星比较高的! ## 修复建议 - 升级版本 # 三、Shiro721 ## 漏洞描述 Shiro 721(CVE-2019-12422) 核心是利用AES-CBC 加密模式的 Padding Oracle 攻击,在未知密钥的情况下,伪造或解密 [RememberMe] 功能的 Cookie,最终触发反序列化远程代码执行(RCE)。 ## 影响范围 - Apache Shiro 1.2.5 ~ 1.4.0 ## 漏洞原理 Shiro550 修复后(1.2.5 及以上版本),官方移除了硬编码密钥,要求用户自定义 AES 密钥,但加密逻辑仍存在缺陷: - 加密模式风险:Shiro 对 “RememberMe” Cookie 的加密仍使用AES-CBC 模式,该模式需要对不足块大小的数据进行 “填充”(Padding,如 PKCS#5/PKCS#7)。若加密数据的填充不符合规则,解密时会抛出 “填充错误” 异常。 - 响应差异泄露:当攻击者发送填充错误的恶意 Cookie 时,Shiro 会返回不同的错误响应(如 HTTP 状态码、响应内容差异) 例如,填充正确但解密失败时返回一种提示,填充错误时返回另一种提示。这种 “响应差异” 被称为 “Padding Oracle”,攻击者可利用该差异逐步破解加密数据或伪造恶意 Cookie。 - 反序列化未修复:即使密钥未知,攻击者通过 Padding Oracle 攻击伪造出合法的加密 Cookie 后,Shiro 仍会对其解密并反序列化,若 Cookie 中包含恶意序列化数据,将触发 RCE。 ## 填充操作 以 AES 为例,它是一种 “块加密算法”,只能处理固定大小的 “数据块”(AES 的块大小固定为 128 位,即 16 字节)。当待加密的数据长度不是块大小的整数倍时,就需要通过 “填充” 补足,这是块加密的基础操作。 块加密算法(如 AES、DES)的核心是:每次加密 / 解密只能处理固定长度的数据块(AES 为 16 字节)。如果原始数据的长度不是块大小的整数倍(比如 10 字节、20 字节),就需要在数据末尾添加一些 “填充字节”,使总长度刚好是块大小的整数倍。 例如: - 原始数据长度为 10 字节(不足 16 字节),需要填充 6 字节,总长度变为 16 字节(1 个块); - 原始数据长度为 20 字节(1 个块 16 字节 + 剩余 4 字节),需要填充 12 字节,总长度变为 32 字节(2 个块)。 填充不是随意添加字节,而是需要遵循约定的规则(否则解密时无法正确去除填充)。Shiro 中使用的是PKCS#7 填充规则(与 PKCS#5 兼容,适用于块大小≤255 字节的场景),规则如下: - 设块大小为B(AES 中B=16字节),原始数据长度为L; - 需要填充的字节数为P = B - (L % B)(即 “块大小 - 数据长度对块大小的余数”); - 填充的P个字节中,每个字节的值均为P(即填充字节的 “值” 等于填充的 “数量”)。 原始数据长度 = 10 字节(L=10): - 填充字节数P=16-10=6; - 填充 6 个字节,每个字节的值为0x06(十六进制),最终总长度 = 16 字节。 原始数据长度 = 16 字节(L=16,刚好是 1 个块): - 此时L%B=0,填充字节数P=16; - 填充 16 个字节,每个字节的值为0x10,最终总长度 = 32 字节(2 个块)。 解密时,算法会读取最后一个字节的值P,然后去除末尾P个字节,即可恢复原始数据(这就是填充规则的核心作用:让解密方知道需要去掉多少填充字节)。 ## 利用方式 在 Shiro 的 “RememberMe” 功能中,加密的RememberMe Cookie 解密流程如下: 1. 服务器读取 Cookie 值→Base64 解码→AES-CBC 解密(使用用户配置的密钥); 2. 解密后,先检查填充是否符合 PKCS#7 规则: - 若填充错误→抛出BadPaddingException,服务器可能返回特定错误响应(如 HTTP 500 状态码,或包含 “填充错误” 的提示); - 若填充正确→继续反序列化数据,若反序列化失败(如数据不是合法的序列化格式)→返回另一种响应(如 HTTP 200 但认证失败,提示 “无效的 rememberMe 令牌”)。 这种 “填充错误” 和 “填充正确但反序列化失败” 的响应差异(状态码、响应内容、响应时间等),就是 “Padding Oracle”(填充预言机) 攻击者可利用这种差异,通过以下方式伪造恶意 Cookie: 1. 构造大量不同填充的恶意数据,加密后作为rememberMe Cookie 发送给服务器; 2. 根据服务器的响应差异,判断当前填充是否正确(“是” 或 “否”); 3. 逐步调整填充和数据内容,最终 “猜解” 出能通过填充校验的加密数据(即使不知道密钥); 4. 当伪造的数据包含恶意序列化代码时,服务器解密后反序列化就会触发远程代码执行。  ## 修复建议 - 升级版本 # 四、CVE-2020-1957 ## 漏洞描述 认证绕过漏洞,CVE-2020-1957 CVE-2020-1957,Spring Boot中使用 Apache Shiro 进行身份验证、权限控制时,可以精心构造恶意的URL,利用 Apache Shiro 和 Spring Boot 对URL的处理的差异化,可以绕过 Apache Shiro 对 Spring Boot 中的 Servlet 的权限控制,越权并实现未授权访问。 对URL的权限配置如下: ```java @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); chainDefinition.addPathDefinition("/login.html", "authc"); // need to accept POSTs from the login form chainDefinition.addPathDefinition("/logout", "logout"); chainDefinition.addPathDefinition("/admin/**", "authc"); return chainDefinition; } ``` ## 影响版本 - Apache Shiro < 1.5.1 ## 漏洞复现 进入靶场环境,启动容器 ```txt root@ubuntu:~/vulhub/shiro# cd CVE-2020-1957/ root@ubuntu:~/vulhub/shiro/CVE-2020-1957# docker compose up -d ```  抓取数据包,直接访问admin路径,会发现跳转到登录页面  访问login.html文件  构造特殊路径绕过认证: ```txt /xxx/..;/admin/ ```   ## 修复建议 - 升级版本
毛林
2026年11月15日 18:41
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~