Weblogic ChainedExtractor葫芦兄弟漏洞分析(CVE-2020-2555、CVE-2020-2883)

2020-09-02 5,503

简介

2020年Oracle Weblogic发布了包含编号为CVE-2020-2555、CVE-2020-2883漏洞的CPU。

CVE-2020-2555和CVE-2020-2883漏洞的相似性非常高,均使用T3协议,均利用核心的ChainedExtractor类进行攻击,CVSS 3.0均达到9.8,均能完成远程任意命令执行。


环境

漏洞环境:

  • java version "1.8.0_112"

  • WebLogic 12.2.1.4.0

  • IDEA DEBUG


攻击

使用Y4er师傅基于weblogic_cmd修改的支持T3协议WebLogic攻击框架:

https://github.com/Y4er/CVE-2020-2555

CVE-2020-2555可以直接使用该框架进行攻击,CVE-2020-2883需要单独新增一个攻击模块,攻击模块来源Y4er师傅:

https://github.com/Y4er/CVE-2020-2883

导入IDEA:

image-20200901155740113.png

因为会使用到weblogic中的jar包,所以添加lib到本地项目中:

image-20200901155902124.png

WebLogic 12.2.1.4.0可以使用攻击框架项目自带的,其他的版本最好使用和目标版本一致的,可以从WebLogic提取。

coherence.jar的位置

/Users/rai4over/Oracle/Middleware/Oracle_Home/wlserver/server/lib/console-ext/autodeploy/coherence.jar

wlfullclient.jar需要手动生成

java -jar ~/Oracle/Middleware/Oracle_Home/wlserver/modules/com.bea.core.jarbuilder.jar

运行后在会生成wlfullclient.jar,路径为:

~/Oracle/Middleware/Oracle_Home/wlserver/server/lib/wlfullclient.jar

替换攻击框架中lib中的jar即可。


调试

Weblogic开启远程调试:

vim /root/Oracle/Middleware/user_projects/domains/base_domain/bin/setDomainEnv.sh

添加配置代码:

debugFlag="true"
export debugFlag

image-20200716123537882-8947866.png

Middleware目录下提取全部的jarwar包到test目录。

cd /Users/rai4over/Desktop/weblogic/weblogic_jars/Oracle/Middleware
mkdir test
find ./ -name "*.jar" -exec cp {} ./test/ \;
find ./ -name "*.war" -exec cp {} ./test/ \;

新建IDEA项目,然后添加包含test目录到项目的Libraries


CVE-2020-2555

该编号反序列化利用的类为BadAttributeValueExpException,先看EXP如何构造的

EXP构造

文件位置:

com.supeream.CVE_2020_2555#main

image-20200901172535905.png

创建三个ReflectionExtractor对象,第一个参数均为字符串,第二个参数均为对象,然后将三个ReflectionExtractor元素放入ReflectionExtractor的数组中。

先跟进ReflectionExtractor的构造函数。

com.tangosol.util.extractor.ReflectionExtractor#ReflectionExtractor(java.lang.String, java.lang.Object[])

image-20200901173522764.png

继续调用其他参数的构造函数

com.tangosol.util.extractor.ReflectionExtractor#ReflectionExtractor(java.lang.String, java.lang.Object[], int)

image-20200901174058123.png

分别将第一个参数存在m_sMethod成员,第二个参数存在m_aoParam成员,放入数组后的赋值情况为:

image-20200901175046641.png

回到主流程

image-20200901175506262.png

创建一个ChainedExtractor对象,并将ReflectionExtractor数组作为构造参数传入,跟进构造函数:

com.tangosol.util.extractor.ChainedExtractor#ChainedExtractor(com.tangosol.util.ValueExtractor[])

image-20200901180257260.png

ChainedExtractor继承AbstractCompositeExtractor类,首先将ReflectionExtractor数组传给AbstractCompositeExtractor父类并调用构造函数。

com.tangosol.util.extractor.AbstractCompositeExtractor#AbstractCompositeExtractor(com.tangosol.util.ValueExtractor[])

image-20200901180424440.png

在父类的构造函数中将ReflectionExtractor数组赋值给m_aExtractor成员,并返回至子类ChainedExtractor的构造函数,调用computeTarget()完成对m_nTarget的赋值。

com.tangosol.util.extractor.ChainedExtractor#computeTarget

image-20200901180843358.png

是个三元表达式,对ReflectionExtractor数组的长度,还有数组中第一个元素是否为AbstractExtractor的实例进行了判断

aExtractor != null && aExtractor.length > 0 && aExtractor[0] instanceof AbstractExtractor == true

执行aExtractor[0].getTarget(),第一个元素调用父类AbstractExtractor的getTarget方法

com.tangosol.util.extractor.AbstractExtractor#getTarget

image-20200901181459981.png

返回值为0,最终整个ChainedExtractor对象的内容为:

image-20200901181635870.png

返回到主流程继续

image-20200901202303227.png

创建LimitFilter对象,然后利用反射将上文的ChainedExtractor对象赋值给m_comparator成员,将Runtime.class赋值给m_oAnchorTop

最终整个LimitFilter对象的内容为

image-20200901212005515.png

