Java是否有缓冲区溢出?


96

Java是否有缓冲区溢出?如果可以,可以给我一些方案吗?


2
某些库函数(以本机代码实现)已知存在错误。特别是在Java 5领域,许多2D,声音或颜色配置文件的漏洞利用都是众所周知的。
eckes 2015年

Answers:


108

由于Java字符串基于char数组,并且Java自动检查数组范围,因此仅在特殊情况下才可能发生缓冲区溢出:

  1. 如果您通过JNI调用本机代码
  2. 在JVM本身(通常用C ++编写)中
  3. 解释器或JIT编译器无法正常工作(Java字节码强制性边界检查)

24

诸如Java和C#之类的托管语言没有这些问题,但是实际运行代码的特定虚拟机(JVM / CLR / etc)可能会出现这些问题。


5
在不安全的上下文中,C#可能会发生缓冲区溢出。Java作为一种语言完全禁止这样做(您必须通过JNI更改语言才能获得未管理的指针访问)
ShuggyCoUk 2009年

1
好点子。使用不安全的C#,您显然再也不会在舒适的托管环境中沙箱了。
布赖恩·拉斯穆森

1
没错,即使您没有编写任何不安全的内容或进行任何互操作,也可以使用具有该功能的库。所以这是需要提防的事情。
BobbyShaftoe

13

出于所有意图和目的,不可以。

Java具有数组边界检查功能,它将检查无法从分配的数组之外的区域访问数据。当尝试访问超出数组大小的区域时,ArrayOutOfBounds将引发异常。

如果存在缓冲区溢出,则可能是Java虚拟机中的一个错误引起的,据我所知,这不是Java语言规范或Java虚拟机规范中编写的预期行为。


10

是的,没有。不,因为您不能真正创建错误地使自己面临缓冲区溢出漏洞,因为它是托管内存模型。但是,JVM和JDK中可能存在缓冲区溢出漏洞。请参阅此Secunia咨询:

http://secunia.com/advisories/25295

或者查看有关以前的几个JDK和JRE漏洞的这些旧建议:

  • Java运行时环境(JRE)中的整数和缓冲区溢出漏洞“ unpack200” JAR Unpacking Utility可能导致特权升级https://download.oracle.com/sunalerts/1020225.1.html

    使用“ unpack200” JAR拆包实用程序解压缩小程序和Java Web Start应用程序的Java运行时环境(JRE)中的整数和缓冲区溢出漏洞可能允许不受信任的小程序或应用程序提升特权。例如,不受信任的小程序可能会授予自己读取和写入本地文件或执行运行不受信任的小程序的用户可以访问的本地应用程序的权限。

    Sun感谢与iDefense VCP(http://labs.idefense.com/vcp/)和Google的Chris Evans 一起工作的“ regenrecht” 引起了我们的注意。

  • Sun Java Development Kit(JDK)和Java Runtime Environment(JRE)中已发现多个漏洞。https://security.gentoo.org/glsa/200705-23

    富士通安全团队报告了一个未指定的漏洞,涉及“系统类的错误使用”。此外,Google安全团队的Chris Evans报告了整数溢出,导致与JPG或BMP文件一起使用的ICC解析器中的缓冲区溢出,以及在处理某些BMP文件时对/ dev / tty的错误open()调用。


9

从严格意义上来说,覆盖堆栈或堆本身的缓冲区溢出将需要:

  1. 框架中的错误(这些错误已经存在并且可能再次发生)
  2. JNI的使用(基本上不再使用托管代码)

从某种意义上说,您有使用缓冲区的代码,并且您的代码负责正确解析缓冲区,但这样做可能会导致缓冲区溢出。例如,您可能编写了XML解析器,并且有人可以向您提供格式错误(或合法但不常见)的请求,由于解析器的设计,该请求会使用一些有效负载覆盖先前验证的数据,这会导致您的应用程序行为异常。

后一种形式不太可能,但是写得不好的sql字符串清除函数分布广泛,但存在诸如此类的问题是一个吸引人的目标。


4

Java(和.Net)虚拟机捕获试图在保留内存之外写入的代码。无法正确处理此问题的应用程序仍可能导致安全问题。如果恶意用户可以通过输入无效输入来触发异常,则他们可以进行例如拒绝服务攻击。


3

正如已经指出的那样,Java作为一种语言,对所有内存访问进行了边界检查,并且如果这里有错误,则说明JVM出错了,而不是程序出错了。但是,应该注意的是,这与Java中的内存泄漏类似。尽管无法粉碎堆栈,但在错误的地方放置了ArrayOutOfBoundsException,如果处理不正确,则可能仍然会破坏系统。


3

如果您正在使用Java Native Interace(JNI)工具来调用外部代码,并且外部代码存在可利用的问题,则可能导致Java程序中的缓冲区溢出。这是相当罕见的,因为大多数应用程序都尽可能避免使用JNI。


3

方法有可能通常通过整数溢出将其不打算写入的有效条目写入数组。

例如,以下内容不足以检查界限:

/* !! WRONG !! */ 0 <= off && 0 <= len && off+len <= buff.length /* !! WRONG !! */

IIRC StringBuffer曾经有一个类似的错误,但是您无法使用它做任何有趣的事情。


什么足够的检查范围?
Broam 2010年

1
@布鲁克:0 <= off && 0 <= len && off <= buff.length-len我想。不要引用我 看起来一样,但是没有可能的溢出(在原始的off + len中可能为负,因此显然小于数组长度)。确保没有维护程序员曾经将其“整理”成明显的形式。我发现整数溢出非常令人困惑。必须考虑一会儿,然后会有the的怀疑我弄错了。但是,当然,应该有另一位审阅者和原始程序员-当然,没有任何错误可以解决!(不是)
汤姆·霍顿

我不得不凝视这一点,但是你是对的。off + len可能会溢出并在C中包装。在Java中,除非我弄错了,否则您会在溢出发生之前得到溢出异常,对吗?
Broam 2010年

1
不。整数算术默默地回绕。C#有一个“模式”,在溢出时会引发异常,但是我认为它的使用率不高(如果您想使用它,那么您可能会想做正确的事情)。
Tom Hawtin-大头钉

1

JAVA的主要功能之一是安全性。用解释性语言编写的程序不容易受到缓冲区溢出攻击,但是您总是可以在Interpreter本身中引起缓冲区溢出。虽然会很困难。同样,Python也是一种解释性语言,可以防止缓冲区溢出。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.