weblogic漏洞分析之CVE-2016-0638
weblogic漏洞分析之CVE-2016-0638
一、環境搭建:
這裡使用前一篇文章的環境,然後打上補丁
上一篇文章:https://www.cnblogs.com/yyhuni/p/15137095.html
- 下載補丁p20780171_1036_Generic和p22248372_1036012_Generic
- 解壓補丁後,複製補丁到Docker中:
docker cp ./p22248372_1036012_Generic/ d1b6be39e32e:/home/
docker cp ./p20780171_1036_Generic d1b6be39e32e:/home/
- 安裝補丁:
docker exec -it d1b6be39e32e /bin/bash cd /root/Oracle/Middleware/utils/bsu mkdir cache_dir cp /home/p20780171_1036_Generic/* ./cache_dir/ cp /home/p22248372_1036012_Generic/* ./cache_dir/ vi bsu.sh 編輯MEM_ARGS引數為1024 ./bsu.sh -install -patch_download_dir=/root/Oracle/Middleware/utils/bsu/cache_dir/ -patchlist=EJUW -prod_dir=/root/Oracle/Middleware/wlserver_10.3 -verbose ./bsu.sh -install -patch_download_dir=/root/Oracle/Middleware/utils/bsu/cache_dir/ -patchlist=ZLNA -prod_dir=/root/Oracle/Middleware/wlserver_10.3 -verbose
- 重啟服務:
docker restart d1b6be39e32e
這時候,使用原先的poc已經是失效了,說明補丁成功打上
二、補丁分析
配置好weblogic的遠端除錯埠後,複製jar包,匯入idea
詳細步驟看前面一篇文章:https://www.cnblogs.com/yyhuni/p/15137095.html
補丁位置:
weblogic.rjvm.InboundMsgAbbrev.class :: ServerChannelInputStream
weblogic.rjvm.MsgAbbrevInputStream.class
weblogic.iiop.Utils.class
第一個位置在InboundMsgAbbrev
重點在ClassFilter.isBlackListed
判斷是否存在黑名單中,跟進方法
方法isBlackListed
中對className和pkgName都進行了黑名單判斷,匹配到了則返回true。黑名單list
在值為org.apache.commons.collections.functors.ChainedTransformer
時候丟擲了異常
補丁的第二個位置MsgAbbrevInputStream
也是做了同樣的判斷
現在來進行一遍流程分析,先看下之前的整個呼叫棧
POC偽造的T3協議資料包,傳送到伺服器,伺服器反序列化處理到了InboundMsgAbbrev#readObject
switch分發節點,到了case0中,呼叫了(new InboundMsgAbbrev.ServerChannelInputStream(in))
的readObject
方法來進行的反序列化
計算得出為InboundMsgAbbrev
類中的一個內部類ServerChannelInputStream
以下是ServerChannelInputStream
類的繼承圖
其繼承了ObjectInputStream
,並重寫了resolveClass
方法
weblogic反序列化類時候呼叫的是ServerChannelInputStream
的readObject
方法,而在執行到resolveClass
方法的時候呼叫的是ServerChannelInputStream
重寫的resolveClass
方法,在方法中對其做了黑名單過濾導致無法執行後面的readObject
、readExternal
、readResolve
方法。
三、繞過黑名單
要想繞過黑名單,則需要尋找一個不在黑名單的類。要知道,ObjectInputStream
在執行readObject
方法的時候,除了會呼叫反序列化類的readObject方法外,還會呼叫readExternal
、readResolve
,詳細呼叫過程可以看https://www.cnblogs.com/yyhuni/p/15127416.html
所以weblogic.jms.common.StreamMessageImpl
類就被挖掘了出來。其StreamMessageImpl#readExternal
中,會呼叫var5的readObject
方法,而var5是一個ObjectInputStream
物件
四、漏洞分析
攻擊機
這裡使用weblogic_cmd構造的poc:https://github.com/5up3rc/weblogic_cmd
-H "192.168.202.129" -C "touch /tmp/success" -B -os linux
這裡把CC1的利用鏈,進行了序列化後傳入了streamMessageImpl
方法
跟進streamMessageImpl
方法,new了一個StreamMessageImpl
物件,這個物件也就是構造payload的關鍵,然後把序列化轉換後的byte陣列傳入了setDataBuffer
方法
跟進setDataBuffer
,對this.buffer
和this.length
進行了賦值操作
隨後把獲得的StreamMessageImpl
物件又進行了一次序列化操作(序列話後的payload傳入物件,再把物件進行了序列化)
StreamMessageImpl
物件序列化會呼叫writeExternal
方法
在StreamMessageImpl
物件的writeExternal
方法中進行了重寫,把之前的payload給write進了ObjectOutputStream
物件中
最後返回給了byte[] payload,然後進行了T3協議構造並且傳送給了伺服器
服務端
在服務端接受到payload,隨後進行了反序列化操作,跳轉到InboundMsgAbbrev#resolveClass
方法中,進行黑名單判斷
黑名單中並沒有StreamMessageImpl
這個類,返回false,走入else中
接下來就會到StreamMessageImpl#readExternal
方法
switch中由前面構造payload時候寫入,case為1
此時的var4就是CC1的承載了payload的AnnotationInvocationHandler
序列化後的BufferInputStream
最後呼叫了var5.readObject就觸發了AnnotationInvocationHandler#readObject
方法了
總結
在這裡用了StreamMessageImpl
類來繞過黑名單檢查,把AnnotationInvocationHandler
序列化後通過重寫的writeExternal
方法給write進了ObjectOutputStream
物件中,呼叫StreamMessageImpl
類的readExternal
傳入了引數並執行了引數的readObject方法從而觸發了呼叫鏈