返回到主流程继续

image-20200901212421335.png

创建一个BadAttributeValueExpException对象,同样利用反射将LimitFilter对象赋值到val成员,然后将整个对象反序列化,俄罗斯套娃的最终结果

image-20200901230823932.png


Gadget chain

先直接跟踪到最外层的BadAttributeValueExpException类

javax.management.BadAttributeValueExpException#readObject

image-20200902095652329.png

反序列化获取val成员,也就是LimitFilter对象,然后调用toString方法。

com.tangosol.util.filter.LimitFilter#toString

image-20200902100942151.png

this.m_comparator是ChainedExtractor对象且为ValueExtractor类实例,进入if分支,并调用this.m_comparator的extract方法,参数为this.m_oAnchorTop,此时的this.m_comparator内容为:

image-20200902102153842.png

com.tangosol.util.extractor.ChainedExtractor#extract

image-20200902102304707.png

调用getExtractors函数

com.tangosol.util.extractor.AbstractCompositeExtractor#getExtractors

image-20200902102712340.png

返回数组:

image-20200902103118191.png

迭代循环调用数组元素的extract方法,并且上一次循环extract的结果作为这一次的参数

com.tangosol.util.extractor.ReflectionExtractor#extract

image-20200902103405057.png

这里method.invoke参数可控,可以进行任意反射,结合上层的循环,完成反射调用链。

简化的调用栈:

exec:485, Runtime (java.lang)
invoke:-1, GeneratedMethodAccessor239 (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
extract:121, ReflectionExtractor (com.tangosol.util.extractor)
extract:105, ChainedExtractor (com.tangosol.util.extractor)
toString:599, LimitFilter (com.tangosol.util.filter)
readObject:86, BadAttributeValueExpException (javax.management)


CVE-2020-2883

该编号反序列化利用的类为PriorityQueue,先看EXP如何构造的


EXP构造

该编号反序列化利用的类为PriorityQueue,先看EXP如何构造的


PriorityQueue一个基于优先级的无界优先级队列。

优先级队列的元素按照其自然顺序进行排序,放入PriorityQueue的元素,必须实现Comparable接口,PriorityQueue会根据元素的排序顺序决定出队的优先级;或者根据构造队列时提供的Comparator进行排序,元素就不必实现Comparable接口,具体取决于所使用的构造方法。


image-20200902125855072.png

和前文相似,同样是创建三个ReflectionExtractor对象,放入ValueExtractor数组中。

image-20200902131738129.png

再创建一个ValueExtractor数组

image-20200902132845283.png

创建一个ChainedExtractor对象,ValueExtractor数组作为构造,然后将ChainedExtractor对象作为构造参数传入ExtractorComparator对象

com.tangosol.util.comparator.ExtractorComparator#ExtractorComparator(com.tangosol.util.ValueExtractor<? super T,? extends E>)

image-20200902133431458.png

再将ExtractorComparator对象作为构造参数传入PriorityQueue

java.util.PriorityQueue#PriorityQueue(int, java.util.Comparator<? super E>)

image-20200902133450791.png

利用反射修改ChainedExtractor对象

image-20200902133550051.png

整个过程和CC2很相似,序列化的最终对象为:

image-20200902134206608.png


Gadget chain

先直接跟踪到最外层的PriorityQueue类

java.util.PriorityQueue#readObject

image-20200902135015138.png

PriorityQueue重写了readObject,首先通过defaultReadObject执行默认的反序列化操作

java.util.PriorityQueue#queue

image-20200710161633711.png

queue成员本来被transient修饰,不能默认反序列化,但自定义通过循环设置成员数组queue,此时两个关键成员:

image-20200902135624947.png

java.util.PriorityQueue#heapify

image-20200710162955404.png

进入heapify进行排序,循环遍历成员数组queueRuntime作为参数传入siftDown

java.util.PriorityQueue#siftDown

image-20200902135848546.png

java.util.PriorityQueue#siftDownUsingComparator

image-20200902140309540.png

这里的comparator是ExtractorComparator对象,调用compare方法

com.tangosol.util.comparator.ExtractorComparator#compare

image-20200902140503891.png

继续调用ChainedExtractor对象的extract方法,和上文相似,迭代循环调用数组元素的extract方法,并且上一次循环extract的结果作为这一次的参数,最终完成反射

com.tangosol.util.extractor.ChainedExtractor#extract

image-20200902140707856.png

最终的调用栈为:

exec:485, Runtime (java.lang)
invoke:-1, GeneratedMethodAccessor239 (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
extract:121, ReflectionExtractor (com.tangosol.util.extractor)
extract:105, ChainedExtractor (com.tangosol.util.extractor)
compare:71, ExtractorComparator (com.tangosol.util.comparator)
siftDownUsingComparator:721, PriorityQueue (java.util)
siftDown:687, PriorityQueue (java.util)
heapify:736, PriorityQueue (java.util)
readObject:795, PriorityQueue (java.util)


参考

https://www.oracle.com/security-alerts/cpujan2020.html


本文作者:Rai4over

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/140206.html

Tags:
评论  (0)
快来写下你的想法吧!

Rai4over

文章数:27 积分: 535

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号