介绍
本篇主要介绍java的RMI、JNDI、LDAP,在后面会详细分析log4j的jndi注入原理。
什么是RMI
RMI全称是Remote Method Invocatioon,也就是远程方法调用,看起来和RPC(Remote Procedure Call)很像
实际上它俩的确很像,RMI算是JAVA定制版RPC吧
一个完整的RMI调用过程,需要下面几个部分
- 注册服务
- RMIServer
- 客户端
- 接口
- 实现接口的类
执行流程如下
- 首先开启注册服务
- RMI创建实现接口的类的对象,并在注册服务中注册
- 客户端从注册服务调用接口里的方法
先来个例子,说不多说,都在代码里(网上找的)
注册服务代码

【→所有资源关注我,私信回复“资料”获取←】
1、网络安全学习路线
2、电子书籍(白帽子)
3、安全大厂内部视频
4、100份src文档
5、常见安全面试题
6、ctf大赛经典题目解析
7、全套工具包
8、应急响应笔记
接口和实现接口的类
[外链图片转存中…(img-0YGvrLnk-1646029690356)]
RMI服务

客户端

运行流程如下图

此图和上面的代码对应关系
Client -> Client
存根(stub) -> Client代码中的remoteHello对象(是个代理类,在通过它调用方法时,会将参数,函数名等信息打包,发送给骨架,存根对象包含了RMIServer的端口和ip)
rmiregistry -> RegServeer
Server -> RMI
骨架(Skeleton) -> 也是个代理类,监听4000端口,用于和存根通信,收到存根的请求后,去调用RemoteImp对应的方法,然后将结果返回给存根
ServiceImpl -> RemoteImpl
所以,再以上面的代码为例,解读下执行流程
先启动Register服务(默认端口1099)
RMI去连接Register服务,并将Name和存根发送给Register服务
如图

Client连接Register服务,根据Name获取到对应存根,再通过存根调用sayHello(“World”),因为存根是代理类,所以可以获取到函数名,参数,参数类型等信息,存根将这些信息打包,发给骨架
RMI的骨架也是代理类,通过反射调用remoteHello.sayHello(“World”),获取返回值Hello, World,并发送给存根
Client的存根将从骨架获取到的返回值Return,这样Client端看起来就好像调用的是本地的方法
补充下,以上步骤,通过网络传输的数据都是通过序列化对象的形式,使用的协议是JRMP(Java Remote Method Protocol)协议 很重要!!!
上面的代码还可以写成简化版
如图服务端,在启动注册中心的同时,设置了存根和名字

客户端,通过url连接注册中心,获取存根

本文介绍了Java的RMI(远程方法调用)、JNDI(Java命名和目录接口)和LDAP(轻量级目录访问协议),并详细分析了Log4j的JNDI注入漏洞,包括RMI的工作流程、JNDI的命名与目录服务、DNS的目录服务特性以及LDAP的应用场景。此外,还展示了Log4j漏洞的复现和调用栈分析。
最低0.47元/天 解锁文章
1850

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



