Shiro
初识shiro
Shiro是一种java安全框架,用于身份验证,会话管理,授权,加密,shiro灵活性强,全面,低耦合灵活性强易于扩展,支持web,被广泛的使用。
Shiro用途
1 验证用户身份
2 用户访问控制,比如用户是否被赋予了某个角色;是否允许访问某些资源
3 在任何环境都可以使用Session API,即使不是WEB项目或没有EJB容器
4 事件响应(在身份验证,访问控制期间,或是session生命周期中)
5 集成多种用户信息数据源
6 SSO-单点登陆
7 Remember Me,记住我
8 Shiro尝试在任何应用环境下实现这些功能,而不依赖其他框架、容器或应用服务器。
漏洞
反序列化漏洞
影响版本:shiro<1.2.5,但升级后也未必安全
原理
使用shiro框架,用户在登录成功后会生成一个经过加密的cookie,其key值为rememberMe,Value的值是经过序列化,AES、Base64编码后得到的结果,服务器在接收到cookie时,会按照如下步骤进行解析处理:
1 检索RememberMe Cookie的值
2 进行base64解码
3 进行AES解码
4 反序列化
若在第四步反序列化中未进行充分的过滤,就可能导致远程代码执行的漏洞。
由于使用了AES加密,成功利用该漏洞需要获取AES的加密密钥,在Shiro1.2.4版本之前AES的加密密钥为硬编码,其默认密钥的Base64编码后的值为kPH+bIxk5D2deZiIxcaaaA==,于是就可得到Payload的构造流程:
恶意命令-->序列化-->AES加密-->base64编码-->发送Cookie
目前官方通过去掉硬编码的密钥是的每次生成一个密钥来解决其漏洞,但可以通过搜索引擎等方式收集到不同的密钥,提高对该漏洞的利用成功率。
指纹
响应包中存在字段set-Cookie: rememberMe=deleteMe
防护
由于漏洞利用的核心在于获取AES的加密密钥,因此解决的核心在于对密钥的保护,可将版本升级为1.2.5及以上,自己生成密钥,一定不能使用默认或网络上的密钥,做好对密钥的保护。
权限绕过(CVE-2020-1957)
影响版本:shiro<1.5.2
原理:
Shiro框架使用拦截器对用户访问权限进行控制,常见的有如anon、authc等拦截器。
anon拦截器为匿名拦截器,无需登陆即可进行访问,一般用于静态资源。authc为登陆拦截器,需要登陆才可以访问。
用户可以在Shiro.ini编写匹配URL配置,将会拦截匹配的URL,并执行响应的拦截器。从而实现对URL的访问控制,URL路径表达式通常为ANT格式。即访问/index时无需登陆,而访问/user/test时需要登陆认证。
#Shiro.ini
/index = anon
/user/** = authc
------
Ant格式:
?:匹配一个字符
*:匹配零个或多个字符串
**:匹配路径中的零个或多个路径
这里的/**可以匹配路径,即可以匹配到/user/test/,而/*只能匹配到单个或多个字符串,即/user/test。那么假设配置内改为:/user/* = authc,则可以匹配到/user/test但无法匹配到/user/test/(多了个斜杆),那么就会放行/user/test/。然后进入到Spring(Servlet)拦截器中,对于Spring,上述两个路径都是一致的,于是就造成了权限绕过。
防护
1 更新shiro版本至1.5.2及以上
2 尽量避免使用*通配符作为动态路由拦截器的URL路径表达