shiro漏洞及原理

shiro是什么

Apache Shiro框架是一个功能强大且易于使用的 Java 安全框架,它执行身份验证、授权、加密和会话管理。借助 Shiro 易于理解的 API,您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。

shiro的漏洞原理

Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会将用户信息加密,加密过程:用户信息=>序列化=>AES加密=>base64编码=>RememberMe Cookie值。如果用户勾选记住密码,那么在请求中会携带cookie,并且将加密信息存放在cookie的rememberMe字段里面,在服务端收到请求对rememberMe值,先base64解码然后AES解密再反序列化,这个加密过程如果我们知道AES加密的密钥,那么我们把用户信息替换成恶意命令,就导致了反序列化RCE漏洞。在shiro版本<=1.2.4中使用了默认密钥kPH+bIxk5D2deZiIxcaaaA==,这就更容易触发RCE漏洞。
所以我们Payload产生的过程:
命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值

Shiro服务器识别身份加解密处理的流程

(1)加密

1.用户使用账号密码进行登录,并勾选”Remember Me”。

2、Shiro验证用户登录信息,通过后,查看用户是否勾选了”Remember Me“。

3、若勾选,则将用户身份序列化,并将序列化后的内容进行AES加密,再使用base64编码。

4、最后将处理好的内容放于cookie中的rememberMe字段。

(2)解密

1、当服务端收到来自未经身份验证的用户的请求时,会在客户端发送请求中的cookie中获取rememberMe字段内容。

2、将获取到的rememberMe字段进行base64解码,再使用AES解密。

3、最后将解密的内容进行反序列化,获取到用户身份。

(3)Key

AES加密的密钥Key被硬编码在代码里

于是可得到Payload的构造流程:

恶意命令–>序列化–>AES加密–>base64编码–>发送Cookie

漏洞验证

未登录的情况下,请求包的cookie中没有rememberMe字段,返回包set-Cookie里也没有deleteMe字段
登录失败的话,不管有没有勾选RememberMe字段,返回包都会有 rememberMe= deleteMe 字段
不勾选RememberMe,登录成功的话,返回包set-Cookie里有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有RememberMe字段
勾选RememberMe,登录成功的话,返回包set-Cookie里有rememberMe=deleteMe字段,还会有remember 字段,之后的所有请求中Cookie都会有rememberMe字段
或者可以在cookie后面自己加一个rememberMe=1,看返回包有没有rememberMe= deleteMe

Shiro-550反序列化漏洞

shiro-550主要是由shiro的rememberMe内容反序列化导致的命令执行漏洞,造成的原因是默认加密密钥是硬编码在shiro源码中,任何有权访问源代码的人都可以知道默认加密密钥。于是攻击者可以创建一个恶意对象,对其进行序列化、编码,然后将其作为cookie的rememberMe字段内容发送,Shiro 将对其解码和反序列化,导致服务器运行一些恶意代码。

特征:cookie中含有rememberMe字段

Shiro-721反序列化漏洞

漏洞介绍

在Shiro721中,Shiro通过AES-128-CBC对cookie中的rememberMe字段进行加密,所以用户可以通过PaddingOracle加密生成的攻击代码来构造恶意的rememberMe字段,进行反序列化攻击,需要执行的命令越复杂,生成payload需要的时间就越长。

shrio550和721的区别

主要区别在于Shiro550使用已知默认密码,只要有足够的密码,不需要Remember Cookie的
Shiro721的ase加密的key为系统随机生成,需要利用登录后的rememberMe去爆破正确的key值。
利用有效的RememberMe Cookie作为Padding Oracle Attack的前缀,再去构造反序列化攻击。

漏洞指纹

URL中含有Shiro字段

cookie中含有rememberMe字段

返回包中含有rememberMe