小研究 - JVM 逃逸技术与 JRE 漏洞挖掘研究(四)

news2024/11/18 2:43:46

Java语言是最为流行的面向对象编程语言之一, Java运行时环境(JRE)拥有着非常大的用户群,其安全问题十分重要。近年来,由JRE漏洞引发的JVM逃逸攻击事件不断增多,对个人计算机安全造成了极大的威胁。研究JRE安全机制、JRE漏洞及其挖掘、JVM逃逸攻防技术逐渐成为软件安全领域的热门研究方向。

针对Java层API与原生层API, JRE安全机制分别包括JRE沙箱与JVM 类型安全机制。本文针对JRE沙箱组件及其工作原理进行剖析,总结其脆弱点;分析调研JVM安全机制,提出其脆弱点在于Java原生层漏洞,为JRE漏洞挖掘工作提供理论基础。

对于JRE漏洞,本文进行漏洞分类研究,提取Java API设计缺陷、Java原生层漏洞两种JRE漏洞类型的典型漏洞进行分析,总结漏洞特征,为漏洞挖掘工作建立漏洞模型。

根据JRE漏洞分析中建立的漏洞模型,本文采用源代码审计的方法开展Java API设计缺陷类型的漏洞挖掘工作,发现了数个Oracle JRE、OpenJDK和Apple JRE 的 Java API 设计缺陷问题。在 Java原生层漏洞挖掘工作中,出于Java原生层漏洞的特殊性,本文基于程序分析领域的符号执行技术提出一种寄存器符号化监控方法,选取开源符号执行平台S2E作为漏洞挖掘工具,并且基于其实现了针对JRE原生层漏洞挖掘的辅助插件 SymJava 和 SymRegMonitor,基于 OpenJDK 和 Oracle JRE逆向代码进行源代码白盒审计并构建了用于进行漏洞挖掘的 Java 测试用例,最后对36个调用Java原生层API的Java测试用例进行实际测试发现了共计6 个 JRE原生层安全隐患,其中2 个可被攻击者恶意利用,并给出漏洞分析和 PoC。

针对 JVM 逃逸攻防问题,本文分别从攻击和防御角度,提出 JVM逃逸攻击的5 个关键元素,针对每个元素进行攻防技术研究,并通过绕过杀毒软件静态检测的实验证明了本文提出的 JVM 逃逸攻击技术。最后,本文从多角度给出JVM逃逸攻击的防御策略。

目录

3.2.3  CVE-2013-2423

3.2.4  CVE-2013-1493

3.3  本章小结

4  JRE 漏洞挖掘研究

4.1  针对 Java API 设计缺陷的漏洞挖掘工作

4.2  针对Java原生层漏洞的漏洞挖掘工作

4.2.1  符号执行技术简介


3.2.3  CVE-2013-2423

作为一门面向对象的语言, Java中所有的类型也都有对象的定义类。例如int类型的定义类是java.lang.Integer, long类型为java.lang.Long, float类型则为java.lang.Float, double类型为java.lang.Double。通过查看它们的源码,可以看到上述每个class都有一个名为"TYPE"的域,以Integer类为例,其"TYPE”域定义如表3-15 所示。

在 Java 程序执行时,JVM 根据这个 TYPE 域来判断当前变量是何种类型,需要分配多少空间。那么,通过一定的手段修改掉这个TYPE域,理论上就可以达到 Type Confusion 的目的。

第二章中提到Java 7新增了功能更加强大、调用更加方便的反射API,其中findStaticSetter可用于设置域的值。CVE-2013-2423231便是这样利用这个反射API,对TYPE域进行了恶意篡改,从而在Java API层面实现了Type Confusion.下面给出这个漏洞利用原理的分析。

首先要明确,在32位的JVM中, int值占4字节, double与long是占8字节,另外值得注意的是, Java语言中有一个基类Object,所有的类都继承自它,在hotspot源码中可以看的它的声明,在这里只需知道一个Object对象也是占用4字节(可以理解为指针,其实底层也是这样实现的)。第一步,构造三个辅助类,如表3-16 所示。

第二步,通过反射API获得修改Long和Integer类中TYPE域的方法句柄,如表3-17 所示。

