网站首页 > 技术文章 正文
前言
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,另外声明了 readExternal 和 writeExternal 这两个方法。
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 方法含有对任意对象方法的反射调用:
配合 ChainedExtractor 和 ConstantExtractor 可以实现类似 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 方法,可以调用任意类中的的 get 和 is 开头的无参方法,可以配合 jdbsRowset,利用 JDNI 来远程加载恶意类实现 RCE。
涉及 CVE
CVE-2020-14645,CVE-2020-14825 , CVE-2020-14841
LockVersionExtractor
oracle.eclipselink.coherence.integrated.internal.cache.LockVersionExtractor 中的 extract() 方法,可以调用任意 AttributeAccessor 的
getAttributeValueFromObject 方法,赋值 Accessor 为 MethodAttributeAccessor 进而可以实现调用任意类的无参方法。
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 参与序列化和反序列化) ValueExtractor 的 extract方法调用。
Comparator.compare 方法,则可以通过 CC2 中用到的PriorityQueue.readObject` 来触发。
另外在 weblogic 中,
BadAttributeValueExpException.readObject 中也可以实现调用任意 compartor.compare方法:
涉及 CVE
CVE-2020-2883,修复方法是将 ReflectionExtractor 和 MvelExtractor 加入了黑名单 。
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.PartialResult 的 readExternal 会触发任意 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月)
上面补丁的修复方案 只是检查了 DataInput 为 ObjectInputStream 的情况, 却没有过滤其他 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 中的 getKey 和 getValue方法中存在
ExternalizableHelper.fromBinary 的调用,所以就只要找到调用 getKey 和 getValue 的地方就可以了。
然后在
com.sun.org.apache.xpath.internal.objects.XString重写的equals方法里调用了 tostring ,在 tostring 中调用了 getKey 方法。
ExternalizableHelper#readMap 中会调用 map.put ,map.put 会调用 equals 方法。
com.tangosol.util.processor.ConditionalPutAll 的 readExteranl 中调用了 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.readObject 和
ExternalizableHelper.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 其他反序列化链也是如此,很多情况都是一个链会用到其他链的一部分。所以在学习中,把一个组件或者一个库的漏洞总结起来一起分析还是比较重要的,最后希望这篇文章能帮助到其他一起学反序列化的朋友们。
猜你喜欢
- 2025-07-23 完全零基础入门Fastjson系列漏洞(fastjson远程代码漏洞)
- 2025-07-23 安全研究 | 如何有效保护Weblogic服务器免受CVE-2023-21839攻击
- 2025-07-23 Unity的游戏数据存储(unity游戏数据文件)
- 2025-07-23 Java单向代码执行链配合的动态代码上下文执行
- 2025-07-23 4款让人骄傲的国产软件,只因功能强大,被误认为是外国人开发
- 2024-10-25 续:Oracle数据库中几种很有用的非典型函数(二)
- 2024-10-25 oracle expdp导出数据处理方法 oracle11g expdp导出
- 2024-10-25 分享一份生产环境PG数据库定时备份脚本,值得收藏
- 2024-10-25 数据管理与应用试题库 数据管理与应用专业好就业吗
- 2024-10-25 S、X、IS、IX数据库锁机制 很详细的教程,简单易懂
你 发表评论:
欢迎- 624℃几个Oracle空值处理函数 oracle处理null值的函数
- 616℃Oracle分析函数之Lag和Lead()使用
- 605℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 601℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 596℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 589℃【数据统计分析】详解Oracle分组函数之CUBE
- 577℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 565℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- 国产化红利到底在哪?好多人都在瞎折腾
- Oracle 推出 Java 24,增强 AI 支持和后量子加密
- JAVA桥接模式适用场景,优缺点是什么你知道吗,这篇文章彻底讲透
- SpringBoot条件化配置(@Conditional)全面解析与实战指南
- Navicat Data Modeler使用教程十二:配置
- 软件测试|数据库的内连接,左连接,右链接分别是什么
- 每日学习“IT”是什么呢?(每日学习每日一词)
- SQLite:小众?其实它比你想象的更普及,连这个领域都有人用!
- 【推荐】一款实用且跨平台的数据库管理神器,支持Web浏览器
- Spring Batch中的JobRepository:批处理的“记忆大师”是如何工作
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)