百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

总结分析组件化漏洞产生的原理

ccwgpt 2025-01-04 17:57 103 浏览 0 评论

前言

Coherence 组件是 WebLogic 中的一个核心组件,内置在 WebLogic 中。关于 Coherence 组件的官方介绍:https://www.oracle.com/cn/java/coherence/

近些年,weblogic Coherence 组件反序列化漏洞被频繁爆出,苦于网上没有公开对 weblogic Coherence 组件历史反序列化漏洞的总结,导致很多想入门或者了解 weblogic Coherence 组件反序列化漏洞的朋友不知道该怎么下手,于是本文便对 weblogic Coherence 组件历史反序列化漏洞做出了一个总结和分析。

关于 Coherence 组件反序列化漏洞利用链的架构,我把他分为两个,一个是基于 ValueExtractor.extract 的利用链架构,另一个则是基于 ExternalizableHelper 的利用链架构。

前置知识

想理清 WebLogic 的 Coherence 组件历史反序列化漏洞需要首先了解一些 Coherence 组件反序列化漏洞中经常会涉及的一些接口和类。他们在 Coherence 组件反序列化漏洞利用中经常出现。

ValueExtractor

com.tangosol.util.ValueExtrator 是一个接口:

在 Coherence 中 很多名字以 Extrator 结尾的类都实现了这个接口:

这个接口中声明了一个 extract 方法,而 ValueExtractor.extract 正是 Coherence 组件历史漏洞( ValueExtractor.extract 链部分 )的关键。

ExternalizableLite

Coherence 组件中存在一个 com.tangosol.io.ExternalizableLite,它继承了 java.io.Serializable,另外声明了 readExternalwriteExternal 这两个方法。

com.tangosol.io.ExternalizableLite 接口 和 jdk 原生的 java.io.Externalizable 很像,注意不要搞混了。

ExternalizableHelper

上面提到的 com.tangosol.io.ExternalizableLite 接口的实现类的序列化和反序列化操作,都是通过 ExternalizableHelper 这个类来完成的。

我们可以具体看 ExternalizableHelper 这个类是怎么对实现 com.tangosol.io.ExternalizableLite 接口的类进行序列化和反序列化的,这里以 readObject 方法为例,writeObject 读者可自行去查看:

如果传入的DataInput 不是 PofInputStream 的话(Coherence 组件历史漏洞 涉及到的 ExternalizableHelper.readObject传入的 DataInput 都不是 PofInputStream),ExternalizableHelper#readObject 中会调用 ExternalizableHelper#readObjectInternal 方法:

readObjectInternal 中会根据传入的中 nType 进行判断,进入不同的分支:

对于实现 com.tangosol.io.ExternalizableLite 接口的对象,会进入到 readExternalizableLite 方法:

可以看到在 readExternalizableLite 中 1125 行会根据类名加载类,然后并且实例化出这个类的对象,然后调用它的 readExternal() 方法。

漏洞链

ValueExtractor.extract

我们在分析反序列化利用链的时候,可以把链分为四部分,一个是链头,一个是危险的中间的节点(漏洞点),另一个是调用危险中间节点的地方(触发点),最后一个则是利用这个节点去造成危害的链尾。

在 Coherence 组件 ValueExtractor.extract 利用链架构中,这个危险的中间节点就是 ValueExtractor.extract 方法。

漏洞点

ReflectionExtractor

ReflectionExtractor 中的 extract 方法含有对任意对象方法的反射调用:

配合 ChainedExtractorConstantExtractor 可以实现类似 cc1 中的 transform 链的调用。

涉及 CVE

CVE-2020-2555,CVE-2020-2883

MvelExtractor

MvelExtrator 中的 extract 方法,会执行任意一个 MVEL 表达式(RCE):

而在序列化和反序列化的时候 m_sExpr 会参与序列化和反序列化:

所以 m_xExpr 可控,所以就导致可以利用 MvelExtrator.extrator 来达到执行任意命令的作用。

涉及 CVE

CVE-2020-2883

UniversalExtractor

UniversalExtractor(Weblogic 12.2.1.4.0 独有) 中的 extract 方法,可以调用任意类中的的 getis 开头的无参方法,可以配合 jdbsRowset,利用 JDNI 来远程加载恶意类实现 RCE。

涉及 CVE

CVE-2020-14645,CVE-2020-14825 , CVE-2020-14841

LockVersionExtractor

oracle.eclipselink.coherence.integrated.internal.cache.LockVersionExtractor 中的 extract() 方法,可以调用任意 AttributeAccessorgetAttributeValueFromObject 方法,赋值 AccessorMethodAttributeAccessor 进而可以实现调用任意类的无参方法。

