JNDI 高版本MemoryUserDatabaseFactory 利用
字数 1580 2025-08-22 12:23:30

JNDI高版本利用:MemoryUserDatabaseFactory攻击分析

前言

JNDI(Java Naming and Directory Interface)的高版本利用一直是安全研究的热点。本文详细分析了一种针对高版本JDK的JNDI利用方法,通过MemoryUserDatabaseFactory实现攻击,绕过了高版本JDK的安全限制。

JNDI低版本利用方法回顾

传统RMI利用方式

低版本JDK中,JNDI攻击通常通过远程代码加载实现:

  1. RMI服务端代码:设置恶意RMI服务
  2. 客户端代码:触发JNDI查找
  3. 恶意代码:通常放置在远程服务器上

关键方法分析

攻击流程进入getObjectInstance方法:

  1. 检查是否已为地址创建过工厂类
  2. ref赋值(传入的refInfo
  3. factory赋值并进入getObjectFactoryFromReference方法

关键代码部分:

  • 首先尝试本地加载类(抛出ClassNotFoundException
  • 然后尝试clas = helper.loadClass(factoryName, codebase)从远程codebase加载类

低版本利用的限制

从JDK 6u45、7u21开始:

  • java.rmi.server.useCodebaseOnly默认值变为true
  • 远程代码加载被严格限制

高版本利用思路

必须绕过以下条件判断之一:

  1. ref为空
  2. ref.getFactoryClassLocation()为空
  3. trustURLCodebase为true(已不可行)

本文利用的是第二种方法:ref.getFactoryClassLocation()返回空值,这意味着:

  • classFactoryLocation属性为空(通常存储远程代码库URL)
  • 对于本地工厂类,该属性自然为空
  • 从而绕过高版本JDK的安全限制

MemoryUserDatabaseFactory利用分析

工厂类特性

MemoryUserDatabaseFactorygetObjectInstance方法:

  1. 实例化MemoryUserDatabase对象
  2. Reference中提取pathnamereadonly参数
  3. 调用setter方法赋值
  4. 如果readonly=false,调用save()方法

open()方法漏洞

关键漏洞点:

  • open()方法可以解析XML文件
  • 没有任何防护措施
  • 可被用来加载恶意XML文件

攻击流程

  1. 准备恶意XML文件(如包含DNS解析的XML)
  2. 启动服务端
  3. 启动客户端

调用栈分析

  1. getObjectInstance方法获取Reference
    • 关键信息:地址和工厂类名称
  2. 通过getObjectFactoryFromReference加载
    • 第一步就已加载好,无需使用codebase
  3. 进入MemoryUserDatabaseFactory.getObjectInstance
    • database存储攻击者控制的信息
  4. 进入open()方法
    • 获取并解析文件内容

防御建议

  1. 升级JDK到最新版本
  2. 限制JNDI查找的可信来源
  3. 对XML解析进行严格校验
  4. 设置com.sun.jndi.rmi.object.trustURLCodebase为false
  5. 设置com.sun.jndi.cosnaming.object.trustURLCodebase为false

总结

这种利用方法通过本地工厂类MemoryUserDatabaseFactory绕过了高版本JDK对远程代码加载的限制,利用XML解析漏洞实现攻击。安全人员需要关注此类本地工厂类的潜在风险,及时采取防御措施。

JNDI高版本利用:MemoryUserDatabaseFactory攻击分析 前言 JNDI(Java Naming and Directory Interface)的高版本利用一直是安全研究的热点。本文详细分析了一种针对高版本JDK的JNDI利用方法,通过MemoryUserDatabaseFactory实现攻击,绕过了高版本JDK的安全限制。 JNDI低版本利用方法回顾 传统RMI利用方式 低版本JDK中,JNDI攻击通常通过远程代码加载实现: RMI服务端代码 :设置恶意RMI服务 客户端代码 :触发JNDI查找 恶意代码 :通常放置在远程服务器上 关键方法分析 攻击流程进入 getObjectInstance 方法: 检查是否已为地址创建过工厂类 为 ref 赋值(传入的 refInfo ) 为 factory 赋值并进入 getObjectFactoryFromReference 方法 关键代码部分: 首先尝试本地加载类(抛出 ClassNotFoundException ) 然后尝试 clas = helper.loadClass(factoryName, codebase) 从远程codebase加载类 低版本利用的限制 从JDK 6u45、7u21开始: java.rmi.server.useCodebaseOnly 默认值变为 true 远程代码加载被严格限制 高版本利用思路 必须绕过以下条件判断之一: 令 ref 为空 令 ref.getFactoryClassLocation() 为空 令 trustURLCodebase 为true(已不可行) 本文利用的是第二种方法: ref.getFactoryClassLocation() 返回空值,这意味着: classFactoryLocation 属性为空(通常存储远程代码库URL) 对于本地工厂类,该属性自然为空 从而绕过高版本JDK的安全限制 MemoryUserDatabaseFactory利用分析 工厂类特性 MemoryUserDatabaseFactory 的 getObjectInstance 方法: 实例化 MemoryUserDatabase 对象 从 Reference 中提取 pathname 和 readonly 参数 调用setter方法赋值 如果 readonly=false ,调用 save() 方法 open()方法漏洞 关键漏洞点: open() 方法可以解析XML文件 没有任何防护措施 可被用来加载恶意XML文件 攻击流程 准备恶意XML文件(如包含DNS解析的XML) 启动服务端 启动客户端 调用栈分析 getObjectInstance 方法获取 Reference 关键信息:地址和工厂类名称 通过 getObjectFactoryFromReference 加载 第一步就已加载好,无需使用codebase 进入 MemoryUserDatabaseFactory.getObjectInstance database 存储攻击者控制的信息 进入 open() 方法 获取并解析文件内容 防御建议 升级JDK到最新版本 限制JNDI查找的可信来源 对XML解析进行严格校验 设置 com.sun.jndi.rmi.object.trustURLCodebase 为false 设置 com.sun.jndi.cosnaming.object.trustURLCodebase 为false 总结 这种利用方法通过本地工厂类 MemoryUserDatabaseFactory 绕过了高版本JDK对远程代码加载的限制,利用XML解析漏洞实现攻击。安全人员需要关注此类本地工厂类的潜在风险,及时采取防御措施。