一.Shiro介绍

Shiro 是一款轻量化的权限管理框架,能够较方便的实现用户验权,请求拦截等功能,同类型的框架是我们的 Spring Security ,相比之下 Spring Security 提供了更多的功能

Authentication:身份认证,验证用户是否拥有某个身份。
Authorization: 权限校验,验证某个已认证的用户是否拥有某个权限。确定“谁”可以访问“什么”。
Session Management:会话管理,管理用户登录后的会话。
Cryptography:加密,使用密码学加密数据,如加密密码。
Web Support:Web支持,能够比较轻易地整合到Web环境中。
Caching:缓存,对用户的数据进行缓存。
Concurrency:并发,Apache Shiro支持具有并发功能的多线程应用程序,也就是说支持在多线程应用中并发验证。
Testing:测试,提供了测试的支持。
Run as:允许用户以其他用户的身份来登录。
Remember me:记住我
一.CVE-2010-3863
漏洞描述:
在Apache Shiro 1.1.0以前的版本中,shiro 进行权限验证前未对url 做标准化处理,攻击者可以构造/、//、/./、/../ 等绕过权限验证

漏洞复现:
直接请求管理页面/admin,无法访问,将会被重定向到登录页面:

构造恶意请求/./admin,即可绕过权限校验,访问到管理页面:

二.CVE-2016-4437
漏洞原理:
Apache Shiro框架提供了记住我(RememberMe)的功能,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问。
Shiro对rememberMe的cookie做了加密处理,shiro在CookieRememberMeManaer类中将cookie中rememberMe字段内容分别进行序列化、AES加密、Base64编码操作。
在识别身份的时候,需要对Cookie里的rememberMe字段解密。根据加密的顺序,不难知道解密的顺序为:
1.获取rememberMe cookie
2.base64 decode
3.解密AES(加密密钥硬编码)
4.反序列化(未作过滤处理)
但是,AES加密的密钥Key被硬编码在代码里,意味着每个人通过源代码都能拿到AES加密的密钥。因此,攻击者构造一个恶意的对象,并且对其序列化,AES加密,base64编码后,作为cookie的rememberMe字段发送。Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。
因为在反序列化时,不会对其进行过滤,所以如果传入恶意代码将会造成安全问题
在 1.2.4 版本前,是默认ASE秘钥,Key: kPH+bIxk5D2deZiIxcaaaA==,可以直接反序列化执行恶意代码。
而在1.2.4之后,ASE秘钥就不为默认了,需要获取到Key才可以进行渗透
漏洞特征:
shiro反序列化的特征:在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段
登陆失败的话,不管勾选RememberMe字段没有,返回包都会有rememberMe=deleteMe字段
不勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有rememberMe字段
勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段,还会有rememberMe字段,之后的所有请求中Cookie都会有rememberMe字段

直接上工具
https://github.com/SummerSec/ShiroAttack2

命令执行

