发布于12月5日12月5日 ## 1 SpringSecurity di0xide@深蓝攻防实验室天选团队 ## 1.1 前言 SpringSecurity是Java开发中非常常用的库,用于身份验证、授权、安全等功能。在我们的白盒测试中,我们可以分析代码是否使用了SpringSecurity来发现是否存在绕过权限的漏洞。本文将介绍SpringSecurity中一些常见的权限绕过漏洞。 这是CHATGPT对SpringSecurity库的介绍 ## 1.2 antMatchers配置不当绕过权限 ### 1.2.1 功能说明 antMatchers() 是Spring Security 中用于匹配请求路径的方法。它基于Ant风格的路径匹配规则。在Spring Security 中,antMatchers() 通常用于定义需要安全配置的URL 模式。 简单来说,antMatchers()是一个匹配路由的函数。当后续的路由匹配时,就会找到对应的权限规则。 ```` ?匹配任何单个字符 * 匹配0个或多个字符 ** 匹配0个或多个目录 ```` 示例: ```` antMatchers(\'/admin/**\').access(\'hasRole('ADMIN')\') ```` 含义:当访问的路由为/admin/**时,需要当前权限为ADMIN 示例: ```` antMatchers(“/js/**”).permitAll() ```` 意思是:释放js目录下的所有文件,无需权限验证。 示例: ```` antMatchers("/**/*.js").permitAll() ```` 也可以这样写,意思是释放所有js ### 1.2.2 存在漏洞代码 ```` 包com.example.springsecdemo2.demos; 导入org.springframework.context.annotation.Bean; 导入org.springframework.context.annotation.Configuration; 导入org.springframework.security.config.annotation.web.builders.HttpSecurity; 导入org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 导入org.springframework.security.core.userdetails.User; 导入org.springframework.security.core.userdetails.UserDetails; 导入org.springframework.security.provisioning.InMemoryUserDetailsManager; 导入org.springframework.security.web.SecurityFilterChain; @配置 @EnableWebSecurity 公共类antMatchersConfig { @豆子 公共SecurityFilterChain securityFilterChain(HttpSecurity http)抛出异常{ http .csrf().disable() .authorizeRequests() .antMatchers(\'/admin\').access(\'hasRole('ADMIN')\') .antMatchers(\'/**\').permitAll(); 返回http.build(); } @豆子 公共InMemoryUserDetailsManager userDetailsService() { UserDetails 用户=User.withDefaultPasswordEncoder() .用户名(\'用户\') .password(\'密码\') .roles(\'用户\') .build(); 返回新的InMemoryUserDetailsManager(用户); } } ```` 这里使用antMatchers(\'/test\').access(\'hasRole('ADMIN')\') 。只有ADMIN可以访问test,但不遵循正常的写法: /test/**,所以可以利用/test/绕过/test的验证 对应控制器 ### 1.2.3绕过方法 http://127.0.0.1:8012/测试/ 正常情况: 访问/admin,提示403 访问/admin/,验证通过 ### 1.2.4 修复方法 可以使用 ```` mvcMatchers(“/test”).access(“hasRole(‘ADMIN’)”) ```` 或 ```` antMatchers(“/test/**”).access(“hasRole(‘ADMIN’)”) ```` ## 1.3 regexMatchers配置不当绕过权限 ### 1.3.1 功能说明 使用正则表达式进行匹配。 与antMatchers() 的主要区别在于参数。 antMatchers() 参数是ant 表达式,regexMatchers() 参数是正则表达式。 示例: ```` regexMatchers(".+[.]js").permitAll() ```` 任何以.js 结尾的内容都是允许的 示例: ```` regexMatchers(\'/manager.*?\').access(\'hasRole('ADMIN')\' ```` 以manager 开头的路由必须具有ADMIN 权限才能访问它们。 ### 1.3.2 存在漏洞代码 ```` 公共类AuthConfig { @豆子 公共SecurityFilterChain securityFilterChain(HttpSecurity http)抛出异常{ http .csrf().disable() .authorizeRequests() .regexMatchers(\'/manager\').access(\'hasRole('ADMIN')\') .regexMatchers(\'/**\').access(\'匿名\'); 马云惹不起马云马云惹不起马云马云惹不起马云马云惹不起马云马云惹不起马云马云惹不起马云 `` 意思是通过正则表达式匹配admin路由后,判断权限是否为ADMIN,但是正则表达式并没有写完整。攻击者可以使用/admin?或/admin/绕过权限验证 ### 1.3.3绕过方法 ```` http://127.0.0.1:8012/测试? http://127.0.0.1:8012/测试/ ```` 正常接入: 旁路: ### 1.3.4 修复方法 写出完整的正则表达式 ```` .regexMatchers(\'/manager.*?\').access(\'hasRole('ADMIN')\') ```` 除了上面两个老的匹配函数之外,目前官方正在推广requestMatcher函数来匹配路由,这样会更安全。 ## 1.4 useSuffixPatternMatch低版本权限绕过 ### 1.4.1 功能说明 当spring-webmvc版本=4.3.25时,suffixPatternMatch默认为True。 该方法决定是否启用后缀匹配。如果启用,映射到/users 的方法也可以匹配/users.*。 /users 和/user.* 是相等的。 网上说的是如果配置低于5.3那就是真的。经过测试5.2.15的代码,默认为False 5.0.4 也不起作用 经测试,需要满足条件:springboot=1.5.22.RELEASE 对应的mvc版本为=4.3.25 此时 ### 1.4.2 存在漏洞代码 当Spring MVC版本=4.3.25时,suffixPatternMatch默认为True。 新建项目,选择spring版本为低版本 然后修改pom.xml中的版本 ````html 属性 java.version1.8/java.version 项目.build.sourceEncodingUTF-8/project.build.sourceEncoding project.reporting.outputEncodingUTF-8/project.reporting.outputEncoding spring-boot.version1.5.22.RELEASE/spring-boot.version /属性 `` 然后就可以看到Spring MVC版本以及相关组件的版本=4.3.25 这种情况下,无论配置文件中怎么写路由验证,都会出现漏洞,例如: 场景一: 假设这里的/admin系列路由不允许访问 ```` 包com.example.springsecdemo2.demos.Controller; 导入org.springframework.stereotype.Controller; 导入org.springframework.web.bind.annotation.RequestMapping; 导入org.springframework.web.bind.annotation.RequestMethod; 导入org.springframework.web.bind.annotation.ResponseBody; @控制器 公共类AuthController { @RequestMapping(值={\'/admin\'}, 方法={RequestMethod.GET}) @ResponseBody 公共字符串管理(){ return \'你好管理员\'; } @RequestMapping(值={\'/test\'}, 方法={RequestMethod.GET}) @ResponseBody 公共字符串测试(){ 返回“你好测试”; } } ```` /admin 路由似乎没有问题,常规的绕过方法也不起作用。 但在较低版本(1.x)的springboot上仍然可以绕过,只需使用/admin即可。 ### 1.4.3绕过方法 http://127.0.0.1:8080/管理员.123456789 ### 1.4.4 修复方法 只需使用新版本即可 ## 1.5 CVE-2022-22978(正则表达式匹配器) | Http安全|控制器|绕行| | - | - | - | | .regexMatchers(\'/admin/.*\').access(\'hasRole('ADMIN')\') | /管理/API/| | | .regexMatchers(\'/admin/.*\').access(\'hasRole('ADMIN')\') | /管理/** | | ### 1.5.1 漏洞介绍 Spring Security是Spring家族中的一个安全管理框架。在某些版本中,当使用regexMatchers 来匹配路由时,会调用RegexRequestMatcher()。但由于配置不正确,可以通过使用==.==来实现权限绕过。 **受影响的版本:** 春季安全5.6.x 5.6.4 春季安全5.5.x 5.5.7 春季安全5.4.x 5.4.11 **描述** 当然,这个漏洞有点没用,因为需要同时满足两个条件: 1、配置permissions config时,一般情况下都会匹配/admin/.*之后的所有路由,必须使用regexMatchers()进行正则匹配 2、Controller代码中,只有/admin/**这种匹配所有路径的语法才能生效。如果/admin/upload是硬编码的,这是无法绕过的,因为即使绕过权限验证,程序也无法匹配路由。 这将绕过, 但是当访问硬编码的/admin/api时
创建帐户或登录后发表意见