1. 首页
  2. 渗透测试

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

漏洞信息

前几年 Apache Shiro 曾经爆出过多个认证绕过漏洞。而作为 Java 安全认证领域中另一个流行框架 Spring Security 看起来似乎更加安全。但是近日 Spring 官方通报了一个 Spring Security 框架的认证绕过漏洞 CVE-2022-22978 :

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

因为 `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` :

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

对正则表达式匹配规则进行了修改,查看重新定义的 `DEFAULT` 和 `CASE_INSENSITIVE` :

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

补丁中新增了 `Pattern.DOTALL` ,默认情况下正则表达式 `.` 不会匹配换行符,设置了 `Pattern.DOTALL` 模式后,才会匹配所有字符包括换行符。

`RegexRequestMatcher` 中通过 `matches` 对 URL 进行正则检查的代码如下:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

通过补丁对比很容易判断漏洞触发的原因,可以考虑在 URL 中加入换行符( `r` 或 `n` )来绕过正则表达式匹配。首先想到结合 `/admin/..;/***` 之类的方法来实现,但是 Spring Security 存在 `StrictHttpFirewall` 过滤机制,默认会过滤特殊字符:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

经过尝试,可以通过换行字符 URL 编码的方式,构造出一些实际漏洞应用场景。比如创建一个 `Controller` ,定义接口如下:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

在 Spring Security 中通过正则表达式添加认证配置:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

那么正常访问 `/admin/***` 是需要认证的:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

加入换行符:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

认证绕过:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

拓展分析

CVE-2022-22978 漏洞出现在 `RegexRequestMatcher` ,回顾 `RegexRequestMatcher#matches` 函数:

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过漏洞与利用场景分析

通过 `getServletPath` 获取 URL 之后,尝试提取 `?` 后面的 GET 参数并进行拼接,然后进行正则表达式匹配,如果应用存在如下接口:

@GetMapping("/admin2")
public String admin2()
 {    return "admin2";}

特定的认证规则定义下通过构造请求,也可实现认证绕过。这种绕过方式针对 Spring Security 最新版仍然有效。

原创文章,作者:mOon,如若转载,请注明出处:https://www.moonsec.com/5313.html

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息