【JavaWeb安全】初识JNDI

简介

JNDI(Java Naming and Directory Interface)是Java提供的Java 命名和目录接口。通过调用JNDI的API应用程序可以定位资源和其他程序对象。JNDI是Java EE的重要部分,需要注意的是它并不只是包含了DataSource(JDBC 数据源),JNDI可访问的现有的目录及服务有:JDBC、LDAP、RMI、DNS、NIS、CORBA

Naming Service 命名服务
命名服务将名称和对象进行关联,提供通过名称找到对象的操作。
例如:DNS系统将计算机名和IP地址进行关联。文件系统将文件名和文件句柄进行关联等等。
Directory Service 目录服务
目录服务是命名服务的扩展,除了提供名称和对象的关联,还允许对象具有属性。目录服务中的对象称之为目录对象。目录服务提供创建、添加、删除目录对象以及修改目录对象属性等操作。
Reference 引用:
在一些命名服务系统中,系统并不是直接将对象存储在系统中,而是保持对象的引用。引用包含了如何访问实际对象的信息。

JNDI支持的协议

image

JNDI的使用

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;


public class DNSContextFactoryTest {

    public static void main(String[] args) {
        // 创建环境变量对象
        Hashtable env = new Hashtable();

        // 设置JNDI初始化工厂类名
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");

        // 设置JNDI提供服务的URL地址,这里可以设置解析的DNS服务器地址
        env.put(Context.PROVIDER_URL, "dns://223.6.6.6/");

        try {
            // 创建JNDI目录服务对象
            DirContext context = new InitialDirContext(env);

            // 获取DNS解析记录测试
            Attributes attrs1 = context.getAttributes("baidu.com", new String[]{"A"});
            Attributes attrs2 = context.getAttributes("qq.com", new String[]{"A"});

            System.out.println(attrs1);
            System.out.println(attrs2);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

}

过程分析:就是首先用JNDI绑定一个本地服务或者远程服务并创建一个Name或Directory对象,然后直接和对象按照既定的规则进行交,互完成服务.
例如上面的DNS服务,就是通过传入域名和解析类型,完成DNS服务。

JNDI注入

触发JNDI注入漏洞的方式也是非常的简单,只需要直接或间接的调用JNDI服务,且lookup的参数值可控、JDK版本、服务器网络环境满足漏洞利用条件就可以成功的利用该漏洞了。

Context ctx = new InitialContext();

// 获取RMI绑定的恶意ReferenceWrapper对象
Object obj = ctx.lookup("注入JNDI服务URL");

我们只需间接的找到调用了JNDI的lookup方法的类且lookup 的URL可被我们恶意控制的后端接口或者服务即可利用。

posted @ 2021-12-13 10:04  Aur0ra*  阅读(210)  评论(0编辑  收藏  举报