MethodAttributeAccessor.getAttributeValueFromObject,本质是利用MethodAttributeAccessor.getAttributeValueFromObject中存在任意无参方法调用,在 CVE-2021-2394 中也利用到了。

涉及 CVE

CVE-2020-14825 , CVE-2020-14841

FilterExtractor.extract

filterExtractor.extract 中存在任意 AttributeAccessor.getAttributeValueFromObject(obj) 的调用,赋值 this.attributeAccessor 为上面说的MethodAttributeAccessor 就可以导致任意无参方法的调用。

涉及 CVE

CVE-2021-2394

触发点

上面例举出了很多危险的 ValueExtractor.extract 方法,接下来再看看哪里存在调用 ValueExtractor.extract 方法的地方。

Limitfiler

Limitfiler 中 Limitfiler.toString 中存在任意 ValueExtractor.extract 方法调用:

由于 this.m_comparator 参与序列化和反序列化,所以可控:

我们只需要赋值 this.m_comparator 为 恶意的 ValueExtractor 就可以实现任意 ValueExtractor .extract 方法的调用。toString 方法,则可以利用 CC5 中用到的 BadAttributeValueExpException 来触发。

涉及 CVE

CVE-2020-2555

ExtractorComparator

ExtractorComparator.compare ,其实是针对 CVE-2020-2555 补丁的绕过,CVE-2020-2555 的修复方法中修改了 Limitfiler.toString 方法,也就是说修改了一个调用 ValueExtractor.extract 方法的地方。 而 CVE-2020-2883 则找到另一个调用 ValueExtractor.extract 的地方,也就是 ExtractorComparator.compare

ExtratorComparator.compare 中存在任意(因为 this.m_extractor 参与序列化和反序列化) ValueExtractorextract方法调用。

