CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

admin 2022年6月28日21:51:59评论81 views字数 5093阅读16分58秒阅读模式

更多全球网络安全资讯尽在邑安全

一、漏洞分析

这篇文章对认证绕过的分析比较简单,因为关键部分就在对正则模式的绕过。
主要花较多的篇幅在spring的高低版本对业务的转发上。可以选择对自己感兴趣的部分进行阅读。
如有错误请多多指出!

1、漏洞成因

因为 RegexRequestMatcher 正则表达式处理的特性,导致可能某些需要认证的 Servlet 被绕过。影响版本如下:

  • 5.5.x prior to 5.5.7

  • 5.6.x prior to 5.6.4

  • Earlier unsupported versions

补丁中新增了 Pattern.DOTALL (0x20 可以在源码中看到注释),默认情况下正则表达式 . 不会匹配换行符,设置了 Pattern.DOTALL 模式后,才会匹配所有字符包括换行符。这里把dotall模式的注解和谷歌翻译贴在下面。

Enables dotall mode.
In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators.
Dotall mode can also be enabled via the embedded flag expression (?s). (The s is a mnemonic for "single-line" mode, which is what this is called in Perl.)

启用dotall模式。

在dotall模式下,表达式。匹配任何字符,包括行终止符。默认情况下,此表达式与行终止符不匹配。

也可以通过嵌入的标志表达式(?s)启用Dotall模式。(s是“单行”模式的助记符,在Perl中就是这样称呼的。)

可以考虑在 URL 中加入换行符( r 或 n )来绕过正则表达式匹配。
/admin/..;/*** 。而Spring Security 存在 StrictHttpFirewall 过滤机制,默认会过滤特殊字符:
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

2、环境搭建

在这里直接将pom文件提供给大家。测试springboot所使用的环境是2.7.0。在一开始使用2.5.3环境的时候,会遇到路由转发的问题,导致404。后面会详细把代码贴出来。

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version> //这个版本一定要高 </parent>

<groupId>org.example</groupId>
<artifactId>springsecurity</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring-security.version>5.6.3</spring-security.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- web模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies></project>

实现WebSecurityConfigurerAdapter添加需要认证的接口。

package start.security;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configurationpublic class SecurityDemo extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity.authorizeRequests().regexMatchers("/admin/.*","/admin2").authenticated();
}}

admin接口和admin2接口。

import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class SecAdminController {

@GetMapping("/admin/*")
public String admin(){
return "hello Admin";
}}

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class NewController {

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

3、调试分析

其实关键点就在于如何对url进行校验。

进入org.springframework.security.web.util.matcher.RegexRequestMatcher#matches方法中。

request.getServletPath() -->对字符解码 并且会将;之后的字符到/字符删除
request.getRequestURI() -->原样输出

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
所以在校验的时候会产生认证的绕过:
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

4、如何转发到对应业务

Spring-boot 2.7.0

从过滤器走出之后,可以看下面的调用栈,要进行服务功能的执行,分发器(Dispatcher)要选择相应的处理器进行选择。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

org.springframework.web.servlet.DispatcherServlet#getHandler
所有映射的内容放在了注册中心处。

RequestMappingInfoHandlerMapping继承org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
在他的方法上下断点getHandlerInternal

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
虽然这里会移除分号,但是在spring security前面就会被过滤的。这里是spring-web-mvc的组件
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

这里的返回值是lookupPath是没有被解码的,可以正常映射到/admin/*的路径上。
感兴趣的后面也可以跟一下。在匹配上之后就是选择对应路径的方法进行反射调用,唤醒业务逻辑部分代码。

Spring-boot 2.5.3

切换版本至2.5.3 先把这个版本下的结果公布一下:
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

选择对应的版本后进行调试,直接在前面分析的部分下断点。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
这里的lookupPath会将%0a解码,导致映射不到对应的路由上面。
所以跟进initLookupPath里面,看看他是如何获取的。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

在上面的方法返回的时候,走进了org.springframework.web.util.UrlPathHelper#decodeAndCleanUriString,在decodeRequestString那行将url解码返回了。导致路由映射不到相应的handler。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

这里是直接从directPath里面寻找。先匹配directPath再去匹配带有通配符的path,所以path分配的优先级在这里就可以体现。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

然后在对应所有的path里面去寻找相应的匹配。到这里可以看到,我们前面分析的其实都白费了= = 。最终去匹配的竟然还是request对象。好的 那我们进入这个方法重新开始。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

具体的代码逻辑可以看这里面这个方法org.springframework.util.AntPathMatcher#doMatch
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

跟到最后面会发现非常有意思的是,springcore在进行路由匹配的时候也是使用相同的pattern的模式,导致路由也无法匹配上。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

我把RegexRequestMatcher的Pattern和用于路由选择匹配的Pattern放在一起,他们使用同一种flag为0的模式,导致n字符无法被匹配上,至此首尾呼应,完结撒花!
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

最后找不到对应的handler就会出现404
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

二、加上参数的情况

import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class NewController {

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

可以看到这里的逻辑也存在一些问题会导致认证被绕过。将参数拼接之后并与需要校验认证的路径进行对比,导致认证被绕过。
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

三、 如何在路径上修复-单行模式

其实这个问题也可以说是开发人员在路径匹配的时候,没有加正确的匹配模式导致的。我们将路径改为

/admin/(?s).*

@Configurationpublic class SecurityDemo extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity.authorizeRequests().regexMatchers("/admin/(?s).*","/admin2").authenticated();
}}

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

这样业务逻辑就不会被绕过了。

原文来自: xz.aliyun.com

原文链接: https://xz.aliyun.com/t/11473

欢迎收藏并分享朋友圈,让五邑人网络更安全

CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

欢迎扫描关注我们,及时了解最新安全动态、学习最潮流的安全姿势!


推荐文章

1

新永恒之蓝?微软SMBv3高危漏洞(CVE-2020-0796)分析复现

2

重大漏洞预警:ubuntu最新版本存在本地提权漏洞(已有EXP) 



原文始发于微信公众号(邑安全):CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月28日21:51:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析http://cn-sec.com/archives/1137475.html

发表评论

匿名网友 填写信息