安全矩阵

 找回密码
 立即注册
搜索
查看: 4951|回复: 0

CVE-2020-14756 漏洞利用以及分析

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2021-2-14 22:11:54 | 显示全部楼层 |阅读模式
原文链接:CVE-2020-14756 漏洞利用以及分析

0x01利用思路
weblogic的T3协议反序列化漏洞一直是一个比较热门也比较好用的漏洞,weblogic针对该漏洞的解决方案就是不断填充黑名单,在高版本jdk下配合jep290机制实现黑名单,在低版本下配合resolveClass进行防御,所以安全人员对于T3反序列化的利用也是一直在寻找黑名单之外的利用链。
CVE-2020-14756 这个漏洞的利用比较巧妙,通过利用weblogic coherence组件中的类,绕过了黑名单机制的检测,重新能够利用黑名单中的类,造成代码执行。

0x02漏洞分析
在weblogic的coherence.jar中,存在着一个比较特殊的接口com.tangosol.io.ExternalizableLite,他继承了Serializable接口。

readExternal和writeExternal方法

而ExternalizableLite接口的对象可以在com.tangosol.util.ExternalizableHelper里被序列化。

这里的nType是在writeObject写入的,是可控的

readExternalizableLite方法的具体内容为:
这里会加载传入的对象,对象需要是ExternalizableLite的实现类

这里直接调用class.forName还原对象

之后,会继续调用对象的readExternal方法,这样一来,后续的流程就绕过了ObjectInputStream对于对象的还原,而weblogic的黑名单检测也主要是针对ObjectInputStream的,所以,现在只需要找到后续的利用链就可以造成代码执行。
漏洞发现者使用了com.tangosol.util.aggregator.TopNAggregator.PartialResult这个类。这里会利用ExternalizableHelper还原m_comparator参数,是一个Comparator类型的对象。

然后调用了instantiateInternalMap方法,传入m_comparator

首先实例化SortedBag.WrapperComparator,赋值f_comparator,然后返回TreeMap对象

接着,调用add方法,在add方法里调用super.add,即SortedBag.add,继续调用put方法。

在put方法里,调用了compare方法

而这里又会调用WrapperComparator的compare方法

这个f_comparator就是之前已经赋值过的。

所以,最终的利用就在f_comparator这里,f_comparator从前面可以知道,需要是一个Comparator类型,这里使用的是 MvelExtractor 这是之前黑名单里的一个类,在CVE-2020-2555中有使用,不过现在我们不受黑名单的限制,MvelExtractor 没有compare方法。于是调用父类AbstractExtractor的compare方法。

然后又会调用子类MvelExtractor的extract方法。
序列化入口一
到现在我们的入口是TopNAggregator$PartialResult,他的readExternal(DataInput in)不是标准的readExternal(ObjectInput in),序列化的过程中是不会自动调用到该方法的,所以还需要找一个入口,这里作者发现了AttributeHolder。
这里不但会将ObjectInput转为DataInput,还会主动调用ExternalizableHelper.readObject。所以我们只需要m_oValue是TopNAggregator$PartialResult即可完成利用。

调用栈

序列化入口二
另外一个入口是com.tangosol.net.security.PermissionInfo,我们看他的readExternal方法,将输入流传入readCollection方法里,PermissionInfo是ExternalizableHelper的子类,所以这里PermissionInfo没有readCollection方法,直接调用其父类ExternalizableHelper的方法。

判断输入流类型之后,调用了readObject。
在调用readCollection的时候,将ObjectInput转为了DataInput

走到这里,就和之前的流程一模一样了。

调用栈


0x03 12.1.3版本问题
经测试,12.1.3 利用存在如下问题

从前面的分析可以知道,类的加载是在loadClass方法里,利用class.forName去加载类。

这里的loader就很关键了,决定了哪些类可以加载,哪些类没发加载,这里的loader是调用getContextClassLoader获得的一个线程上下文类加载器。

这里的线程上下文类加载器是默认的 AppClassLoader,在loaders里发现JarLoader加载了的coherence组件的依赖只有coherence.jar和coherence-web.jar,而MvelExtractor在coherence-rest.jar里,所以没有办法加载。


以下是一些尝试(未成功):
于是我这里先是考虑了另一个在黑名单的类,ReflectionExtractor,这个类在coherence.jar包下,不过在构造利用这个反射执行链的时候,需要反序列化Runtime.class对象,而Runtime.class对象不是ExternalizableLite的实现类,根据nType,在序列化的时候会调用readSerializeable方法

该方法还是会走ObjectInputStream的反序列化流程,即使是通过修改nType让他走readExternalizable,后面还是会有类型转换报错。

所以这样是不行的,12.1.3版本很多类都利用不了,比如RemoteConstructor、UniversalExtractor、LockVersionExtractor这些类在 12.1.3 版本中都没有,已知的利用链在 12.1.3 来说是没有办法进行利用的。

0x04官方修复之梅开二度

(补丁只能针对实现了jep290的jdk)
根据补丁来看:

对输入流的类型进行了判断,如果是ObjectInputStream,那么会去调用checkObjectInputFilter方法,方法如下:

这里会获取filter,在ExternalizableHelper的静态代码块里初始化了filter
首先会获取是否存在ObjectInputFilter,来判断jdk环境中是否存在jep290。

然后通过getObjectInputFilter/getInternalObjectInputFilter方法去获取serialFilter,之后,调用checkInput,对当前序列化的类进行检测。
不过,对于没有实现jep290的jdk版本而言,这个修补是没有作用的,因为低版本jdk不存在ObjectInputFilter,所以说filter参数就为null,也就是说checkObjectInputFilter方法直接返回true。

既然为true,那么还是能进行类的实例化。


END

【版权说明】本作品著作权归ob1t0所有,授权补天漏洞响应平台独家享有信息网络传播权,任何第三方未经授权,不得转载


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 18:00 , Processed in 0.014176 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表