第三步,通过反射API获取辅助类Union1与Union2的int域field1,如表3-18所示。

第四步,通过 invoke 的方式执行 mhl 与 mh2,也就是执行 Type Confusion这里需要注意的是,在 invoke 之前,先把 Long 与 Integer 原本的 TYPE 域记录下来,以便混淆利用之后将其恢复正常,如表3-19所示。这段代码将Long的TYPE 域设置为 int.class,同时将 Integer 的 TYPE 域设置为其他非 int 类型。混淆过后,当JVM遇到 int型变量时,会上溯到TYPE等于int.class的那个类,此时即为Long。值得注意的是,int是4字节而long是8字节,在执行后续操作时,JVM 会认为 int 类型是8 字节。

混淆工作完成后,使用反射AP1可以将Union2的SystemClass设置为真正的java.lang.System类。具体实现代码如表3-20所示。

当Field的get/set方法执行时,由于field1的声明为int型,此时JVM会认为它是8 字节的 long 型,而实际上,ul 与 u2 的 field1 都没有实际赋值,在 set方法执行时,8 字节的数据(包括4 字节的field1 和4 字节的Object指针--也就是 System.class 对象)会被拷贝到 u2 中, u2 的 field2 也就被设置为自定义的SystemClass类。原本不能被任意修改的System类,被混淆为可以任意修改的SystemClass,从而形成一个可以利用的Type Confusion.

第五步,恢复Integer与Long的TYPE域,如表3-21所示。

第六步,将securityManager对象设置为null。辅助类SystemClass是由30个Object 组成,而且已经成功混淆为真正的 System 类对象。这样通过搜索这30 个Object,总可以找到 securityManager 对象,经过不断实验发现,在Windows系统下,该对象总是稳定匹配第29 或第30 个 Object.PoC 代码如表3-22 所示。

3.2.4  CVE-2013-1493

由于 Java 是类型安全的语言,Java 具有健壮的内存异常捕获机制,假如要创建一个数组,其size最大值是由JVM限制的。例如开发者编写Java代码创建一个大小为0x7FFFFFFF的数组,编译执行,会发现Java控制台打印了异常信息"java.lang.OutOfMemoryError:Requested array size exceeds VM limit",说明JVM拒绝了这种不安全的大量内存申请。但利用CVE-2013-1493这样的漏洞,可以绕过JVM的类型安全机制,下文将给出该漏洞分析。

3.3  本章小结

本章主要介绍了 JRE 漏洞的类型,针对 Java API 设计缺陷、类型混淆、Java原生层漏洞,以及 Java Applet 自签名问题分别给出阐述,分别列举出4个漏洞:CVE-2012-4681, CVE-2012-5076, CVE-2013-2423, CVE-2013-1493,并给出漏洞原理分析。

4  JRE 漏洞挖掘研究

在软件安全领域,漏洞挖掘一直是最为热门的研究方向之一。在日趋激烈的攻防技术研究或攻防实战中,无论攻击者还是防御者,掌握漏洞挖掘技术意味着掌握了攻防的主动权。对于软件厂商和广大用户而言, Oday漏洞(特指被攻击者掌握却尚未被软件厂商修复的漏洞)是最大的潜在威胁。为了保证软件的质量,软件发布前的测试环节备受关注。如何提高测试效率,或者说提高挖掘潜在漏洞的能力,尽量避免在软件发布后出现0day漏洞,已经成为一个热门的研究方向。

4.1  针对 Java API 设计缺陷的漏洞挖掘工作

通过第三章中对 JRE 漏洞的分析,可以总结出缺陷 Java API 具备的一些特点:

1. 存在一条信任调用链(Trusted Invoke Chain)

2. API 参数可控;

3. 关键代码被 doPrivileged block 包裹;

4. 被调用后可以完成获得任意类对象、获得任意方法对象、获得任意域对象、以BootstrapClassloader来加载任意指定类等等。
所谓“信任调用链”是指,该API或者可以被直接调用,或者其本身不能被直接调用,但却间接地被其他可直接调用的 API 所调用。

由于API设计缺陷具备一些共同特征,而且源代码可以方便地获得,针对该问题的漏洞挖掘更适合于进行源代码审计。源代码审计的步骤为:

