想学JDNI,那想必一定躲不过RMI。
RMI简述
RMI可以远程调用JVM对象并获取结果。所以需要一个server和一个client进行通信。
Server端会创建一个远程对象用于client端远程访问。
下面改造一张来自W3Cschool的图:

只需要知道:Client端使用stub来请求远程方法,而Server端用Skeleton来接收stub,然后将返回值传输给Client。
-
RMI server的构造需要:
-
一个远程接口rmidemo,rmidemo需要继承java.rmi.Remote接口,其中的方法还需要有serializable接口
public interface rmidemo extends Remote {private static final long serialVersionUID = 6490921832856589236L;
public String hello() throws RemoteException{}
}
-
serialVersionUID是为了防止在序列化时导致版本冲突,所以序列化后UID不同会报异常

2. 能被远程访问的类RmiObject(需要继承UnicastRemoteObject类),类必须实现rmidemo接口。
public class RmiObject extends UnicastRemoteObject implements rmidemo {
protected RmiObject() throws RemoteException {}
public String hello() throws RemoteException{}
}
3. 注册远程对象(RMIRegistry):
public class server {
public static void main(String[] args) throws RemoteException {
rmidemo hello = new RmiObjct();//创建远程对象
Registry registry = LocateRegistry.createRegistry(1099);//创建注册表
registry.rebind("hello",hello);//将远程对象注册到注册表里面,并且设置值为hello
}
}
-
RMI Client。LocateRegistry.getRegistry进行连接,用到lookup()搜索对应方法,然后调用需要的远程方法:
public class clientdemo {public static void main(String[] args) throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry(“localhost”, 1099);//获取远程主机对象
// 利用注册表的代理去查询远程注册表中名为hello的对象
rmidemo hello = (rmidemo) registry.lookup(“hello”);
// 调用远程方法
System.out.println(hello.hello());
}
}
以上过程也可以用素十八大佬的一图概括:

RMI反序列化攻击
以CC1链利用AnnotationInvocationHandler进行攻击为例:
CC1的POC为:
package org.vulhub.Ser;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import

本文深入探讨Java RMI(Remote Method Invocation),解析Server端UnicastRemoteObject和Registry端createRegistry的源码,揭示RMI反序列化攻击的原理。通过源码分析,展示了RMI在创建远程对象、动态代理及Registry管理等方面的关键步骤。同时,文章提到了非Object参数的RMI攻击策略,以及学习网络安全的全面路径和资源。
最低0.47元/天 解锁文章
726

被折叠的 条评论
为什么被折叠?