Comparator.compare 方法,则可以通过 CC2 中用到的PriorityQueue.readObject` 来触发。

另外在 weblogic 中, BadAttributeValueExpException.readObject 中也可以实现调用任意 compartor.compare方法:

涉及 CVE

CVE-2020-2883,修复方法是将 ReflectionExtractorMvelExtractor 加入了黑名单 。

CVE-2020-14645 使用 com.tangosol.util.extractor.UniversalExtractor 绕过,修复方法将 UniversalExtractor 加入黑名单。

CVE-2020-14825,CVE-2020-14841 使用 oracle.eclipselink.coherence.integrated.internal.cache.LockVersionExtractor.LockVersionExtractor 进行绕过。

ExternalizableHelper

在分析ExternalizableHelper 利用链架构的时候,我们依然可以把链分为四部分,一个是链头,一个是危险的中间的节点(漏洞点),另一个是调用危险中间节点的地方(触发点),最后一个则是利用这个节点去造成危害的链尾。

ExternalizableHelper 利用链架构中,这个危险的中间节点就是 ExternalizableLite.readExternal 方法。

weblogic 对于反序列化类的过滤都是在加载类时进行的,因此在 ExternalizableHelper.readExternalizableLite 中加载的 class 是不受黑名单限制的。

具体原因是:weblogic 黑名单是基于 jep 290 ,jep 290 是在 readObject 的时候,在得到类名后去检查要反序列化的类是否是黑名单中的类。而这里直接使用的 loadClass 去加载类,所以这里不受 weblogic 黑名单限制。(也可以这么理解: jep 290 是针对在反序列化的时候,通过对要加载类进行黑名单检查。而这里直接通过 loadClass 加载,并没有通过反序列化,和反序列化是两码事,当然在后续 readExternal 的时候还是受 weblogic 黑名单限制,因为走的是反序列化那一套)

漏洞点

PartialResult

com.tangosol.util.aggregator.TopNAggregator.PartialResultreadExternal 会触发任意 compartor.compare 方法。

大致原理:

在 182 行会把comparator 作为参数传入 TreeMap 的构造函数中。

然后186 行,会调用 this.add ,this.add 会调用 this.m_map.put 方法,也就是说调用了 TreeMap 的 put 方法,这就导致了 comparator.compare()的调用。

然后调用 comparator.compare 就可以接到 ExtractorComparator.compare 那里去了,从而实现 rce 。

涉及 CVE

CVE-2020-14756 (1月)

ExternalizableHelper 的利用第一次出现是在 CVE-2020-14756 中。利用的正是 ExternalizableHelper 的反序列化通过 loadClass 加载类,所以不受 weblogic 之前设置的黑名单的限制。

CVE-2020-14756 的修复方法则是对 readExternalizable 方法传入的 Datainput 检查,如果是 ObjectInputStream 就调用 checkObjectInputFilter() 进行检查,checkObjectInputFilter 具体是通过 jep290 来检查的。

CVE-2021-2135 (4月)

上面补丁的修复方案 只是检查了 DataInputObjectInputStream 的情况, 却没有过滤其他 DataInput 类型 。

那我们只需要找其他调用 readExternalizableit 函数的地方,并且传入的参数不是 ObjectInputStream 就可以了。【ObjectInputStream 一般是最常见的,通常来说是 readObject =>readObjectInternal =>readExternalizableite 这种链,也就是上游是常见的 readObject, 所以补丁就可能只注意到ObjectInputStream 的情况。】

所以CVE-2021-2135 绕过的方法就是设置传入 readExternalizableite 函数的参数类型为 BufferInput 来进行绕过。

ExternalizableHelper 中调用 readObjectInternal 的地方有两处,一处是 readObjectInternal , 另一处则是 deserializeInternal 。而 deserializeInternal 会先把 DataInput 转化为 BufferInut

所以只要找调用 ExternalizableHelper .deserializeInternal 的地方。

ExternalizableHelper.fromBinary (和 ExternalizableHelper.readObject 平级的关系 )里就调用了 deserializeInternal , 所以只需要找到一个地方用 来 ExternalizableHelper.fromBinary 来反序列化就可以接上后面的(CVE-2020-14756)利用链了。

然后就是找 调用了 ExternalizableHelper.fromBinary 的方法的地方。SimpleBinaryEntry 中的 getKeygetValue方法中存在 ExternalizableHelper.fromBinary 的调用,所以就只要找到调用 getKeygetValue 的地方就可以了。

然后在 com.sun.org.apache.xpath.internal.objects.XString重写的equals方法里调用了 tostring ,在 tostring 中调用了 getKey 方法。

ExternalizableHelper#readMap 中会调用 map.putmap.put 会调用 equals 方法。

com.tangosol.util.processor.ConditionalPutAllreadExteranl 中调用了 ExternalizableHelper#readMap 方法。

然后再套上 AttributeHolder 链头就可以了。

4月漏洞修复则是:

1.添加simpleBianry 到黑名单。

2.设置了白名单:

private static final Class[] ABBREV_CLASSES = new Class[]{String.class, ServiceContext.class, ClassTableEntry.class, JVMID.class, AuthenticatedUser.class, RuntimeMethodDescriptor.class, Immutable.class};

filterExtractor

filterExtractor.reaExternal 方法中的 readAttributeAccessor() 方法会直接 new 一个 MethodAttributeAccessor 对象。

随后在 filterExtractor.extract 函数中会因为调用 this.attributeAccessor.getAttributeValueFromObject 进而导致任意无参方法的调用。

涉及 CVE

CVE-2021-2394 (4月)

在4月的补丁中,对 ois 的 DataInput 流进行了过滤,所以直接通过 newInstance 实例化恶意类的方式已经被阻止(CVE-2021-2135 通过 bufferinputStream 进行了绕过),所以需要重新寻找其他不在黑名单中的 readExternal 方法。

CVE-2021-2394 中就是利用 filterExtractor.readExternal 来进行突破。

触发点

ExternalizableHelper.readExternal 的触发点有 ExternalizableHelper.readObjectExternalizableHelper.fromBinary这两个。其中 CVE-2021-2135 则就是因为在 CVE-2020-14756 的修复方法中,只注意到了 ExternalizableHelper.readObject ,只在ExternalizableHelper.readObject 里面做了限制,但是没有考虑到 ExternalizableHelper.fromBinary 从而导致了绕过。

ExternalizableHelper.readObject可以利用 com.tangosol.coherence.servlet.AttributeHolder来触发,com.tangosol.coherence.servlet.AttributeHolder 实现了 java.io.Externalizabe 接口,并且他的readExternal 方法 调用了 ExternalizableHelper.readObject(in)

ExternalizableHelper.fromBinary 的触发则较为复杂一些

后记

weblogic Coherence 反序列化漏洞很多都是相关联的,对于某个漏洞,很可能就是用到了之前一些漏洞的链子。其实不仅仅 weblogic ,java 其他反序列化链也是如此,很多情况都是一个链会用到其他链的一部分。所以在学习中,把一个组件或者一个库的漏洞总结起来一起分析还是比较重要的,最后希望这篇文章能帮助到其他一起学反序列化的朋友们。

相关推荐

自己动手写Android数据库框架_android开发数据库搭建

http://blog.csdn.net/feiduclear_up/article/details/50557590推荐理由关于Android数据库操作,由于每次都要自己写数据库操作,每次还得去...

谷歌开源大模型评测工具LMEval,打通谷歌、OpenAI、Anthropic

智东西编译|金碧辉编辑|程茜智东西5月28日消息,据科技媒体TheDecoder5月26日报道,当天,谷歌正式发布开源大模型评测框架LMEval,支持对GPT-4o、Claude3.7...

工信部:着力推动大模型算法、框架等基础性原创性的技术突破

工信部新闻发言人今日在发布会上表示,下一步,我们将坚持突出重点领域,大力推动制造业数字化转型,推动人工智能创新应用。主要从以下四个方面着力。一是夯实人工智能技术底座。通过科技创新重大项目,着力推动大模...

乒乓反复纠结“框架不稳定”的三个小误区

很多球友由于对框架的认知不清晰,往往会把“框架不稳定”当成一种心理负担,从而影响学球进度,其典型状态就是训练中有模有样,一旦进入实战,就像被捆住了手脚。通过训练和学习,结合“基本功打卡群”球友们交流发...

前AMD、英特尔显卡架构师Raja再战GPU,号称要全面重构堆栈

IT之家8月5日消息,知名GPU架构师拉贾科杜里(RajaKoduri)此前曾先后在AMD和英特尔的显卡部门担任要职。而在今日,由Raja创立的GPU软件与IP初创企...

三种必须掌握的嵌入式开发程序架构

前言在嵌入式软件开发,包括单片机开发中,软件架构对于开发人员是一个必须认真考虑的问题。软件架构对于系统整体的稳定性和可靠性是非常重要的,一个合适的软件架构不仅结构清晰,并且便于开发。我相...

怪不得别人3秒就知道软考案例怎么做能50+

软考高级统一合格标准必须三科都达到45分,案例分析也一直是考生头疼的一门,但是掌握到得分点,案例能不能50+还不是你们说了算吗?今天就结合架构案例考点,分享实用的备考攻略~一、吃透考点,搭建知识框架从...

UML统一建模常用图有哪些,各自的作用是什么?一篇文章彻底讲透

10万+爆款解析:9大UML图实战案例,小白也能秒懂!为什么需要UML?UML(统一建模语言)是软件开发的“蓝图”,用图形化语言描述系统结构、行为和交互,让复杂需求一目了然。它能:降低沟通成本避...

勒索软件转向云原生架构,直指备份基础设施

勒索软件组织和其他网络犯罪分子正越来越多地将目标对准基于云的备份系统,对久已确立的灾难恢复方法构成了挑战。谷歌安全研究人员在一份关于云安全威胁演变的报告中警告称,随着攻击者不断改进数据窃取、身份泄露和...

ConceptDraw DIAGRAM:释放创意,绘就高效办公新未来

在当今数字化时代,可视化工具已成为提升工作效率和激发创意的关键。ConceptDrawDIAGRAM,作为一款世界顶级的商业绘图软件,凭借其强大的功能和用户友好的界面,正逐渐成为众多专业人士的首选绘...

APP 制作界面设计教程:一步到位_app界面设计模板一套

想让APP界面设计高效落地,无需繁琐流程,掌握“框架搭建—细节填充—体验优化”三步法,即可一步到位完成专业级设计。黄金框架搭建是基础。采用“三三制布局”:将屏幕横向三等分,纵向保留三...

MCP 的工作原理:关键组件_mcp部件

以下是MCP架构的关键组件:MCP主机:像ClaudeDesktop、GitHubCopilot或旅行助手这样的AI智能体,它们希望通过MCP协议访问工具、资源等。MCP主机会...

软件架构_软件架构师工资一般多少

软件架构师自身需要是程序员,并且必须一直坚持做一线程序员。软件架构应该是能力最强的一群程序员,他们通常会在自身承接编程任务的同时,逐渐引导整个团队向一个能够最大化生产力的系统设计方向前进。软件系统的架...

不知不觉将手机字体调大!老花眼是因为“老了吗”?

现在不管是联系、交友,还是购物,都离不开手机。中老年人使用手机的时间也在逐渐加长,刷抖音、看短视频、发朋友圈……看手机的同时,人们也不得不面对“视力危机”——老花眼,习惯眯眼看、凑近看、瞪眼看,不少人...

8000通用汉字学习系列讲座(第046讲)

[表声母字]加(续)[从声汉字]伽茄泇迦枷痂袈笳嘉驾架咖贺瘸(计14字)嘉[正音]标准音读jiā。[辨形]上下结构,十四画。会意形声字,从壴从加,加也表声。注:从壴,字义与鼓乐有关;从加,字义与...

取消回复欢迎 发表评论: