CVE-2020-2555 Weblogic RCE

前言

WebLogic 对于 T3 协议和 IIOP 协议的处理,天然就会进行反序列化的漏洞点。因此,对于 WebLogic 反序列化漏洞的挖掘,主要就是在 gadget 的寻找和补丁绕过上。
2020年的1月、4月和7月, WebLogic 先后爆出了三个一脉相承的反序列化 CVE,涉及了七个 gadget

CVE-2020-2555主要源于在coherence.jar存在着用于gadget构造的类(反序列化构造类)并且利用weblogic默认存在的T3协议进行传输和解析进而导致weblogic服务器反序列化恶意代码最后执行攻击语句。
所以这里就直接去找coherence.jar包中的gadget

漏洞影响范围:

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),通过调试发现该版本默认并未启用 Coherence,所以 Weblogic 10.3.6.0 不在受影响范围内。

漏洞原理

1
2
3
4
5
6
7
8
gadget:
BadAttributeValueExpException.readObject()
com.tangosol.util.filter.LimitFilter.toString()
com.tangosol.util.extractor.ChainedExtractor.extract()
com.tangosol.util.extractor.ReflectionExtractor.extract()
Method.invoke()
...
Runtime.getRuntime.exec()
1
2
3
4
5
ReflectionExtractor#extract -> method.invoke(oTarget, this.m_aoParam);
ChainedExtractor#extract -> aExtractor[i].extract(oTarget);
LimitFilter#toString -> .append(extractor.extract(...)...);
BadAttributeValueExpException#readObject() -> valObj.toString();
`->`是调用的意思

com.tangosol.util.extractor.ReflectionExtractor

ReflectionExtractor类的exctract方法,可以看到通过传输一个oTarget对象,通过findMethod反射来获取oTarget对象指定参数的方法,将其赋值给m_methodPrev字段,然后最后进行method.invoke方法调用
1
试着执行一下:
2
结果如预期。现在还需要一个方法执行ReflectionExtractor#extract()

com.tangosol.util.extractor.ChainedExtractor

发现ChainedExtractorextract方法可以实现链式调用
3
ChainedExtractor中传入ReflectionExtractor数组对象,然后通过ChainedExtractor对象的extract方法进行链式调用
试着执行一下:
4
结果如预期。现在还需要一个方法执行ChainedExtractor#extract()

com.tangosol.util.filter.LimitFilter

直接看toString,可以看到其中的extractor.extract(this.m_oAnchorTop)有进行调用
5
继续看extractor.extract(this.m_oAnchorTop)中的m_oAnchotTop,可以看到变量可控,那么就可以替换为Runtime.class来进行执行命令

1
2
3
4
5
6
Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
m_comparator.setAccessible(true);
m_comparator.set(limitFilter, chainedExtractor);
Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop");
m_oAnchorTop.setAccessible(true);
m_oAnchorTop.set(limitFilter, Runtime.class);

6
这里需要注意下,因为ChainedExtractor是实现了Comparator接口的。
此时需要一个方法触发LimitFilter#toString()

BadAttributeValueExpException

BadAttributeValueExpException的反序列化会调用指定对象的toString方法
7
此时利用链完成。
8

POC建议全用反射来进行赋值,要不然会有问题

这篇文章介绍了另外两条链,但是我在coherence-3.7.1.jar中没有找到MvelExtractor类。
文章使用 MvelExtractor 替换掉利用链的ChainedExtractorReflectionExtract
使用MultiExtractor 作为连接第一条利用链中 LimitFilter.toString()ChainedExtractor.extract() 的桥梁。LimitFilter.toString() 间接通过 MultiExtractor.extract() 调用到 ChainedExtractor.extract() 中。

9

修复方案

Oracle 打在了 LimitFilter.toString() 函数里。Oracle官方提供的CVE-2020-2555补丁中将LimitFilter类的toString()方法中的extract()方法调用全部移除了。

这个修复很神奇,仅仅封锁了三条调用链的入口,而从 MultiExtractor.extract() 经过 ChainedExtractor.extract() 调用到 ReflectionExtractor.extract() 的利用链、以及MvelExtractor.extract() 的利用链依然存在,只要再找一个入口就好了。

后面的CVE-2020-2883CVE-2020-14645都是对相应修复的绕过。
可参考githubgithub

后两个漏洞复现过程挺迷的,过程都知道了,但是环境一言难尽。

Reference

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2555
https://www.yaowendao.com/2020/09/06/%E4%BB%8EWebLogic%E4%B8%80%E8%84%89%E7%9B%B8%E6%89%BF%E7%9A%84%E4%B8%89%E4%B8%AA%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96CVE%E8%AF%B4%E8%B5%B7/
https://www.cnblogs.com/zpchcbd/p/15629063.html
https://xz.aliyun.com/t/7387