5

Weblogic CVE-2016-3510 MarshalledObject反序列化绕过分析

 3 years ago
source link: https://y4er.com/post/weblogic-cve-2016-3510/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
2 min read

Weblogic CVE-2016-3510 MarshalledObject反序列化绕过分析

2020-02-12

Weblogic系列文章,还是绕过黑名单。

https://github.com/5up3rc/weblogic_cmd 修改payload类型

image

成功执行命令,断点同样下在InvokerTransformer的transform(),堆栈如下。

transform:123, InvokerTransformer (org.apache.commons.collections.functors)
transform:122, ChainedTransformer (org.apache.commons.collections.functors)
get:157, LazyMap (org.apache.commons.collections.map)
invoke:50, AnnotationInvocationHandler (sun.reflect.annotation)
entrySet:-1, $Proxy57
readObject:327, AnnotationInvocationHandler (sun.reflect.annotation)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:39, NativeMethodAccessorImpl (sun.reflect)
invoke:25, DelegatingMethodAccessorImpl (sun.reflect)
invoke:597, Method (java.lang.reflect)
invokeReadObject:974, ObjectStreamClass (java.io)
readSerialData:1848, ObjectInputStream (java.io)
readOrdinaryObject:1752, ObjectInputStream (java.io)
readObject0:1328, ObjectInputStream (java.io)
readObject:350, ObjectInputStream (java.io)
readResolve:58, MarshalledObject (weblogic.corba.utils)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:39, NativeMethodAccessorImpl (sun.reflect)
invoke:25, DelegatingMethodAccessorImpl (sun.reflect)
invoke:597, Method (java.lang.reflect)
invokeReadResolve:1061, ObjectStreamClass (java.io)
readOrdinaryObject:1761, ObjectInputStream (java.io)
readObject0:1328, ObjectInputStream (java.io)
readObject:350, ObjectInputStream (java.io)
readObject:69, InboundMsgAbbrev (weblogic.rjvm)
read:41, InboundMsgAbbrev (weblogic.rjvm)
readMsgAbbrevs:283, MsgAbbrevJVMConnection (weblogic.rjvm)
init:215, MsgAbbrevInputStream (weblogic.rjvm)
dispatch:498, MsgAbbrevJVMConnection (weblogic.rjvm)
dispatch:330, MuxableSocketT3 (weblogic.rjvm.t3)
dispatch:394, BaseAbstractMuxableSocket (weblogic.socket)
readReadySocketOnce:960, SocketMuxer (weblogic.socket)
readReadySocket:897, SocketMuxer (weblogic.socket)
processSockets:130, PosixSocketMuxer (weblogic.socket)
run:29, SocketReaderRequest (weblogic.socket)
execute:42, SocketReaderRequest (weblogic.socket)
execute:145, ExecuteThread (weblogic.kernel)
run:117, ExecuteThread (weblogic.kernel)

用的common-collection1,MarshalledObject 在 (weblogic.corba.utils) 中 WEB-INF\lib\weblogic.jar!\weblogic\corba\utils\MarshalledObject.class

同样是绕过黑名单,将反序列化的对象封装进了weblogic.corba.utils.MarshalledObject,然后再对MarshalledObject进行序列化,生成payload字节码。由于MarshalledObject不在WebLogic黑名单里,可正常反序列化,在反序列化时MarshalledObject对象调用readObject时对MarshalledObject封装的序列化对象再次反序列化,可以绕过黑名单的限制。

看下weblogic_cmd中如何构造的

image

handler是构造的cc对象,进入BypassPayloadSelector.selectBypass()

image

根据TYPE决定使用什么来构造payload,跟进到marshalledObject(payload)

image

将构造的cc对象封装进MarshalledObject对象marshalledObject,然后return,进入Serializables.serialize(_handler)

image

拿到序列化对象的字节码数组,然后通过t3协议发送出去,后面不在解释。

总的来说,就是将cc对象封装进MarshalledObject,MarshalledObject不在黑名单中,那么执行他的readObject()就可以触发cc链。

再来看下weblogic在哪触发的readObject(),断到MarshalledObject.class的48行。

image

这里的readObject()触发反序列化,怎么进入到readResolve()这个方法的?查看堆栈进入invokeReadResolve()

image

这里通过反射调用var1也就是MarshalledObject对象的readResolve()方法。var1中包含了我们恶意的序列化数据,它怎么传进来的?

进入堆栈中readOrdinaryObject()

private Object readOrdinaryObject(boolean var1) throws IOException {
    if (this.bin.readByte() != 115) {
        throw new InternalError();
    } else {
        ObjectStreamClass var2 = this.readClassDesc(false);
        var2.checkDeserialize();

        Object var3;
        try {
            var3 = var2.isInstantiable() ? var2.newInstance() : null;
        } catch (Exception var6) {
            throw (IOException)(new InvalidClassException(var2.forClass().getName(), "unable to create instance")).initCause(var6);
        }

        this.passHandle = this.handles.assign(var1 ? unsharedMarker : var3);
        ClassNotFoundException var4 = var2.getResolveException();
        if (var4 != null) {
            this.handles.markException(this.passHandle, var4);
        }

        if (var2.isExternalizable()) {
            this.readExternalData((Externalizable)var3, var2);
        } else {
            this.readSerialData(var3, var2);
        }

        this.handles.finish(this.passHandle);
        if (var3 != null && this.handles.lookupException(this.passHandle) == null && var2.hasReadResolveMethod()) {
            Object var5 = var2.invokeReadResolve(var3);
            if (var1 && var5.getClass().isArray()) {
                var5 = cloneArray(var5);
            }

            if (var5 != var3) {
                var3 = var5;
                this.handles.setObject(this.passHandle, var5);
            }
        }

        return var3;
    }
}

在这里调用了invokeReadResolve(),参数var3在上文经过this.readClassDesc().newInstance()拿到传入t3协议的MarshalledObject对象,具体做了什么处理不深入研究。

t3传入MarshalledObject对象 -> readOrdinaryObject() 拿到MarshalledObject对象 -> invokeReadResolve() 反射调用MarshalledObject对象的readResolve() -> readObject()触发cc反序列化。

  1. jdk最好用1.6的,不然总是定位不到正确的函数。
  2. https://www.cnblogs.com/afanti/p/10240232.html

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK