★且听安全★-点关注,不迷路!
★漏洞空间站★-优质漏洞资源和小伙伴聚集地!
前几年 Apache Shiro 曾经爆出过多个认证绕过漏洞。而作为 Java 安全认证领域中另一个流行框架 Spring Security 看起来似乎更加安全。但是近日 Spring 官方通报了一个 Spring Security 框架的认证绕过漏洞 CVE-2022-22978 :
因为 `RegexRequestMatcher` 正则表达式处理的特性,导致可能某些需要认证的 `Servlet` 被绕过。影响版本如下:
-
5.5.x prior to 5.5.7
-
5.6.x prior to 5.6.4
-
Earlier unsupported versions
新建一个 SpringBoot 工程,引入 Spring Security 。由于 Spring Boot 提供了 Maven BOM 来管理依赖版本,因此默认状态下无需指定 Spring Security 版本,为了方便漏洞调试,我们需要覆盖默认版本,可以通过添加 Maven 属性的方式来修改 Spring Security 版本。
首先对比 5.6.4 及 5.6.3 版本的 `RegexRequestMatcher.java` :
对正则表达式匹配规则进行了修改,查看重新定义的 `DEFAULT` 和 `CASE_INSENSITIVE` :
补丁中新增了 `Pattern.DOTALL` ,默认情况下正则表达式 `.` 不会匹配换行符,设置了 `Pattern.DOTALL` 模式后,才会匹配所有字符包括换行符。
`RegexRequestMatcher` 中通过 `matches` 对 URL 进行正则检查的代码如下:
通过补丁对比很容易判断漏洞触发的原因,可以考虑在 URL 中加入换行符( `r` 或 `n` )来绕过正则表达式匹配。首先想到结合 `/admin/..;/***` 之类的方法来实现,但是 Spring Security 存在 `StrictHttpFirewall` 过滤机制,默认会过滤特殊字符:
经过尝试,可以通过换行字符 URL 编码的方式,构造出一些实际漏洞应用场景。比如创建一个 `Controller` ,定义接口如下:
在 Spring Security 中通过正则表达式添加认证配置:
那么正常访问 `/admin/***` 是需要认证的:
加入换行符:
认证绕过:
CVE-2022-22978 漏洞出现在 `RegexRequestMatcher` ,回顾 `RegexRequestMatcher#matches` 函数:
通过 `getServletPath` 获取 URL 之后,尝试提取 `?` 后面的 GET 参数并进行拼接,然后进行正则表达式匹配,如果应用存在如下接口:
public String admin2() {
return "admin2";
}
特定的认证规则定义下通过构造请求,也可实现认证绕过。这种绕过方式针对 Spring Security 最新版仍然有效。
有兴趣获取完整漏洞分析与复现过程的小伙伴,请加入我们的漏洞空间站-致力于打造优质漏洞资源和小伙伴聚集地!
由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,且听安全团队及文章作者不为此承担任何责任。
★且听安全★-点关注,不迷路!
★漏洞空间站★-优质漏洞资源和小伙伴聚集地!
原文始发于微信公众号(且听安全):CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析