CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析
【推荐学习】暗月渗透测试培训 十多年渗透经验,体系化培训渗透测试 、高效学习渗透测试,欢迎添加微信好友aptimeok 咨询。
前几年 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 最新版仍然有效。
原创文章,作者:mOon,如若转载,请注明出处:https://www.moonsec.com/5313.html