嗯,感觉以前对这个概念的理解不是很清楚,今天抽了时间再学习了学习。
JNDI提供了一个统一的接口屏蔽了一些协议负载的调用与使用过程,如RMI、LDAP、COBRA等,主要功能是实现了远程方法调用,针对JNID的攻击一般有以下两种,一种是注册在远程的对象由一些危险的方法,那么我们便可以直接使用注册中兴对外暴露的接口调用这些危险的方法来实现攻击,一类是我们可以直接在客户端向注册中心直接注册一个恶意对象,因为对象在传输过程中时序列化传输的,那么注册中心再加载该对象的时候会进行反序列化操作,那么如果我们的恶意对象的静态代码块中有一些危险操作那么便会直接被执行,因为静态代码块中的方法是在类加载过程中被调用的,且只会调用一次。
关于第一种情况,没什么好说的,只要我们能够远程调用接口便能完成攻击,当然是在你知道对方注册了什么危险对象的基础上。第二种情况也分多种情况,一是我们可以直接向远程注册恶意对象。二是我们可以利用JNDI的动态类加载机制完成攻击,一是利用CodeBase机制,如果客户端的lookup参数内容可控,那么我们便可以自行搭建一个注册中心,注册恶意类。那么客户端在调用的时候就会调用到我们的恶意对象,但是这有一个问题,如果是我们自行注册的恶意对象,那么客户端如果没有这个恶意类,客户端也是不会反序列化成功的,利用CodeBase机制我们可以在服务端指定恶意类的加载地址,当客户端请求该恶意对象的时候,客户端会一并将CodeBase指定的地址发送个客户端,如果客户端没有这个恶意类那么则会使用CodeBase指定的地址去加载恶意类,从而完成恶意类的自动调用。这里注意CodeBase是双向指定的,客户端可以指定,服务端也可以指定,当然优先使用的是服务端指定的地址。麻烦的是一些版本的JDK模式不允许CodeBase远程类加载,而且还涉及到java的安全管理器。另一种情况是利用JNDI Naming Reference,Reference类表示对存在于命名/目录系统以外的对象的引用,如果注册在注册中心的对象为Reference类的子类,那么再客户端获取到远程对象的存根实例的时候将使用Reference对象指定的远程地址与类名去加载恶意类从而完成攻击,可以注意到,这个攻击发生在客户端。因为Reference没有继承UnicastRemoteObject,所以我们需要对Reference类使用ReferenceWrapper对其进行包装,然后绑定在注册中心中才能实现远程调用。两种情况重点都是需要lookup函数参数可控,也就是可以指定远程服务器的位置,当然你如果可以操控对方远程服务器又另说。



