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攻击通常通过远程代码加载实现:
- 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.getObjectInstancedatabase存储攻击者控制的信息
- 进入
open()方法- 获取并解析文件内容
防御建议
- 升级JDK到最新版本
- 限制JNDI查找的可信来源
- 对XML解析进行严格校验
- 设置
com.sun.jndi.rmi.object.trustURLCodebase为false - 设置
com.sun.jndi.cosnaming.object.trustURLCodebase为false
总结
这种利用方法通过本地工厂类MemoryUserDatabaseFactory绕过了高版本JDK对远程代码加载的限制,利用XML解析漏洞实现攻击。安全人员需要关注此类本地工厂类的潜在风险,及时采取防御措施。