1. 程式人生 > 其它 >weblogic漏洞分析之CVE-2016-0638

weblogic漏洞分析之CVE-2016-0638

weblogic漏洞分析之CVE-2016-0638

一、環境搭建:

這裡使用前一篇文章的環境,然後打上補丁

上一篇文章:https://www.cnblogs.com/yyhuni/p/15137095.html

  1. 下載補丁p20780171_1036_Generic和p22248372_1036012_Generic
  2. 解壓補丁後,複製補丁到Docker中:
docker cp ./p22248372_1036012_Generic/ d1b6be39e32e:/home/
docker cp ./p20780171_1036_Generic d1b6be39e32e:/home/
  1. 安裝補丁:
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
  1. 重啟服務:
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反序列化類時候呼叫的是ServerChannelInputStreamreadObject方法,而在執行到resolveClass方法的時候呼叫的是ServerChannelInputStream重寫的resolveClass方法,在方法中對其做了黑名單過濾導致無法執行後面的readObjectreadExternalreadResolve方法。

三、繞過黑名單

要想繞過黑名單,則需要尋找一個不在黑名單的類。要知道,ObjectInputStream在執行readObject方法的時候,除了會呼叫反序列化類的readObject方法外,還會呼叫readExternalreadResolve,詳細呼叫過程可以看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.bufferthis.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方法從而觸發了呼叫鏈

參考:https://xz.aliyun.com/t/8443