1. 分析已有 Java API 设计缺陷范例,建立漏洞模型和审计规则;

2. 确定审计对象,对于可获得源代码的版本,以源代码为审计对象,对于不可获取源代码的版本,通过逆向工程(class 文件的反编译)得到可读性较高的源代码;

3. 通过文本关键字搜索,在审计对象中提取包含doPrivileged代码块的类:

4. 对第3 步中的所有类按照制定好的规则进行人工源代码审计,匹配已建立的漏洞模型;

5. 找到疑似漏洞,尝试构造 PoC以进行漏洞验证。

4.2  针对Java原生层漏洞的漏洞挖掘工作

第二章中提到,作为一种类型安全的编程语言,JRE 提供了一系列的原生层层安全机制,如结构化的内存访问、自动化垃圾收集、数组越界检查、空指针引用检查、严格的类型转换检查等。基于这些安全机制考虑,Java被认为是一种较为安全的语言。然而近年来,JRE漏洞不断被发现,其漏洞类型包括利用Java API逻辑缺陷的沙箱绕过,还有原生层代码(Native Code)级别的漏洞,也称 JRE 原生层漏洞。

4.2.1  符号执行技术简介

在众多灰盒测试技术中,符号执行(Symbolic Execution)是一种代码执行空间遍历技术,早在1975年就由Boyer等人提出,并将其用于程序测试和调试领域。但是由于当时硬件条件不能满足符号执行所需的计算能力,该技术并没有得到广泛采用。随着硬件技术的快速发展,符号执行又被重新提出,并广泛应用于程序分析、漏洞挖掘等领域。

符号执行是用抽象符号代替程序变量,根据程序的语义,在每条路径上通过符号执行引擎对抽象符号作收集、合并、归约等计算,最终得出每条路径的路径条件。从数学的角度来看,就是一个包含符号和运算符的逻辑表达式。

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

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

相关文章

ArcGIS学习总结(19)——要素转点与空间连接(属性表字段映射)

1.在新创建的面矢量数据的属性表中没有对应的字段信息,为了能够和有属性信息的数据进行匹配,使其具有对应字段的信息。 2.需要匹配的矢量文件属性表信息。 3.对新创建的矢量文件执行要素转点:数据管理工具→要素→要素转点。 4.选择分析工…

基于CH552G主控的开源九键小键盘(资料齐全)

Content 1. 前言2. CH55X Arduino平台环境搭建2.1 常规安装2.2 HFS挂载本地服务器安装 3. 例程使用3.1 工程下载及编译3.2 程序烧录 1. 前言 芯片选型:CH552G 本文主要解决Arduino下CH552G芯片包的环境配置问题 开源地址:CV键盘有线小键盘 - 嘉立创ED…

变量函数及销毁函数中的变量-PHP8知识详解

今天分享php8知识详解中的变量函数及销毁函数中的变量,以及相应的示例代码。 1、变量函数 变量函数,是指通过变量来访问的函数。当变量后有圆括号时,PHP将自动寻找与变量的值同名的函数,然后执行该函数。 变量函数引用&#xf…

【C++】AVL树(高度平衡二叉树)

AVL树 概念AVL树节点定义AVL树节点插入AVL树四种旋转情况左单旋右单旋先左单旋再右单旋先右单旋后左单旋 元素的插入及控制平衡判断最后节点是否平衡 概念 二叉搜索树虽然可以缩短查找的效率,但如果数据有序或者接近有序二叉搜索树将退化为单支树,查找元…

LeetCode面试经典150题(day 3)

169. 多数元素 难度:简单 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums …

4.19 20

服务端没有 listen,客户端发起连接建立,会发生什么? 服务端如果只 bind 了 IP 地址和端口,而没有调用 listen 的话,然后客户端对服务端发起了连接建立,服务端会回 RST 报文。 没有 listen&#x…

【HSPCIE仿真】输入网表文件(1)基本内容和基本规则

