这篇文章将为大家详细讲解有关WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
琼海网站制作公司哪家好,找成都创新互联公司!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设等网站项目制作,到程序开发,运营维护。成都创新互联公司从2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联公司。
Oracle七月发布的安全更新中,包含了一个Weblogic的反序列化RCE漏洞,编号CVE-2020-14645,CVS评分9.8。
该漏洞是针对于CVE-2020-2883的补丁绕过,CVE-2020-2883补丁将MvelExtractor和ReflectionExtractor列入黑名单,因此需要另外寻找一个存在extract且方法内存在恶意操作的类,这里用到的类为com.tangosol.util.extractor.UniversalExtractor,存在于Coherence组件。
先来回顾一下CVE-2020-2883的两个poc调用链
//poc1 javax.management.BadAttributeValueExpException.readObject() com.tangosol.internal.sleepycat.persist.evolve.Mutations.toString() java.util.concurrent.ConcurrentSkipListMap$SubMap.size() java.util.concurrent.ConcurrentSkipListMap$SubMap.isBeforeEnd() java.util.concurrent.ConcurrentSkipListMap.cpr() com.tangosol.util.comparator.ExtractorComparator.compare() com.tangosol.util.extractor.ChainedExtractor.extract() com.tangosol.util.extractor.ReflectionExtractor().extract() Method.invoke() //... com.tangosol.util.extractor.ReflectionExtractor().extract() Method.invoke() Runtime.exec() //poc2 java.util.PriorityQueue.readObject() java.util.PriorityQueue.heapify() java.util.PriorityQueue.siftDown() java.util.PriorityQueue.siftDownUsingComparator() com.tangosol.util.extractor.AbstractExtractor.compare() com.tangosol.util.extractor.MultiExtractor.extract() com.tangosol.util.extractor.ChainedExtractor.extract() //... Method.invoke() //... Runtime.exec()
其本质上,都是通过ReflectionExtractor调用任意方法,从而实现调用Runtime对象的exec方法执行任意命令,但补丁现在已经将ReflectionExtractor列入黑名单,那么只能使用UniversalExtractor重新构造一条利用链,这里使用poc2的入口即CommonsCollections4链的入口进行构造。
为了方便一些纯萌新看懂,此处将会从0开始分析反序列化链(啰嗦模式警告),并且穿插一些poc构造时需要注意的点,先来看看调用栈。
从头开始跟进分析整个利用链,先来看看PriorityQueue.readObject()方法。
第792会执行for循环,将s.readObject()方法赋给queue对象数组,跟进heapify()方法。
这里会取一半的queue数组分别执行siftDown(i, (E) queue[i]);,实质上PriorityQueue是一个最小堆,这里通过siftDown()方法进行排序实现堆化,那么跟进siftDown()方法。
这里有个对于comparator的判定,我们暂时不考虑comparator的值是什么,接下来会使用到,我们先跟进siftDownUsingComparator()方法。
重点关注comparator.compare()方法,那么我们先来看看comparator是怎么来的。
是在PriorityQueue的构造函数中被赋值的,并且这里可以看到,queue对象数组也是在这里被初始化的。那么结合上述所分析的点,我们需要构造一个长度为2的queue对象数组,才能触发排序,进入siftDown()方法。同时还要选择一个comparator,这里选用ExtractorComparator。继续跟进ExtractorComparator.compare()方法。
这里将会调用this.m_extractor.extract()
方法,让我们看看this.m_extractor
是怎么来的。
可以看到,this.m_extractor的值是与传入的extractor有关的。这里需要构造this.m_extractor为ChainedExtractor,才可以调用ChainedExtractor的extract()方法实现串接extract()调用。因此,首先需要构造这样一个PriorityQueue对象:
PriorityQueue