Shiro身份验证绕过——CVE-2022-40664

1,212 阅读3分钟

Shiro身份验证绕过(CVE-2022-40664)

1、漏洞介绍

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。该组件于2022年10月13日Shiro官方发布1.10.0版本,最新版本之前存在身份验证绕过漏洞,编号CVE-2022-40664。

2、漏洞逆向审计

通过分析Github上的shiro官方仓库中的commit,来查看1.10.0版本与上一版本的代码变更情况。commit传送门:GitHub-Commit-Shiro

commit1.jpg

由于版本变更的代码较多,我们进行逐一的分析。

可以看以下为第一个业务逻辑更改,通过下图可以看出在调用GuiceShiroFilter方法时参数多加了一个ShiroFilterConfiguration对象,可以继续看commit中其他的类更改,均为增加了ShiroFilterConfiguration类对象。现在就明确追踪目标,向下追踪ShiroFilterConfiguration类对象的定义。

commit2.png

commit3.jpg

追踪到ShiroFilterConfiguration类,发现此类是1.10.0版本新增的代码,创建了isFilterOncePerRequest等方法,我们对注解进行翻译,内容如下:

*设置过滤器是每次请求执行一次,还是每次调用过滤器时执行一次。建议使用
*如果您正在使用{@link javax.servlet.RequestDispatcher RequestDisputcher}转发,请保持禁用状态
*或包含请求(JSP标记、编程方式或通过框架)。
*@param filterOncePerRequest此筛选器是否每个请求执行一次。

通过注解可以看出此次更新为禁用javax.servlet.RequestDispatcher RequestDisputcher(Java请求转发功能),可以看出此漏洞为Java请求转发绕过Shiro的过滤器从而达到身份绕过!

commit4.jpg

我们创建两个本地项目,并分别导入shiro1.7.0和shiro1.10.0,追一下代码区别。

commit5.jpg

可以看出在过滤器处,1.10.0多了个条件校验位filterOncePerRequest,追踪此参数。

commit6.jpg

此参数即为禁用javax.servlet.RequestDispatcher请求转发方法,这也证实了我们之前的猜测。

3、RequestDispatcher介绍

定义一个对象,从客户端接收请求并将其发送到服务器上的任何资源(例如servlet,HTML文件或JSP文件)。servlet容器创建RequestDispatcher对象,该对象用作位于特定路径或特定名称的服务器资源的包装。此接口旨在包装servlet,但servlet容器可以创建RequestDispatcher对象以包装任何类型的资源*。*

RequestDispatcher定义了两个方法分别为forward和include。

我们去追踪这两个方法,通过查看代码逻辑发现即使是shiro1.10.0在spring项目中也是默认不拦截forward和include方法的,在新版本中新增加了ShiroFilterConfiguration类,可以通过这个类来设置外部的过滤器来禁用forward和include方法。

4、漏洞复现

创建个Springboot项目并引入shiro1.7.0依赖,设计controller接口,一个为利用forward进行请求转发至另一个接口,而另一个接口为正常的身份验证接口,存在shiroFilter进行过滤,但这里只是利用shiro默认的设置,不对RequestDispatcher进行限制。

fuxian1.jpg

在外部过滤器中配置加白所有请求转发函数,保证我们接口中的forward可以正常转发。

fuxian2.jpg

下面我们请求第二个存在身份验证的接口,发现返回身份验证失败。

fuxian4.jpg

fuxian3.jpg

直接请求第一个接口发现可以直接绕过身份验证。

fuxian5.jpg

fuxian6.jpg

5、修复建议

升级shiro版本至1.10.0,且设计外部过滤器时,禁用所有请求转发的方法,示例代码如下:

xiufu1.jpg

6、参考链接

github.com/apache/shir…

blog.csdn.net/xyjy11/arti…

blog.csdn.net/weixin_3037…