Java Naming and Directory Interface
java命名和目录接口
让配置参数和代码 解耦的规范或思想
例,使用mysql数据库的语言,当需要更换其他数据库(本质就是更改配置文件),却又不想改代码,就需要JNDI
是我们的数据更加 : 低耦合,高内聚
java对象通过命名绑定到容器环境
我们可以将java对象和一个特定的名称关联到一起
将一个对象的所有的属性信息保存在一个容器环境
Remote Method Invocation Java远程方法调用
实现java程序之间jvm的远程通信
JVM代表Java虚拟机(Java Virtual Machine),是一种能够在不同平台上运行Java程序的虚拟计算机。它是Java平台的核心组件之一,负责将Java字节码翻译成特定平台上的机器指令,并管理程序的执行。
Java程序员编写的代码首先被编译成Java字节码,然后由JVM解释和执行。这种设计使得Java程序可以跨平台运行,而无需修改代码。JVM还提供了许多高级功能,如垃圾回收、动态加载、安全管理和调试支持,使得Java编程变得更加方便和高效。
例:
某个复杂计算
一台计算机需要很久
如果这台计算机支持RMI调用
则可以分配任务到远程计算机
分为三部分
Server 服务端 提供远程的对象
Client 客户端 调用远程的对象
Regist 注册 存放远程对象的位置,包括 IP 端口 标识符
首先建立一个这样的项目
在本地测试环境中,可以利用phpstudy在本地建立仓库使用
但是在测试的时候要删除项目目录中的payload.java
否则rmi不会再去链接本地仓库
客户端通过lookup()方法,注入了rmi协议,访问了远程的rmi服务器
rmi服务器返回了引用对象,而引用对象包含了类的加载工厂
如果本地没有这个类,就去加载工厂加载类的字节码
而加载工厂是本地的localhost的80端口,目录下有payload.class文件
客户端再去访问localhost的80端口,去下载payload.calss的字节码
然后Class.forName加载了这个字节码
造成了payload.class这个类里面的静态代码被执行
在这段代码中,我们创建了一个名为 "payload" 的 Reference 对象,这个对象可以被用于注入恶意代码。接下来,我们将该对象包装在一个 ReferenceWrapper 中,使其可以实现远程接口。最后,我们将该包装对象绑定到了 RMI 注册表的 "hello" 名称上,从而使得该服务可以被远程客户端调用。当客户端调用该服务时,ReferenceWrapper 对象会被反序列化并执行其中的恶意代码,从而实现攻击。
攻击者需要将恶意的Log4j日志信息发送到目标服务器,使得目标服务器解析该日志信息并发起JNDI连接请求。攻击者可以利用JNDI注入攻击获得对目标服务器的控制。
攻击者可以通过向目标服务器发送经过精心构造的日志信息来实现JNDI注入攻击。攻击者可以构造一个包含JNDI URL的恶意日志消息,将其发送到目标服务器的Log4j日志中,当目标服务器解析该日志消息时,它会尝试创建JNDI连接并执行JNDI操作。攻击者可以通过JNDI连接获得对目标服务器的控制,例如读取敏感数据、执行恶意代码等。
攻击者可以通过多种方式将恶意日志消息发送到目标服务器。例如,攻击者可以通过网络发送带有恶意负载的HTTP请求或SMTP邮件,或者通过在已被入侵的服务器上运行恶意代码生成日志消息并将其发送到目标服务器。攻击者也可以伪造源IP地址,使得日志消息看起来像是来自可信来源。
http://localhost"是将创建的 Reference
对象的 factoryClassLocation
属性设置为本地主机地址的URL。这是因为在进行JNDI注入攻击时,攻击者将利用被攻击方的服务器上的JNDI服务来绑定恶意的引用对象,然后再通过远程调用执行恶意代码。在这种情况下,由于攻击者和被攻击方在不同的主机上,所以需要使用可公开访问的IP地址或域名作为 factoryClassLocation
属性的值,以便攻击者可以从远程访问它。但是在本地测试环境中,可以将 factoryClassLocation
属性设置为本地主机地址的URL(如"http://localhost"),以方便进行测试和调试。
factoryClassLocation
factoryClassLocation
属性是InitialContext
类的一个可选属性,它指定了用于创建InitialContext
对象的工厂类的位置。如果没有设置该属性,则会使用默认的工厂类。工厂类是一个实现了javax.naming.spi.InitialContextFactory
接口的类,用于创建InitialContext
对象。factoryClassLocation
属性的值是指定工厂类的位置的字符串。
在使用JNDI(Java命名和目录接口)时,通常需要使用InitialContext
对象来连接到JNDI服务提供者,并在命名和目录服务中查找或存储对象。在创建InitialContext
对象时,需要指定JNDI提供者的名称或URL,以及可能的上下文工厂和URL工厂。如果没有指定上下文工厂和URL工厂,则默认使用JNDI实现提供的工厂。如果需要使用自定义的工厂,则需要设置factoryClassLocation
属性来指定工厂类的位置。
factoryClassLocation
属性用于指定 RMI 客户端在远程调用时从哪里加载远程对象的类定义。如果此属性被设置为恶意的远程代码库的位置,那么客户端将会从该位置下载并执行该代码库中的字节码,从而受到攻击。因此,如果 RMI 服务端无法保证其提供的远程对象的安全性,那么最好不要在客户端上设置 factoryClassLocation
属性,或者只允许从受信任的代码库加载类定义。
用static{}包裹·即可在虚拟机加载类字节码后自动执行
被攻击者(客户端)存在有漏洞的log4j版本
被攻击者(客户端)可以出网(或者攻击端与被攻击端处在同一个内网)