Java RMI

RMI全称是Remote Method Invocation,远程⽅方法调⽤

是让某个Java虚拟机上的对象调⽤另一个Java虚拟机中对象上的⽅方法,只不不过RMI是Java独 有的⼀一种机制

本质是跨越调用JVM对象方法,跨网络的对象方法调用

RMI 的核心概念

  • 远程对象(Remote Object) 运行在远程 JVM 上的对象,必须继承 UnicastRemoteObject 并实现 Remote 接口
  • 远程接口(Remote Interface) 声明远程调用的方法,必须继承 java.rmi.Remote,且每个方法都要抛出 RemoteException
  • 存根(Stub) 客户端代理对象,屏蔽了底层网络通信的细节,把方法调用转发到远程对象
  • 骨架(Skeleton)(Java 5 以前用,现在已合并进 Stub) 服务器端代理对象,负责接收请求并调用真正的远程对象
  • RMI 注册表(RMI Registry) 一个命名服务,服务器可以把远程对象绑定到注册表里,客户端再通过名字查找

工作流程

定义远程接口(继承 Remote

实现远程接口(继承 UnicastRemoteObject

启动 RMI 注册表(rmiregistry)

服务器端绑定对象到注册表

客户端查找对象并调用方法

远程接口

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

public interface Hello extends Remote {
  String sayHello(String name) throws RemoteException;
}

服务端实现

import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;

public class Helloimpl extends UnicastRemoteObject implements Hello {
  protected Helloimpl() throws RemoteException {
      super();
  }

  public String sayHello(String name) throws RemoteException {
      return "Hello, " + name + "!";
  }
}

server

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

public class Server {
  public static void main(String[] args) {
      try {
          Helloimpl obj = new Helloimpl();
          Registry registry = LocateRegistry.createRegistry(1099); // 启动RMI注册表
          registry.rebind("HelloService", obj);
          System.out.println("Server ready");
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}

client

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

public class Client {
  public static void main(String[] args) {
      try {
          Registry registry = LocateRegistry.getRegistry("localhost", 1099);
          Hello stub = (Hello) registry.lookup("HelloService");
          String response = stub.sayHello("sun");
          System.out.println("Response: " + response);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}

运行起来可以看到

我们运行Server类启动服务,运行Client类连接服务并调用远程方法,服务器处理请求并返回结果,最后客户端接收并回显

根据P牛的文章学习攻击

原理和流程我们已经大概了解了,那么我们就应该考虑安全问题了

能够访问到RMI Registry服务的情况下,如何进行攻击?

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

但是java对远程访问RMI Registry进行了限制,只有来源地址是localhost的时候才能调用rebind,bind,unbind等方法

这些方法都是用于把远程对象obj绑定到注册表中的名字name上

其中list()方法,属于 java.rmi.registry.Registry 接口

作用是:返回一个 String[],里面是注册表中当前绑定的所有服务名

方法功能特点
bind注册新服务如果已存在同名,抛 AlreadyBoundException
rebind注册/覆盖服务如果已存在同名,会替换旧的
unbind删除注册表里的服务如果名字不存在,抛 NotBoundException
list查看注册表里所有绑定的服务返回 String[],列出服务名称

如果目标服务器上存在危险方法,我们就可以通过RMI进行调用

…..

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