关于Java getSoundBank函数堆栈溢出漏洞(一)

2014-11-23 23:26:15 · 作者: · 浏览: 3

Inking的自留地

:: 漏洞原理

确切的说,错误函数为Java的Native方法Java.com.sun.media.sound.HeadspaceSoundbank.nOpenResource。该函数在拷贝文件路径时没有检查字符串大小而直接进行了拷贝,最终导致了栈溢出:

// $$kk: 04.11.99: we are never calling XFileClose!!
JNIEXPORT jlong JNICALL
Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource(JNIEnv* e, jobject thisObj, jstring path)
{
XFILE file = NULL;
XFILENAME xfilename;

const char *str = (*e)->GetStringUTFChars(e, path, 0);

TRACE0("Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource. ");

XConvertNativeFileToXFILENAME((void *)str, &xfilename);
file = XFileOpenResource(&xfilename, TRUE);

(*e)->ReleaseStringUTFChars(e, path, str);

TRACE1("Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource completed, returning %lu. ", file);

return (jlong) (INT_PTR) file;
}

// given a native file spec (FSSpec for MacOS, and C string for WinOS, fill in a XFILENAME
void XConvertNativeFileToXFILENAME(void *file, XFILENAME *xfile)
{
if (xfile)
{
XSetMemory(xfile, (INT32)sizeof(XFILENAME), 0);
}
if (file)
{
#if USE_HAE_EXTERNAL_API == TRUE
{
void *dest;

dest = &xfile->theFile;
HAE_CopyFileNameNative(file, dest);
}
#else
#if X_PLATFORM == X_MACINTOSH
xfile->theFile = *((FSSpec *)file);
#endif
#if ( (X_PLATFORM == X_WINDOWS) ||
(X_PLATFORM == X_WIN_HARDWARE) ||
(X_PLATFORM == X_BE) ||
(X_PLATFORM == X_SOLARIS) ||
(X_PLATFORM == X_LINUX) ||
(X_PLATFORM == X_NAVIO) )
XStrCpy((char *)xfile->theFile, (char *)file);
#endif
#endif
}
}

struct XFILENAME
{
// public platform specific
#if X_PLATFORM == X_MACINTOSH
XFILE_HANDLE fileReference;
FSSpec theFile;
#endif
#if ( (X_PLATFORM == X_WINDOWS) ||
(X_PLATFORM == X_WIN_HARDWARE) ||
(X_PLATFORM == X_WEBTV) ||
(X_PLATFORM == X_BE) ||
(X_PLATFORM == X_SOLARIS) ||
(X_PLATFORM == X_LINUX) ||
(X_PLATFORM == X_NAVIO) )
/* $$fb 2002-02-14: itanium port */
XFILE_HANDLE fileReference;
char theFile[FILE_NAME_LENGTH]; // "C" string name for path
#endif

// private variables. Zero out before calling functions
INT32 fileva lidID;
XBOOL resourceFile;

XPTR pResourceData; // if file is memory based
INT32 resMemLength; // length of memory resource file
INT32 resMemOffset; // current offset of memory resource file
XBOOL readOnly; // TRUE then file is read only
XBOOL allowMemCopy; // if TRUE, when a memory based resource is
// read, a copy will be created otherwise
// its just a pointer into the larger memory resource
// file
XFILE_CACHED_ITEM memoryCacheEntry;
XFILERESOURCECACHE *pCache; // if file has been cached this will point to it
};
typedef struct XFILENAME XFILENAME;
typedef void * XFILE;

// standard strcpy
// Copies C string src into dest
char * XStrCpy(char *dest, char *src)
{
char *sav;

sav = dest;
if (src == NULL)
{
src = "";
}
if (dest)
{
while (*src)
{
*dest++ = *src++;
}
*dest = 0;
}
return sav;
}

以上FILE_NAME_LENGTH在windows下为_MAX_PATH,也就是256,所以只要url->filename大于256就溢出了。还有一个关键点:

HeadspaceSoundbank(URL url) throws IOException {

if(Printer.trace) Printer.trace("HeadspaceSoundbank: constructor: url: " + url);

String protocol = url.getProtocol();
if ( ! (protocol.equals("file")) ) {

InputStream stream = url.openStream();
try {
initialize(stream, false);
} catch (IllegalArgum