RMI简介

Java RMI,即 远程方法调用(Remote Method Invocation),一种用于实现远程过程调用(RPC)(Remote procedure call)的Java API, 能直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于Java虚拟机(JVM),因此它仅支持从一个JVM到另一个JVM的调用。

 

Java中name是什么类型的 java.rmi.naming_JVM

 

 

Rmi的调用

服务端

import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
 
public class RmiRegistry {
public interface IRemoteHello extends Remote{
public String hello() throws RemoteException;
}
public class RemoteHelloWorld extends UnicastRemoteObject implements
IRemoteHello {
protected RemoteHelloWorld() throws RemoteException {
super();
}
public String hello() throws RemoteException {
System.out.println("call from");
return "Hello world";
}
}
private void start() throws Exception {
RemoteHelloWorld h = new RemoteHelloWorld();
LocateRegistry.createRegistry(1099);
Naming.rebind("rmi://127.0.0.1:1099/Hello", h);
}
 
public static void main(String[] args) throws Exception{
new RmiRegistry().start();
}
}

客户端

import java.rmi.Naming;
 
public class TrainMain {
public static void main(String[] args) throws Exception {
RmiRegistry.IRemoteHello hello = (RmiRegistry.IRemoteHello)
Naming.lookup("rmi://127.0.0.1:1099/Hello");
String ret = hello.hello();
System.out.println( ret);
}
}

 

Java中name是什么类型的 java.rmi.naming_JVM_02

 

成功从服务端取回hello world。

整个实现流程如下,客户端连接Registry,并在其中寻找Name是Hello的对象,这个对应数据 流中的Call消息;然后Registry返回⼀个序列化的数据,这个就是找到的Name=Hello的对象,这个对应 数据流中的ReturnData消息;客户端反序列化该对象,发现该对象是⼀个远程对象,地址在10.91.214.135:7532 ,于是再与这个地址建⽴TCP连接;在这个新的连接中,才执⾏真正远程⽅法调⽤,也就是 hello() 。

 

RMI的参与者

RMI Registry

RMI Server

RMI Client

攻击RMI Registry

RMI Registry是一个远程对象管理的地方,可以理解为一个远程对象的“后台”。我们可以尝试直

接访问“后台”功能。

注:远程访问RMI Registry时,只能通过list和lookup方法访问。rebind、bind、unbind方法只有来源地址是localhost时才能调用

只要目标服务器上存在一些危险方法,我们通过RMI就可以对其进行调用。

RMI动态类加载

当本地CLASSPATH中无法找到相应的类时,会在指定的codebase里加载class。codebase可以在系统属性java.rmi.server.codebase设置其URL。如果codebase的URL可控,那么我们就可以载入任意的class或jar文件。

RMI利用codebase执行任意代码

需要满足条件:

1.安装并配置了SecurityManager

2.Java版本低于7u21、6u45,或者设置了 java.rmi.server.useCodebaseOnly=false

注:在 java.rmi.server.useCodebaseOnly 配置为 true 的情况下,Java虚拟机将只信任预先配置好的

codebase ,不再支持从RMI请求中获取。

 


链接:https://www.jianshu.com/p/de85fad05dcb

https://www.anquanke.com/post/id/199481