• 简单看下最近的Spring Secrurity、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,实际调用:

    <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-securityartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency>

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

    @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((requests) -> requests .requestMatchers("/", "/index").permitAll() // 端点/、/index 无需鉴权,交给应用直接控制 .anyRequest().authenticated() ) .formLogin((form) -> form .loginPage("/login") .permitAll() ) .logout((logout) -> logout.permitAll()); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } }

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

    @GetMapping("/index") @ResponseBody public String index(){ // CVE-2024-22234 // 获取当前的认证对象 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); System.out.println(authentication); // 创建 AuthenticationTrustResolver 实例 AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); // 使用 isFullyAuthenticated 方法检查是否完全经过身份验证 boolean fullyAuthenticated = trustResolver.isFullyAuthenticated(authentication); // 传递null返回即为true String msg = ""; if (fullyAuthenticated) { msg = "用户已完全经过身份验证"; } else { msg = "用户可能是匿名用户或者仅部分经过身份验证"; } return msg; }

    复现

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

    image-20240227112713342

    进入登录页面正常登录后

    image-20240227113132942

    返回的页面为:

    image-20240227113142148

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

    boolean fullyAuthenticated = trustResolver.isFullyAuthenticated(null);

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

    ![image-20240227115847155](/Users/shellfeel/Library/Application Support/typora-user-images/image-20240227115847155.png)

    修复

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

    image-20240223151856512

    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匹配的正则表达式去掉[

    image-20240223175826813

    pre:

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

    now:

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

    环境搭建

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

    String url = "http://xxx.com"; UriComponents uriComponents = UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build(); String host = uriComponents.getHost(); System.out.println("userinfo: " + uriComponents.getUserInfo()); System.out.println("host: " + host); // 如果host为 evil.com 则会被拦截 if (host != null && host.equals("evil.com")) { System.out.println("403"); }else { System.out.println("pass"); }

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

    复现

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

    试下UriComponentsBuilder 可不可以:

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

    成功绕过:

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

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

    总结

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

    公众号

    家人们,欢迎关注我的公众号“硬核安全”,跟我一起学起来!

    欢迎关注


    __EOF__

    本文作者9eek
    本文链接https://www.cnblogs.com/9eek/p/18037571.html
    关于博主:评论和私信会在第一时间回复。或者直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    01-juc-入门概念
    京东店铺的所有商品API接口-(item_search_shop-获得店铺的所有商品接口),京东API接口
    leetcode-跳跃游戏系列
    项目管理VS项目治理,初级项目经理的你肯定弄混过
    Go基础——指针、结构体
    鸿蒙系统优缺点,能否作为开发者选择
    Spark面试题(二)
    《数据结构》八大排序(详细图文分析讲解)
    LCR 059.数据流中的第 K 大元素
    栈和队列oj题
  • 原文地址:https://www.cnblogs.com/9eek/p/18037571