输入网表文件 1. 输入网表文件基本内容2. 输入网表文件示例3. 一些基本规则4. 数值表示5. 压缩文件格式的读取6. 参数和表达式 从HSPICE的仿真流程看,出去初始化配置过程,真正的仿真是从输入网表文件开始的。 HSPICE 根据输入网表文件( inpu…

Springboot 实践(11)Spring Cloud 与zuul 路由配置与应用

前文讲解springboot cloud与consul的服务注册与发现,为多微服务程序互联互通做了准备;那么,各个微服务之间是直接调用IP或者域名实现接口调用,还是有其他方式呢?其实,可以通过搭建zuul服务,实现…

左耳朵耗子:从一次经历谈 TIME_WAIT 的那些事

原文地址:https://coolshell.cn/articles/22263.html 今天来讲一讲TCP 的 TIME_WAIT 的问题。这个问题尽人皆知,不过,这次遇到的是不太一样的场景,前两天也解决了,正好写篇文章,顺便把 TIME_WAIT 的那些事都…

STM32入门学习之TFT_LCD显示

1.TFT_LCD简介:薄膜晶体管液晶显示器TFT_LCD(Thin Film Transistor-Liquid Crystal Display)在液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),能够有效的克服非选择时的串扰,使显示屏的静态特性与扫描线数无关…

登录校验-Filter-详解

目录 执行流程 拦截路径 过滤器链 小结 执行流程 过滤器Filter拦截到请求之后,首先执行方放行之前的逻辑,然后执行放行操作(doFilter),然后会访问对应的Web资源(对应的Controller类)&#…

【C++】进一步认识模板

🏖️作者:malloc不出对象 ⛺专栏:C的学习之路 👦个人简介:一名双非本科院校大二在读的科班编程菜鸟,努力编程只为赶上各位大佬的步伐🙈🙈 目录 前言一、非类型模板参数二、模板的特…

Java学数据结构(3)——树Tree B树 红黑树 Java标准库中的集合Set与映射Map 使用多个映射Map的案例

目录 引出B树插入insert删除remove 红黑树(red black tree)自底向上的插入自顶向下红黑树自顶向下的删除 标准库中的集合Set与映射Map关于Set接口关于Map接口TreeSet类和TreeMap类的实现使用多个映射Map:一个词典的案例方案一:使用一个Map对象方案二&…

Leetcode.75 颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函数的情况下解决这…

[管理与领导-50]:IT基层管理者 - 8项核心技能 - 5 - 沟通是润滑剂

目录 前言: 一、什么是沟通 1.1 定义 1.2 沟通模型 1.3 沟通的六层次模型 1.4 为什么需要沟通 二、沟通的五维度 三、沟通的原则 3.1 以终为始 3.2 双赢思维:人们只会做对自己有利的事 3.3 牵善的思维 四、沟通的过程 五、沟通技巧 六、深…

统计Mysql库中每个表的总行数,解决table_rows不准确问题

1、拼接SQL selectsubstring( GROUP_CONCAT(a.sf SEPARATOR ),1,length(GROUP_CONCAT(a.sf SEPARATOR ))-10) as sql_str from( select concat(select ", TABLE_name , ", count(*) as row_num from , TABLE_SCHEMA, .,TABLE_name, union all ) as sf frominformat…

matlab使用教程(25)—常微分方程(ODE)选项

1.ODE 选项摘要 解算 ODE 经常要求微调参数、调整误差容限或向求解器传递附加信息。本主题说明如何指定选项以及每个选项与哪些微分方程求解器兼容。 1.1 选项语法 使用 odeset 函数创建 options 结构体,然后将其作为第四个输入参数传递给求解器。例如&#xff0…

支付宝的支付

对于前端的入门学习的人员来说,支付宝提供的沙箱环境,可以让你体验支付的整个流程。 一、沙箱环境 沙箱(又叫沙盘)环境是用于开发者测试的模拟环境,中间发生任何行为都是虚拟的,如支付。 二、技术选型 支…

一文800字从0到1运用工具Postman快速导出python接口测试脚本

Postman的脚本可以导出多种语言的脚本,方便二次维护开发。 Python的requests库,支持python2和python3,用于发送http/https请求 使用unittest进行接口自动化测试 一、环境准备 1、安装python(使用python2或3都可以) …

前端组件库造轮子——Input组件开发教程

前端组件库造轮子——Input组件开发教程 前言 本系列旨在记录前端组件库开发经验,我们的组件库项目目前已在Github开源,下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验,开源…