### 讲下 RMI 原理以及相关的漏洞

1. RMI 原理

RMI（Remote Method Invocation），是 Java 远程方法调用的缩写。简单来说，它是一种 Java 编程技术，允许你在一个 Java 虚拟机（JVM）上运行的代码，调用另一个不同 JVM 上的对象的方法。这使得分布式应用开发变得相对简单，因为你可以像调用本地对象一样调用远程对象的方法

RMI 的核心思想是存根（Stub）和骨架（Skeleton）

- 客户端（Client）：
  - 存根（Stub）：这是一个本地代理对象，它实现了远程对象的接口。客户端调用远程方法时，实际上是在调用存根上的本地方法。存根负责将方法调用信息（方法名、参数等）打包，并发送给远程服务器
- 服务器端（Server）：
  - 远程对象（Remote Object）：这是真正提供服务、执行方法的对象
  - 骨架（Skeleton）：一个中间层对象，它监听客户端的请求。当收到存根发来的请求时，骨架负责解析请求，找到相应的远程对象，调用其方法，并将结果打包返回给客户端

RMI 工作流程

1. 注册：服务器端创建一个远程对象，并通过一个注册中心（RMI Registry）将其注册。注册中心会绑定远程对象和服务名，例如 `rmi://server:port/serviceName`
2. 查找：客户端通过服务名向注册中心查找远程对象。注册中心会返回一个存根对象给客户端
3. 调用：客户端调用存根上的方法
4. 传输：存根将方法调用信息序列化并通过网络发送给服务器端的骨架
5. 执行：骨架反序列化信息，调用远程对象上的实际方法，并将结果序列化后返回
6. 返回：客户端的存根接收到结果并反序列化，然后返回给客户端

2. RMI 相关漏洞

RMI 的安全问题主要源于其依赖 Java 对象的序列化和反序列化机制。这种机制本身就是高风险的，因为它默认信任所有传入的对象。攻击者可以利用这一特性，构造恶意的序列化对象，在反序列化时触发攻击

漏洞一：RMI 序列化漏洞（反序列化漏洞）

这是 RMI 最常见也是最危险的漏洞类型。

- 原理：在 RMI 的调用过程中，客户端和服务端会相互发送序列化的对象。攻击者可以利用这个机制，构造一个包含恶意 Payload 的序列化对象。当服务器在反序列化这个对象时，如果其所依赖的库中存在可被利用的 Gadget Chain（例如 `Apache Commons Collections`），就会导致远程代码执行（RCE）
- 攻击利用：攻击者首先需要确定 RMI 服务器的地址和端口。然后，他们会使用工具（例如 `ysoserial`）来生成一个恶意的序列化 Payload。最后，通过向 RMI 接口发送这个 Payload，即可触发反序列化攻击
- 影响：这是一种高危 RCE 漏洞，可以使攻击者在未授权的情况下完全控制服务器

漏洞二：RMI 弱口令漏洞

- 原理：如果 RMI Registry 的管理接口存在弱口令，攻击者就可以登录并执行恶意操作
- 攻击利用：攻击者可以尝试对 RMI Registry 的管理接口进行暴力破解或字典攻击。一旦获得权限，就可以修改、删除或注册恶意服务

漏洞三：RMI Registry 绑定漏洞

- 原理：某些情况下，RMI Registry 允许任何客户端绑定新的远程对象。如果应用程序没有对这个功能进行严格的权限控制，攻击者就可以注册一个恶意的远程对象
- 攻击利用：攻击者可以注册一个带有恶意方法的远程对象。然后，他们可以诱导受害者或通过其他方式调用这个恶意方法，从而实现攻击

漏洞四：RMI SSL/TLS 证书验证漏洞

- 原理：RMI 可以配置为使用 SSL/TLS 进行安全通信。但如果客户端没有正确验证服务器的 SSL 证书，攻击者就可以进行中间人攻击（MitM），从而窃取敏感信息或篡改通信内容