利用Java RMI进行反序列化攻击

0x01 RMI简介

RMI(Remote Method Invocation)远程方法调用,是一种允许程序在不同的JVM之间调用对象的方法。

在Java中,如果想要在网络中传递对象,通常会使用序列化来安全、完整地传递Java类对象。当涉及到跨JVM通信时,RMI采用了两个重要概念,即 Stub 和 Skeleton。

客户端调用远程对象时实际上是调用了客户端的代理类(Stub),而服务端在调用远程方法之前会注册一个远程代理类(Skeleton)。

Stub对于使用者是透明的,客户端可以直接通过Stub来调用远程方法,就像调用本地方法一样。Stub包含了远程对象的定位信息和网络通信细节,因此对于RMI服务的使用者来说,Stub和Skeleton的调用是隐藏的,无需手动调用RMI相关的方法。

图片[1]-利用Java RMI进行反序列化攻击-山海云端论坛

0x02 RMI实例

要运行一个RMI实例,需要进行以下步骤:

  1. 创建需要被调用的远程对象的接口(Server),该接口必须继承自java.rmi.Remote接口,并且所有方法必须抛出java.rmi.RemoteException异常。
  2. 实现该接口的类(ServerImpl),该类需要提供一个构造函数并抛出RemoteException异常,最好使用java.rmi.server.UnicastRemoteObject类。
  3. 创建注册中心,在服务端创建并运行。
  4. 编写客户端代码,用于查找远程对象并调用方法。

在Java中,为了实现RMI,引入了Registry来管理远程对象的引用。Registry类似于电话簿,存储着远程对象的名字和引用。通过Registry,客户端可以查找到所需的远程对象引用,并调用其方法。

Java提供了两个类来操作Registry:java.rmi.registry.Registry和java.rmi.Naming。

Registry用于创建注册中心,而Naming提供了一组方法来存储和获取远程对象引用。

下面是一个RMI实例的示例代码:

<code>// 创建接口 public interface ExecServer extends Remote { void execute() throws RemoteException; } // 实现类 public class ExecServerImpl extends UnicastRemoteObject implements ExecServer { public ExecServerImpl() throws RemoteException { super(); } public void execute() throws RemoteException { // 实现方法 } } // 服务端代码 public class RMIServer { public static void main(String[] args) { try { LocateRegistry.createRegistry(1099); ExecServerImpl server = new ExecServerImpl(); Naming.rebind("ExecServer", server); System.out.println("Server started"); } catch (Exception e) { e.printStackTrace(); } } } // 客户端代码 public class RMIClient { public static void main(String[] args) { try { Registry registry = LocateRegistry.getRegistry("localhost", 1099); ExecServer server = (ExecServer) registry.lookup("ExecServer"); server.execute(); } catch (Exception e) { e.printStackTrace(); } } }</code>

0x03 流程及原理

  1. 创建需要被调用的远程对象:在服务端创建远程对象,并通过Registry或Naming注册到注册中心。
  2. 创建注册中心:通过RegistryImpl创建注册中心,用于管理远程对象的引用。
  3. 绑定服务:将远程对象的引用绑定到注册中心。
  4. 查找服务:客户端通过Registry或Naming查找注册中心,并获取远程对象的引用。
  5. 远程调用对象方法:客户端通过远程对象的引用调用其方法,实际上是通过Stub进行网络通信,最终在服务端执行相应的方法。

以上就是RMI的简介、实例和原理。 RMI作为一种Java远程通信技术,通过序列化和反序列化实现了客户端与服务端之间的通信,为分布式系统开发提供了便利。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容