作者:kejaly@白帽匯安全研究院
校對:r4v3zn@白帽匯安全研究院
前言
Coherence 組件是 WebLogic 中的一個核心組件,內置在 WebLogic 中。關于 Coherence 組件的官方介紹:https://www.oracle.com/cn/java/coherence/
https://images.seebug.org/content/images/2021/08/11/1628653081000-image-20210802113229602.png-w331s
近些年,weblogic Coherence 組件反序列化漏洞被頻繁爆出,苦于網上沒有公開對 weblogic Coherence 組件歷史反序列化漏洞的總結,導致很多想入門或者了解 weblogic Coherence 組件反序列化漏洞的朋友不知道該怎么下手,于是本文便對 weblogic Coherence 組件歷史反序列化漏洞做出了一個總結和分析。
關于 Coherence 組件反序列化漏洞利用鏈的架構,我把他分為兩個,一個是基于 ValueExtractor.extract 的利用鏈架構,另一個則是基于 ExternalizableHelper 的利用鏈架構。
前置知識
想理清 WebLogic 的 Coherence 組件歷史反序列化漏洞需要首先了解一些 Coherence 組件反序列化漏洞中經常會涉及的一些接口和類。他們在 Coherence 組件反序列化漏洞利用中經常出現。
ValueExtractor
com.tangosol.util.ValueExtrator 是一個接口:
https://images.seebug.org/content/images/2021/08/11/1628653081000-image-20210725145241910.png-w331s
在 Coherence 中 很多名字以 Extrator 結尾的類都實現了這個接口:
https://images.seebug.org/content/images/2021/08/11/1628653081000-image-20210725145311604.png-w331s
這個接口中聲明了一個 extract 方法,而 ValueExtractor.extract 正是 Coherence 組件歷史漏洞( ValueExtractor.extract 鏈部分 )的關鍵。
ExternalizableLite
Coherence 組件中存在一個 com.tangosol.io.ExternalizableLite,它繼承了 java.io.Serializable,另外聲明了 readExternal 和 writeExternal 這兩個方法。
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210728101447302.png-w331s
com.tangosol.io.ExternalizableLite 接口 和 jdk 原生的 java.io.Externalizable 很像,注意不要搞混了。
ExternalizableHelper
上面提到的 com.tangosol.io.ExternalizableLite 接口的實現類的序列化和反序列化操作,都是通過 ExternalizableHelper 這個類來完成的。
我們可以具體看 ExternalizableHelper 這個類是怎么對實現 com.tangosol.io.ExternalizableLite 接口的類進行序列化和反序列化的,這里以 readObject 方法為例,writeObject 讀者可自行去查看:
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210728102323560.png-w331s
如果傳入的DataInput 不是 PofInputStream 的話(Coherence 組件歷史漏洞 涉及到的 ExternalizableHelper.readObject 傳入的 DataInput 都不是 PofInputStream),ExternalizableHelper#readObject 中會調用 ExternalizableHelper#readObjectInternal 方法:
readObjectInternal 中會根據傳入的中 nType 進行判斷,進入不同的分支:
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210728103543135.png-w331s
對于實現 com.tangosol.io.ExternalizableLite 接口的對象,會進入到 readExternalizableLite 方法:
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210728104059476.png-w331s
可以看到在 readExternalizableLite 中 1125 行會根據類名加載類,然后并且實例化出這個類的對象,然后調用它的 readExternal() 方法。
漏洞鏈
ValueExtractor.extract
我們在分析反序列化利用鏈的時候,可以把鏈分為四部分,一個是鏈頭,一個是危險的中間的節點(漏洞點),另一個是調用危險中間節點的地方(觸發點),最后一個則是利用這個節點去造成危害的鏈尾。
在 Coherence 組件 ValueExtractor.extract 利用鏈架構中,這個危險的中間節點就是 ValueExtractor.extract 方法。
漏洞點
ReflectionExtractor
ReflectionExtractor 中的 extract 方法含有對任意對象方法的反射調用:
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210725151740093.png-w331s
配合 ChainedExtractor 和 ConstantExtractor 可以實現類似 cc1 中的 transform 鏈的調用。
涉及 CVE
CVE-2020-2555,CVE-2020-2883
MvelExtractor
MvelExtrator 中的 extract 方法,會執行任意一個 MVEL 表達式(RCE):
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210725151958385.png-w331s
而在序列化和反序列化的時候 m_sExpr 會參與序列化和反序列化:
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210725152123268-16274409140731.png-w331s
所以 m_xExpr 可控,所以就導致可以利用 MvelExtrator.extrator 來達到執行任意命令的作用。
涉及 CVE
CVE-2020-2883
UniversalExtractor
UniversalExtractor(Weblogic 12.2.1.4.0 獨有) 中的 extract 方法,可以調用任意類中的的 get 和 is 開頭的無參方法,可以配合 jdbsRowset,利用 JDNI 來遠程加載惡意類實現 RCE。
具體細節可以參考:https://nosec.org/home/detail/4524.html
涉及 CVE
CVE-2020-14645,CVE-2020-14825 , CVE-2020-14841
LockVersionExtractor
oracle.eclipselink.coherence.integrated.internal.cache.LockVersionExtractor 中的 extract() 方法,可以調用任意 AttributeAccessor 的 getAttributeValueFromObject 方法,賦值 Accessor 為 MethodAttributeAccessor 進而可以實現調用任意類的無參方法。
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210730155536540.png-w331s
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210730160730854.png-w331s
具體細節可參考:https://cloud.tencent.com/developer/article/1740557
MethodAttributeAccessor.getAttributeValueFromObject,本質是利用MethodAttributeAccessor.getAttributeValueFromObject中存在任意無參方法調用,在 CVE-2021-2394 中也利用到了。
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210730155032451.png-w331s
涉及 CVE
CVE-2020-14825 , CVE-2020-14841
FilterExtractor.extract
filterExtractor.extract 中存在任意 AttributeAccessor.getAttributeValueFromObject(obj) 的調用,賦值 this.attributeAccessor 為上面說的MethodAttributeAccessor 就可以導致任意無參方法的調用。
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210730155415313.png-w331s
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210730155505477.png-w331s
關于 readAttributeAccessor 的細節可以看 CVE-2021-2394:https://blog.riskivy.com/weblogic-cve-2021-2394-rce%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/ 和 https://www.cnblogs.com/potatsoSec/p/15062094.html 。
涉及 CVE
CVE-2021-2394
觸發點
上面例舉出了很多危險的 ValueExtractor.extract 方法,接下來再看看哪里存在調用 ValueExtractor.extract 方法的地方。
Limitfiler
Limitfiler 中 Limitfiler.toString 中存在任意 ValueExtractor.extract 方法調用:
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210728114626359.png-w331s
由于 this.m_comparator 參與序列化和反序列化,所以可控:
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210728114758555.png-w331s
我們只需要賦值 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 方法調用。
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210728115727611.png-w331s
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210728115739991.png-w331s
Comparator.compare 方法,則可以通過 CC2 中用到的PriorityQueue.readObject` 來觸發。
另外在 weblogic 中, BadAttributeValueExpException.readObject 中也可以實現調用任意 compartor.compare方法:
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210728120040372.png-w331s
涉及 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 是不受黑名單限制的。
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210730135848902.png-w331s
具體原因是:weblogic 黑名單是基于 jep 290 ,jep 290 是在 readObject 的時候,在得到類名后去檢查要反序列化的類是否是黑名單中的類。而這里直接使用的 loadClass 去加載類,所以這里不受 weblogic 黑名單限制。(也可以這么理解: jep 290 是針對在反序列化的時候,通過對要加載類進行黑名單檢查。而這里直接通過 loadClass 加載,并沒有通過反序列化,和反序列化是兩碼事,當然在后續 readExternal 的時候還是受 weblogic 黑名單限制,因為走的是反序列化那一套)
weblogic 黑名單機制可以參考:https://cert.#/report/detail?id=c8eed4b36fe8b19c585a1817b5f10b9e,https://cert.#/report/detail?id=0de94a3cd4c71debe397e2c1a036436f,https://www.freebuf.com/vuls/270372.html
漏洞點
PartialResult
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210806191659163.png-w331s
com.tangosol.util.aggregator.TopNAggregator.PartialResult 的 readExternal 會觸發任意 compartor.compare 方法。
大致原理:
在 149 行會把comparator 作為參數傳入 TreeMap 的構造函數中。
然后 153 行,會調用 this.add ,this.add 會調用 this.m_map.put 方法,也就是說調用了 TreeMap 的 put 方法,這就導致了 comparator.compare()的調用。
具體分析見:https://mp.weixin.qq.com/s/E-4wjbKD-iSi0CEMegVmZQ
然后調用 comparator.compare 就可以接到 ExtractorComparator.compare 那里去了,從而實現 rce 。
涉及 CVE
CVE-2020-14756 (1月)
ExternalizableHelper 的利用第一次出現是在 CVE-2020-14756 中。利用的正是 ExternalizableHelper 的反序列化通過 loadClass 加載類,所以不受 weblogic 之前設置的黑名單的限制。具體利用可以參考:https://mp.weixin.qq.com/s/E-4wjbKD-iSi0CEMegVmZQ
CVE-2020-14756 的修復方法則是對 readExternalizable 方法傳入的 Datainput 檢查,如果是 ObjectInputStream 就調用 checkObjectInputFilter() 進行檢查,checkObjectInputFilter 具體是通過 jep290 來檢查的。
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210730135848902.png-w331s
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 :
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210725192343651.png-w331s
所以只要找調用 ExternalizableHelper .deserializeInternal 的地方。
而 ExternalizableHelper.fromBinary (和 ExternalizableHelper.readObject 平級的關系 )里就調用了 deserializeInternal , 所以只需要找到一個地方用 來 ExternalizableHelper.fromBinary 來反序列化就可以接上后面的(CVE-2020-14756)利用鏈了。
然后就是找 調用了 ExternalizableHelper.fromBinary 的方法的地方。SimpleBinaryEntry 中的 getKey 和 getValue方法中存在 ExternalizableHelper.fromBinary 的調用,所以就只要找到調用 getKey 和 getValue 的地方就可以了。
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210806191959478.png-w331s
然后在 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 鏈頭就可以了。
具體可以參考:https://mp.weixin.qq.com/s/eyZfAPivCkMbNCfukngpzg
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210725194322960.png-w331s
4月漏洞修復則是:
添加simpleBianry 到黑名單。
filterExtractor
filterExtractor.reaExternal 方法中的 readAttributeAccessor() 方法會直接 new 一個 MethodAttributeAccessor 對象。
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210730154428860.png-w331s
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210730154447677.png-w331s
隨后在 filterExtractor.extract 函數中會因為調用 this.attributeAccessor.getAttributeValueFromObject 進而導致任意無參方法的調用。
https://images.seebug.org/content/images/2021/08/11/1628653082000-image-20210730155415313.png-w331s
涉及 CVE
CVE-2021-2394 (4月)
https://images.seebug.org/content/images/2021/08/11/1628653083000-image-20210730135848902.png-w331s
在4月的補丁中,對 ois 的 DataInput 流進行了過濾,所以直接通過 newInstance 實例化惡意類的方式已經被阻止(CVE-2021-2135 通過 bufferinputStream 進行了繞過),所以需要重新尋找其他不在黑名單中的 readExternal 方法。
CVE-2021-2394 中就是利用 filterExtractor.readExternal 來進行突破。
具體可以參考:https://blog.riskivy.com/weblogic-cve-2021-2394-rce%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/ 和 https://www.cnblogs.com/potatsoSec/p/15062094.html
觸發點
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) 。
https://images.seebug.org/content/images/2021/08/11/1628653084000-image-20210728172300444.png-w331s
ExternalizableHelper.fromBinary 的觸發則較為復雜一些,具體可以參考:https://mp.weixin.qq.com/s/eyZfAPivCkMbNCfukngpzg
后記
weblogic Coherence 反序列化漏洞很多都是相關聯的,對于某個漏洞,很可能就是用到了之前一些漏洞的鏈子。其實不僅僅 weblogic ,java 其他反序列化鏈也是如此,很多情況都是一個鏈會用到其他鏈的一部分。所以在學習中,把一個組件或者一個庫的漏洞總結起來一起分析還是比較重要的,最后希望這篇文章能幫助到其他一起學反序列化的朋友們。
參考
https://nosec.org/home/detail/4524.html
https://cloud.tencent.com/developer/article/1740557
https://blog.riskivy.com/weblogic-cve-2021-2394-rce%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
https://www.cnblogs.com/potatsoSec/p/15062094.html
https://cert.#/report/detail?id=c8eed4b36fe8b19c585a1817b5f10b9e
https://cert.#/report/detail?id=0de94a3cd4c71debe397e2c1a036436f
https://www.freebuf.com/vuls/270372.html
https://mp.weixin.qq.com/s/E-4wjbKD-iSi0CEMegVmZQ
https://mp.weixin.qq.com/s/eyZfAPivCkMbNCfukngpzg
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1670/
暫無評論