2008-04-26

【翻译】JRE的三类缓冲区溢出

关键字: jre的三类缓冲区溢出
有些人认为,用java写代码是一个银弹,可以预防执行出现的缺陷,如缓冲区溢出。真理有点小明朗。当然,在纯jva代码中并没有提供溢出的例子,除了在数组的最后进行读写操作。下面是一段代码示例:
public class overflow{ 
public static void main(String args[]) {  
char buf[] = new char[10];  
String src=http://anonymouse.org/cgi-bin/anon-www.cgi/http://heasman.blogspot.com/2007/01/args[0];  
for (int i = 0; i < src.length(); i++)  {    
      buf[i] = src.charAt(i);  
     }    
System.out.println("buf is " + new String(buf)); 
  }
}

引用

C:\dev>java overflow foobar1234
buf is foobar1234

C:\dev>java overflow foobar12345
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at overflow.main(overflow.java:10)


但真正的代码,虽然它可能100 %用Java 写,但在很大程度上取决于该运行时间环境( JRE环境)和JRE包含的用整洁的C写的方法。当C与它的朋友(buddies)挂起了:固定大小缓冲区, strcpy和用户输入,大家都会知道发生什么事。
因此,你怎么甚至开始去评估着攻击JRE的表层?或许,在未来某时,我们会进行更详细的讨论。但现在,简单说,如果我们舍弃JRE合理的逻辑,以至让你摆脱沙盒效应(sandbox)(如企图措施,接触到这些,实在是很难)以及唯一地集中在机器码(native code)部分。

•确定机器码内部的JRE数量

1、下载Java源代码和搜索JNIEXPORT 和 JNICALL等宏检测本地方法,如:
src/share/native/sun/awt/image/gif/gifdecoder.c:
JNIEXPORT jboolean JNICALL 
Java_sun_awt_image_GifImageDecoder_parseImage(JNIEnv *env, 
jobject this, 
jint relx, jint rely, 
jint width, jint height, 
jint interlace, 
jint initCodeSize, 
jbyteArray blockh, 
jbyteArray raslineh, 
jobject cmh)
{
...


2、又或者转储出口的DLL内部的JRE bin目录,如:
引用

C:\dev> dumpbin /exports jpeg.dll | findstr /c:"_Java_"

_Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abortRead@16
_Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_disposeReader@16
_Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader@8
_Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initReaderIDs@20
_Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage@80

3、或者在运行时间和累计那些标识为本地(native)中的所有类中的所有方法。这是可以做到在一个几行代码中使用字节码工程库[the Byte Code Engineering Library (BCEL)], 一个伟大工程的低水平操作和建设的类(classes)。

•以一份本地方法执行静态分析,以评价每种方法应包含多少代码(包括在所有函数调用中的所有代码),以及在此过程数据可能不受信任等等。

·现在跟踪(trace)或执行静态分析你的应用程序,小应用程序(Applet),Servlet等,以确定你要用哪个方法。

但我偏题了,这篇最主要的一点是要突出三类存在于JRE的缓冲区溢出,因此,介绍如下:
1、在文件格式解析器中的缓冲区溢出

通常,无论是速度,还是因为代码源于其他地方,大部分的JRE文件格式解析代码是落实在机器码。这包括BMP, GIF, JPEG, ICC, TTF,和Soundbank,以及几个我已经大概忘记了。

顺便提一句,当运行一个Java应用程序(它会发生Burp Proxy,认真!)开始崩溃,离开熟悉的hs_err.log文件的后。记录表明,我触发了违规存取fontmanager.dll,
据此,我跟踪到了曾在我字体(Fonts)文件夹中的一个损坏的TrueType字型(TrueType的解析很难,他由一个16和32位字段,长度,偏移并限定的混合体,提供的一个虚拟机)。
Chris Evans在bugs的发现方面做了伟大的工作,他发现JRE的解析器的文章如下:
http://scary.beasts.org/security/CESA-2005-008.txt
以及http://anonymouse.org/cgi-bin/anon-www.cgi/http://scary.beasts.org/security/CESA-2006-004.html

2、在API平台包装代码中的缓冲区溢出

除了文件格式解析器,方法与操作系统互动也最终落实在机器码,因为他们需要调用适当的平台API 。这些方法通常需要转换为Java的数据类型,如一个字符串转到一个C数据类型,如一个宽字符数组。听起来像一个有潜在危险的行动?我的同事,他们工作于 NGS, Wade Alcorn ("The King of BeEf") and Marcus Pinto(Web应用黑客的手册),他们在使用BEA的 JRockit JVM时发现了这样的一个bug。这里提供了NGS的建议。这个问题可能引发的是远端作为一个未经允许的用户对WebLogic Server请求一个长的URL ( ! ),这个将作为路径触发缓冲区溢出。

3、在底层平台API上的缓冲区溢出

前类别在提交到平台API之前来自于不安全的预处理数据。让我们考虑相反的情况,在一个平台API上,做任何处理和揭露bug。这一类的一个显着例子是NGS工作的另一个同事Peter Winter-Smith发现的一个重要弱点。他发现了可能通过65536个字节串触发对gethostbyname的溢出,由ws2_32.dll输口。这问题固定在MS06-041 。它是琐细的引起Java代码击中这个bug。
现在,您可能会以为这不是真的公平,声称这是一个Java的问题,因为这显然是操作系统第三方库的bug。也许是不公平的: )。有趣的是,在JRE的某些地方,在平台API的顶层设计如此薄弱,以至出现了这类bug(当测试Java应用程序,我认为Peter实际上发现了gethostbyname的bug了)时,并注意这会更进一步使攻击表面分析复杂化:(

结束语关于这些影响Java应用程序的不同的类型。例子(2)在可以用于妥协服务器的Java运行时间给了,是缓冲溢出的一个清晰例子。例子(1)和(3)则不如此。其可行性是Java企业应用程序可能会由用户解析上载的文件,但是它明显地取决于servlet的目的。另一方面,在JRE中,一个恶意附属程序试图通过一个文件格式bug利用浏览器是一定可以想像的。
至于移动Java ,其运行时的实现通常不会与桌面的JRE共享机器码组件 ,所以作为一个征服了所有的跨设备跨架构跨Java实现的脆弱性的机会是相当渺茫的(尽管消息相反) 。虽然我将几乎说不可能:)

注:此blog由John Heasman 写的
Three Categories of Buffer Overflow in the JRE
评论
发表评论

您还没有登录,请登录后发表评论

ivorytower
  • 浏览: 4203 次
  • 性别: Icon_minigender_1
  • 来自: 广东深圳
  • 详细资料
搜索本博客
我的相册
8b2adae2-a0e4-39df-b256-3a039a2e12d2-thumb
screenshotthumb
共 6 张
存档
最新评论