CVE-2020-2555:WebLogic RCE漏洞分析

 

0x00 前言

不安全的反序列化漏洞已经逐渐成为攻击者/研究人员在面对Java Web应用时寻找的目标。这些漏洞通常能得到可靠的远程代码执行(RCE)效果,并且修复起来比较困难。在本文中,我们将分析CVE-2020-2555(ZDI-20-128)漏洞,该漏洞由来自VNPT ISC的Jang提交。这个漏洞级别较高(CVSS评分9.8),存在于Oracle Coherence库中,从而影响使用该库的Oracle WebLogic服务器等常见产品。官方在1月份修复了包括该漏洞在内的300多个漏洞。

 

0x01 补丁分析

漏洞根源存在于某个Java方法中,攻击者可以调用该方法,并且能控制相关参数。在Java中,当重新创建对象图时,类的readObject()readExternal()会被自动调用。因此,这两个方法(以及在方法内部可达的其他方法)可以被视为反序列化gadget的根源点。

CVE-2020-2555的补丁引入了非常有趣的一处修改,涉及LimitFilter类的toString()方法:

补丁在toString()中删除了对extract()方法的所有调用语句,下文中将重点分析extract()方法的重要性。这种修改操作非常有趣,因为我们可以通过各种标准的JRE类(如BadAttributeValueExpException)的readObject()方法,成功访问toString()方法。

如上图所示,经过序列化的BadAttributeValueExpException类实例可以用来调用任意类的toString()方法。这种技术可以用来访问受此补丁影响的LimitFilter类的toString()方法。

关于使用toString()作为入口点的gadget,大家可以参考ysoserial项目的CommonsCollections5 gadget.

 

0x02 寻找sink点

Sink点指的是具有各种副作用的Java方法调用,这类副作用包括:

1、通过调用FileOutputStream.write()实现任意文件创建;

2、通过调用Runtime.exec()实现任意命令执行;

3、通过调用Method.invoke()实现任意方法调用。

对于该漏洞,我们主要关注的是Method.invoke(),该调用能通过反射来调用任意Java方法。了解该信息后,我们开始查找具备extract()方法的所有实例(根据前文分析,该方法正是补丁分析后我们得出的根源点),并且最终会调用Method.invoke()。在Coherence库中,似乎只有一个可序列化类(实现Serializable或者Externalizable接口)实例满足条件。

观察ReflectionExtractor类后,我们可以进一步确认前面的猜测:

ReflectionExtractor提供了一种较为危险的操作原语,可以让攻击者调用任意方法,并且攻击者可以控制具体方法及相关参数。

 

0x03 实现RCE

通常情况下,攻击者需要调用多个方法才能实现RCE。比如,在常见的Apache Commons Collections gadget中,攻击者需要使用ChainedTransformer将任意方法调用串接起来,从而实现RCE。与此类似,Coherence库中也提供了这样一个类(ChainedExtractor),可以让我们串接extract()调用:

将以上信息结合起来,我们可以使用如下调用链,最终实现远程代码执行:

因此,如果有目标环境使用了Coherence库,并且攻击者可以投递恶意序列化对象,那么攻击者就能实现远程代码执行。为了演示攻击环境,这里我们以WebLogic的T3协议作为目标,具体操作过程可参考此处视频

 

0x04 总结

自从Chris Frohoff和Gabriel Lawrence在AppSecCali提出Java反序列化相关概念后,研究人员就一直在寻找反序列化漏洞,以实现可靠的代码执行。在针对SCADA应用的Pwn2Own Miami活动中,我们已经收到了多个这类报告,这也是我们在相关报告中特别关注反序列化问题的原因之一。

(完)