【翻译】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));
}
}

[quote]
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)
[/quote]

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

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

1、下载[url=http://www.sun.com/software/opensource/java/index.jsp]Java源代码[/url]和搜索[url=https://java.sun.com/docs/books/jni/html/types.html#46915]JNIEXPORT 和 JNICALL[/url]等宏检测本地方法,如:
[url=http://anonymouse.org/cgi-bin/anon-www.cgi/https://openjdk.dev.java.net/source/browse/openjdk/jdk/trunk/jdk/src/share/native/sun/awt/image/gif/gifdecoder.c?rev=257&view=markup]src/share/native/sun/awt/image/gif/gifdecoder.c:[/url]


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目录,如:
[quote]
C:\dev> dumpbin /exports jpeg.dll | findstr /c:”_Java_”
[/quote]


_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、或者在运行时间和累计那些标识为[url=http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#1513]本地[/url](native)中的所有类中的所有方法。这是可以做到在一个几行代码中使用字节码工程库[[url=http://jakarta.apache.org/bcel/]the Byte Code Engineering Library [/url](BCEL)], 一个伟大工程的低水平操作和建设的类(classes)。

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

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

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

通常,无论是速度,还是因为代码源于其他地方,大部分的JRE文件格式解析代码是落实在机器码。这包括BMP, GIF, JPEG, ICC, TTF,和[url=http://java.sun.com/products/java-media/sound/soundbanks.html]Soundbank[/url],以及几个我已经大概忘记了。

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

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

除了文件格式解析器,方法与操作系统互动也最终落实在机器码,因为他们需要调用适当的平台API 。这些方法通常需要转换为Java的数据类型,如一个[url=http://java.sun.com/javase/6/docs/api/java/lang/String.html]字符串[/url]转到一个C数据类型,如一个宽字符数组。听起来像一个有潜在危险的行动?我的同事,他们工作于 NGS, Wade Alcorn (“[url=http://www.bindshell.net/tools/beef/]The King of BeEf[/url]”) and Marcus Pinto([url=http://as.wiley.com/WileyCDA/WileyTitle/productCd-0470170778.html]Web应用黑客的手册[/url]),他们在使用BEA的 [url=http://www.bea.com/framework.jsp?CNT=index.htm&FP=/content/products/weblogic/jrockit/]JRockit[/url] JVM时发现了这样的一个bug。这里提供了NGS的[url=http://www.ngssoftware.com/advisories/high-risk-vulnerability-in-jrockit-java-virtual-machine/]建议[/url]。这个问题可能引发的是远端作为一个未经允许的用户对[url=http://www.bea.com/framework.jsp?CNT=index.htm&FP=/content/products/weblogic/server/]WebLogic Server[/url]请求一个长的URL ( ! ),这个将作为路径触发缓冲区溢出。

[b]3、在底层平台API上的缓冲区溢出[/b]

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

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

注:此blog由John Heasman 写的
[url=http://anonymouse.org/cgi-bin/anon-www.cgi/http://heasman.blogspot.com/2007/01/three-categories-of-buffer-overflow-in.html]Three Categories of Buffer Overflow in the JRE[/url]

« »

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *