目 录CONTENT

文章目录

Shiro 反序列化漏洞

Administrator
2024-12-08 / 0 评论 / 0 点赞 / 5 阅读 / 0 字

一.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访问的资源是一样的。

整个请求过程:

  1. 客户端请求URL: /xxx/..;/admin/

  2. shrio 内部处理得到校验URL为 /xxx/.. 校验通过

  3. 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

-.-

0

评论区