Spring-security authorization bypass CVE-2022-22978 analysis

admin 2022年6月20日01:03:29安全漏洞评论30 views5071字阅读16分54秒阅读模式


Spring-security authorization bypass CVE-2022-22978 analysis


前言


Spring SecuritySpring 家族中的一个安全管理框架。在 Spring Security特定版本中存在一处身份认证绕过漏洞(CVE-2022-22978)。由于RegexRequestMatcher正则表达式配置权限的特性,当在Spring Security中使用RegexRequestMatcher且规则中包含带点号的正则表达式时,攻击者可以通过构造恶意数据包绕过身份认证


影响版本


Spring Security 5.5.x < 5.5.7
Spring Security 5.6.x < 5.6.4


环境构建


目录结构

Spring-security authorization bypass CVE-2022-22978 analysis

cc.saferoad.controller.Demo

package cc.saferoad.controller;
import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;
@RestControllerpublic class Demo { @GetMapping("/admin/*") public String Manage(){ return "Manage page"; }
@GetMapping("/") public String User(){ return "Hello bro"; }}


cc.saferoad.config.SpringSecurityConfig

自定义配置类

package cc.saferoad.config;
import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration@EnableWebSecuritypublic class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override protected void configure(HttpSecurity httpSecurity) throws Exception{ httpSecurity.authorizeRequests().regexMatchers("/admin/.*").authenticated(); }}

cc.saferoad.cve202222978.Cve202222978Application

package cc.saferoad.cve202222978;
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"cc.saferoad"})public class Cve202222978Application {
public static void main(String[] args) { SpringApplication.run(Cve202222978Application.class, args); }
}

cc.saferoad.cve202222978.RegexRequestMatcherTests

单元测试类,用于后面具体分析流程代码

package cc.saferoad.cve202222978;
import org.junit.jupiter.api.Test;import org.springframework.mock.web.MockHttpServletRequest;import org.springframework.security.web.util.matcher.RegexRequestMatcher;import static org.assertj.core.api.Assertions.assertThat;
public class RegexRequestMatcherTests {
@Test public void matchesWithLineFeed() { RegexRequestMatcher matcher = new RegexRequestMatcher(".*", null); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/blah%0d"); request.setServletPath("/blahr"); assertThat(matcher.matches(request)).isTrue(); }}

pom.xml

<?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 https://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>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <groupId>cc.saferoad</groupId>    <artifactId>CVE-2022-22978</artifactId>    <version>0.0.1-SNAPSHOT</version>    <packaging>war</packaging>    <name>CVE-2022-22978</name>    <description>CVE-2022-22978</description>    <properties>        <java.version>1.8</java.version>        <spring-security.version>5.6.3</spring-security.version>        <!--注意指定有漏洞的版本,覆盖掉默认版本-->    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <jvmArguments> -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8989 </jvmArguments> <!--远程调试配置,可忽略--> </configuration> </plugin> </plugins> </build>
</project>

配置完成后,启动SpringBoot应用.访问http://localhost:8080

Spring-security authorization bypass CVE-2022-22978 analysis

访问/admin/路由会提示403


Spring-security authorization bypass CVE-2022-22978 analysis


或者使用笔者构建的环境 https://github.com/DeEpinGh0st/CVE-2022-22978

漏洞复现

正常访问/admin/下任何路由均会提示403


Spring-security authorization bypass CVE-2022-22978 analysis


此时在/admin/anything路由中插入%0a或者%0d,即可绕过验证访问页面


Spring-security authorization bypass CVE-2022-22978 analysis


漏洞分析

使用上文中的单元测试样例,首先进行RegexRequestMatcher实例化

Spring-security authorization bypass CVE-2022-22978 analysis

根据构造参数初始化正则表达式及httpMethod属性,注意此处Pattern.compile参数值,对照JDK API文档看一下具体参数含义


Spring-security authorization bypass CVE-2022-22978 analysis


其中第一个参数表示要编译的表达式,而第二个参数则是指定表达式的具体匹配模式,具体可选值有

CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS and COMMENTS

RegexRequestMatcher中由于caseInsensitive设置为了false,所以此处的值为0 代表使用默认状态

随后进入RegexRequestMatcher:matches中在获取到传入的路由后进行路由匹配


Spring-security authorization bypass CVE-2022-22978 analysis


此处我们需要注意一个点

Spring-security authorization bypass CVE-2022-22978 analysis

在默认情况下正则表达式中的.是不会匹配rn换行符的,所以RegexRequestMatcher在进行正则匹配时不会处理rn从而可以绕过需要身份认证的页面


Spring-security authorization bypass CVE-2022-22978 analysis


修复

在清楚具体绕过原理后,来看一下官方提交的修复措施


Spring-security authorization bypass CVE-2022-22978 analysis


5.6.4的diff中官方将DEFAULT默认匹配模式改为了Pattern.DOTALL点阵模式


Spring-security authorization bypass CVE-2022-22978 analysis


在点阵模式下表达式会匹配rn等终止符,而在API文档中官方也进行了说明 默认情况下,此表达式与行终止符不匹配

而后也将Pattern.DOTALL在开启大小写区分的情况下进行了组合,这样无论是否开启大小写模式均使用点阵模式进行匹配

参考

JDK8 API(https://www.matools.com/file/manual/jdk_api_1.8_google/java/util/regex/Pattern.html#compile-java.lang.String-int-)

5.6.3...5.6.4 Diff(https://github.com/spring-projects/spring-security/compare/5.6.3...5.6.4)

Regexp-syntax(https://www.runoob.com/regexp/regexp-syntax.html)




商务合作(培训、渗透测试、咨询审计、CTF办赛出题)

Spring-security authorization bypass CVE-2022-22978 analysis


原文始发于微信公众号(黑伞安全):Spring-security authorization bypass CVE-2022-22978 analysis

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月20日01:03:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  Spring-security authorization bypass CVE-2022-22978 analysis http://cn-sec.com/archives/1078634.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: