简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)


最近的这两个cve我看国内很多情报将其评为高危,所以想着去看看原理,看完发现都比较简单,利用要求的场景也相对有限(特别是第一个),所以就随便看下就行了

Spring Security 用户认证绕过(CVE-2024-22234)

先看下官网的公告(https://spring.io/security/cve-2024-22234)

In Spring Security, versions 6.1.x prior to 6.1.7 and versions 6.2.x prior to 6.2.2, an application is vulnerable to broken access control when it directly uses the AuthenticationTrustResolver.isFullyAuthenticated(Authentication) method.

Specifically, an application is vulnerable if:

  • The application uses AuthenticationTrustResolver.isFullyAuthenticated(Authentication) directly and a null authentication parameter is passed to it resulting in an erroneous true return value.

An application is not vulnerable if any of the following is true:

  • The application does not use AuthenticationTrustResolver.isFullyAuthenticated(Authentication) directly.

  • The application does not pass null to AuthenticationTrustResolver.isFullyAuthenticated

  • The application only uses isFullyAuthenticated via Method Security or HTTP Request Security

大概意思是直接调用 `AuthenticationTrustResolver.isFullyAuthenticated(Authentication) ,若Authentication为null,则方法会永远返回真,从而产生一些与预期相反的结果。

AuthenticationTrustResolver 接口中的 isFullyAuthenticated 方法用于检查 Authentication 对象是否完全经过身份验证,即是否不是匿名用户。在 Spring Security 中,可以使用这个方法来确定用户是否已经进行了完整的身份验证。

影响版本为:

  • 6.1.0 to 6.1.6

  • 6.2.0 to 6.2.1

环境搭建

引入pom,实际调用:

  1. <dependency>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-starter-security</artifactId>

  4. </dependency>

  5. <dependency>

  6. <groupId>org.springframework.boot</groupId>

  7. <artifactId>spring-boot-starter-web</artifactId>

  8. </dependency>

  9. <dependency>

  10. <groupId>org.springframework.boot</groupId>

  11. <artifactId>spring-boot-starter-test</artifactId>

  12. <scope>test</scope>

  13. </dependency>

增加下密码验证和/index的无鉴权的配置(交给应用手动配置)

  1. @Configuration

  2. @EnableWebSecurity

  3. public class WebSecurityConfig {

  4. @Bean

  5. public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

  6. http

  7. .authorizeHttpRequests((requests) -> requests

  8. .requestMatchers("/", "/index").permitAll() // 端点/、/index 无需鉴权,交给应用直接控制

  9. .anyRequest().authenticated()

  10. )

  11. .formLogin((form) -> form

  12. .loginPage("/login")

  13. .permitAll()

  14. )

  15. .logout((logout) -> logout.permitAll());

  16. return http.build();

  17. }

  18. @Bean

  19. public UserDetailsService userDetailsService() {

  20. UserDetails user =

  21. User.withDefaultPasswordEncoder()

  22. .username("user")

  23. .password("password")

  24. .roles("USER")

  25. .build();

  26. return new InMemoryUserDetailsManager(user);

  27. }

  28. }

新增控制器并配置需要用户手动输入密码( isFullyAuthenticated)后才能访问的逻辑:

  1. @GetMapping("/index")

  2. @ResponseBody

  3. public String index(){

  4. // CVE-2024-22234

  5. // 获取当前的认证对象

  6. Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

  7. System.out.println(authentication);

  8. // 创建 AuthenticationTrustResolver 实例

  9. AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();

  10. // 使用 isFullyAuthenticated 方法检查是否完全经过身份验证

  11. boolean fullyAuthenticated = trustResolver.isFullyAuthenticated(authentication); // 传递null返回即为true

  12. String msg = "";

  13. if (fullyAuthenticated) {

  14. msg = "用户已完全经过身份验证";

  15. } else {

  16. msg = "用户可能是匿名用户或者仅部分经过身份验证";

  17. }

  18. return msg;

  19. }

复现

正常情况下,如果没有经过认证,返回的页面为:

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

进入登录页面正常登录后

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

返回的页面为:

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

如果开发在某些情况,比如手动清除 SecurityContextHolder中的 Authentication信息或通过异步处理导致在异步线程中没有可用的信息 getAuthentication()返回 null, 则会导致认证校验的失效,我们这里为了复现就手动置为null,

  1. boolean fullyAuthenticated = trustResolver.isFullyAuthenticated(null);

重启应用,在不登陆的情况下,重新访问 /index ,发现isFullyAuthenticated已经直接返回了true 。访问鉴权后的页面

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

修复

修复方式也比较简单在 isFullyAuthenticated 中增加了对authentication对象为空的判断

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

Spring Framework SSRF or open redirect( CVE-2024-22243)

Applications that use UriComponentsBuilder to parse an externally provided URL (e.g. through a query parameter) AND perform validation checks on the host of the parsed URL may be vulnerable to a open redirect attack or to a SSRF attack if the URL is used after passing validation checks.

这个看官网描述只知道使用UriComponentsBuilder这个方法来做host校验,会导致重定向和ssrf,粗看下源码不知道是怎么回事,看了下代码更新记录,很简单只是将uri匹配中userinfo匹配的正则表达式去掉 [

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

pre:

  1. private static final String USERINFO_PATTERN = "([^@\[/?#]*)";

now:

  1. private static final String USERINFO_PATTERN = "([^@/?#]*)";

环境搭建

这里假设存在一个场景,后端会将用户输入的url交给 UriComponentsBuilder进行验证,通过后进行正常的访问,后端有个简单的黑名单host判断(evil.com) :

  1. String url = "http://xxx.com";

  2. UriComponents uriComponents = UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build();

  3. String host = uriComponents.getHost();

  4. System.out.println("userinfo: " + uriComponents.getUserInfo());

  5. System.out.println("host: " + host);

  6. // 如果host为 evil.com 则会被拦截

  7. if (host != null && host.equals("evil.com")) {

  8. System.out.println("403");

  9. }else {

  10. System.out.println("pass");

  11. }

简单场景,排除使用302、ip、rebind等方式,单纯从UriComponentsBuilder来进行绕过有什么办法?

复现

一般情况下我们知道绕过ssrf会用到 @,如果url为 http://[email protected] ,部分的host校验库会识别这个url Host为A.com,而浏览器或者http client实际会访问B.com 利用这种差异就能绕过部分黑名单限制,直接访问恶意网站。

试下 UriComponentsBuilder可不可以:

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

很明显,在这个方法中,直接这么用是不行的,但根据漏洞的修复删除的正则表达式符号来看,我们在userinfo最后增加一个 [,测试一下

成功绕过:

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

不过这样绕过后大部分情况下不能直接使用原url进行访问,因为url中存在 [ 会让程序报错:

简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

所以更多利用场景我猜可能是使用 UriComponentsBuilder取的host重新进行url拼接来进行访问

总结

Spring Security中这个漏洞可能对于实战利用不大,因为黑盒测未授权都能测试出来不需要什么用户可控的绕过姿势,相对而言Spring Framework这个在实战中对于url可控的地方增加 xxx[@yyy.com 可能会有奇效。


原文始发于微信公众号(硬核安全):简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243)

版权声明:admin 发表于 2024年2月27日 下午6:34。
转载请注明:简单看下最近的Spring Secrutity、Spring漏洞(CVE-2024-22234、CVE-2024-22243) | CTF导航

相关文章