三.CVE-2020-1957
漏洞描述:
Apache Shiro 1.5.2之前版本中存在安全漏洞。攻击者可借助特制的请求利用该漏洞绕过身份验证。
Shiro框架通过拦截器功能来对用户访问权限进行控制,如anon, authc等拦截器。anon为匿名拦截器,不需要登录即可访问;authc为登录拦截器,需要登录才可以访问。Shiro的URL路径表达式为Ant格式,路径通配符*表示匹配零个或多个字符串,/*可以匹配/hello,但是匹配不到/hello/,因为*通配符无法匹配路径。假设/hello接口设置了authc拦截器,访问/hello会进行权限判断,但如果访问的是/hello/,那么将无法正确匹配URL,直接放行,进入到spring拦截器。spring中的/hello和/hello/形式的URL访问的资源是一样的,从而实现了权限绕过。
漏洞影响:
Apache Shiro < 1.5.2
Shiro拦截器:
Shiro框架通过拦截器功能来实现对用户访问权限的控制和拦截。Shiro中常见的拦截器有anon,authc等拦截器。
1.anon为匿名拦截器,不需要登录就能访问,一般用于静态资源,或者移动端接口
2.authc为登录拦截器,需要登录认证才能访问的资源。
用户可以在Shiro.ini编写匹配URL配置,将会拦截匹配的URL,并执行响应的拦截器。从而实现对URL的访问控制,URL路径表达式通常为ANT格式。如下配置,访问 /index.html主页的时候,Shiro将不会对其进行登录判断,anon拦截器不需要登录就能进行访问。而对于/user/xiaoming 等 /user/xiaogang等接口,authc拦截器将会对其进行登录判断,有登录认证才能访问资源。
[urls] /index.html = anon /user/** = authc
Shiro的URL路径表达式为Ant 格式,路径通配符支持 ? * ** 。
?:匹配一个字符 :匹配零个或多个字符串 *:匹配路径中的零个或多个路径
其中*表示匹配零个或多个字符串,/*可以匹配/hello,但匹配不到/hello/因为*通配符无法匹配路径。假设/hello接口设置了authc拦截器,访问/hello将会被进行权限判断,如果请求的URI为/hello/呢,/*URL路径表达式将无法正确匹配,放行。然后进入到spring(Servlet)拦截器,spring中/hello 形式和/hello/形式的URL访问的资源是一样的。

整个请求过程:
客户端请求URL: /xxx/..;/admin/
shrio 内部处理得到校验URL为 /xxx/.. 校验通过
springboot 处理 /xxx/..;/admin/ 最终请求 /admin/ 成功访问了后台请求.
漏洞原因:我们请求的URL在整个项目的传入传递过程。在使用了shiro的项目中,是我们请求的URL(URL1),进过shiro权限检验(URL2), 最后到springboot项目找到路由来处理(URL3)
漏洞的出现就在URL1,URL2和URL3 有可能不是同一个URL,这就导致我们能绕过shiro的校验,直接访问后端需要首选的URL。本例中的漏洞就是因为这个原因产生的。
1.首先我们直接访问”/admin/“,发现跳转到了登陆界面。

2.这时候构造“/xxx/..;/admin/”,发现成功登陆到后台。

四.550和721的区别
Shiro721介绍:
在Shiro550漏洞中,Cookie所使用的AES加密密钥为硬编码,所以我们可以构造恶意序列化数据并使用固定的AES密钥进行正确加密恶意序列发送给服务端,进而达到攻击的目的。但在该漏洞公布后,Shiro官方修复了这一漏洞,将AES密钥修改成了动态生成。也就是说,对于每一个Cookie,都是使用不同的密钥进行加解密的。
漏洞原理:
在Shiro721漏洞中,由于Apache Shiro cookie中通过 AES-128-CBC 模式加密的rememberMe字段存在问题,用户可通过Padding Oracle Attack来构造恶意的rememberMe字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行。
虽然使用Padding Oracle Attack可以绕过密钥直接构造攻击密文,但是在进行攻击之前我们需要获取一个合法用户的Cookie。
漏洞流程:
登录网站获取合法Cookie
使用rememberMe字段进行Padding Oracle Attack,获取intermediary
利用intermediary构造出恶意的反序列化密文作为Cookie
使用新的Cookie请求网站执行攻击
影响版本:
Apache Shiro <= 1.4.1
漏洞利用:
在Shiro550中,我们可以直接通过硬编码密钥直接生成攻击密文。但是Shiro721使用了动态密钥,无法直接获取密钥。但是仍然可以通过Padding Oracle Attack绕过密钥,直接生成攻击密文。
利用链和Shiro550类似,这里我们使用ShiroExploit.V2.51工具进行攻击测试。输入测试网址以及登录用户的Cookie
主要区别:
1、这两个漏洞主要区别在于Shiro550使用已知密钥碰撞,只要有足够密钥库(条件较低),不需要Remember Cookie
2、Shiro721的ase加密的key基本猜不到,系统随机生成,可使用登录后rememberMe去爆破正确的key值,即利用有效的RememberMe Cookie作为Padding Oracle Attack的前缀,然后精心构造 RememberMe Cookie 值来实现反序列化漏洞攻击,难度高
版本问题:
1、Shiro框架1.2.4版本之前的登录时默认是先验证"rememberMe" Cookie的值,而不是先进行身份验证,这也是Shiro550漏洞能够利用的原因之一,攻击者可以利用该漏洞通过伪造"rememberMe" Cookie的值来绕过Shiro框架的身份认证机制,从而实现未授权访问
2、Shiro框架1.2.4版本之后的登录时先进行身份验证,而不是先验证"rememberMe" Cookie的值,所以攻击者需要知道受害者已经通过登录验证,并且Shiro框架已经为受害者创建了一个有效的会话,以便攻击者可以利用该会话ID进行身份伪造并绕过Shiro框架的权限控制机制
配置环境
git clone https://github.com/3ndz/Shiro-721.git
cd Shiro-721/Docker
docker build -t shiro-721 . //不要忽略721后面的那个点,意为当前路径
docker run -p 8080:8080 -d shiro-721
这个docker镜像中存在的war包中的lib主要是Common-Collections3.2.2的,正好是漏洞修复了的版本,不存在可利用
的cc链。因此我们要下载一个Common-Collections3.1放至生成的docker对应的tomcat目录下。
docker cp /root/Common-Collections3.1.jar [dockerid]:/usr/local/tomcat/webapps/ROOT/WEB-INF/lib/Common-Collections3.1.jar
java -jar ysoserial.jar CommonsCollections1 "touch /tmp/1.txt" > payload.class
利用公开exp使用Padding Oracle方式爆破payload的密文
python shiro_exp.py http://192.168.1.8:8080/account [rememberMeCookie] payload.class
五.拓展
漏洞原因:
AES加密算法的key是硬编码在源码中,当勾选了RememberMe,用户登陆成功后会生成经过加密并编码的cookie,在服务端接收cookie值后,Base64解码–>AES解密–>反序列化。攻击者只要找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化–>AES加密–>Base64编码,然后将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞
判断是否是Shiro框架:
当发送rememberMe=xxx过去,返回包会有set-cookie:rememberMe=deleteme
判断Key是否正确:
如果响应头的Set-Cookie字段包含rememberMe=deleteMe说明不是该密钥,如果什么都不返回,说明当前key是正确的key。实际中可能需要多次这样的请求来确认key
Shiro721:
需要用到PaddingOracleAttack技术,限制条件是需要已知合法用户的rememberMe且需要爆破较长的时间,也就是需要登录
shiro反序列化/流量特征:
•cookie传输
•响应头:Set-Cookie: rememberMe=deleteMe
•请求头: rememberMe=cookie
•Ase 加密
•550/721的利用 cookie 进行填充之后 很长
内存马查杀工具
https://github.com/Garck3h/killBehinderMemShell
-.-
评论区