前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring-security authorization bypass CVE-2022-22978 analysis

Spring-security authorization bypass CVE-2022-22978 analysis

作者头像
黑伞安全
发布2022-09-03 09:38:15
1.1K0
发布2022-09-03 09:38:15
举报
文章被收录于专栏:黑伞安全

前言

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

环境构建

目录结构

cc.saferoad.controller.Demo

代码语言:javascript
复制
package cc.saferoad.controller;

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

@RestController
public class Demo {
    @GetMapping("/admin/*")
    public String Manage(){
        return "Manage page";
    }

    @GetMapping("/")
    public String User(){
        return "Hello bro";
    }
}

cc.saferoad.config.SpringSecurityConfig

自定义配置类

代码语言:javascript
复制
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
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception{
        httpSecurity.authorizeRequests().regexMatchers("/admin/.*").authenticated();
    }
}

cc.saferoad.cve202222978.Cve202222978Application

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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("/blah\r");
        assertThat(matcher.matches(request)).isTrue();
    }
}

pom.xml

代码语言:javascript
复制
<?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

访问/admin/路由会提示403

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

漏洞复现

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

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

漏洞分析

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

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

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

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

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

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

此处我们需要注意一个点

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

修复

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

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

在点阵模式下表达式会匹配\r\n等终止符,而在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)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑伞攻防实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 影响版本
      • 环境构建
        • 漏洞复现
          • 漏洞分析
            • 修复
              • 参考
              相关产品与服务
              远程调试
              远程调试(Remote Debugging,RD)在云端为用户提供上千台真实手机/定制机/模拟器设备,快速实现随时随地测试。运用云测技术对测试方式、操作体验进行了优化,具备多样性的测试能力,包括随时截图和记录调试日志,稳定的支持自动化测试, 设备灵活调度,用例高效执行, 快速定位产品功能和兼容性问题。云手机帮助应用、移动游戏快速发现和解决问题,节省百万硬件费用,加速敏捷研发流程。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档