It's been almost a year since we revealed our Binary Planting research project which identified 520+ remote execution vulnerabilities in almost all Windows applications. During this period, hundreds of binary planting vulnerabilities have been publicly reported and some have actually been fixed.
While some in the security community still seem to have a hard time understanding that binary planting doesn't only affect the loading of libraries but also stand-alone executables, we went further and "extended" the problem to all file types. This blog post reveals an interesting sample from our current research on what we call File Planting.
Java Hotspot VM Configuration Files
The current Oracle's Java Runtime Environment (version 6, update 26) - just like its previous versions - supports so-called Hotspot configuration files .hotspotrc and .hotspot_compiler. These files are loaded when Java virtual machine is initialized and can specify (or override) the VM settings that are usually provided as command-line parameters for java.exe or exclude chosen methods from compilation, respectively.
Now this would be just fine... if JRE didn't try to load these configuration files from - you guessed it - the current working directory. So if the current working directory (which we now all know can point to various locations, including a remote share on attacker's server) contains these configuration files, they will be loaded and will influence the way Java virtual machine behaves.
We focused our analysis on the .hotspotrc file since fiddling with VM settings seemed more promising from the security point of view. And indeed, we quickly located a VM setting that can be exploited for launching arbitrary executable: OnOutOfMemoryError. This setting allows one to specify user-defined commands that get ran in case JRE runs out of memory, or more specifically when the OutOfMemoryError error is thrown for the first time. Therefore:
Java code that exhausts all available memory
launching of malicious.exe.
Now, how does one set the current working directory for JRE to an attacker-controlled location? Normally, when Java applications are launched either manually or as a service, this is rather difficult if possible at all: in the former case, the current working directory is set to the location of user's command-line window and in the latter case, the current working directory is inherited from the parent process and can not be influenced by a low-privileged - much less remote - attacker.
The game changes, as it often does, in web browsers. All major web browsers support Java, and can load and execute a remote Java applet inside a web page.
Exploiting The Bug
For this experiment we need four files, which you can find neatly packed on our web page:
- .hotspotrc : a Java configuration file with a single line OnOutOfMemoryError="malicious.exe"
- Test.class : a Java applet that consumes all available memory (ours simply concatenates a string to itself many many times)
- Test.html : an HTML document that loads the applet
- malicious.exe : the executable to get executed
Suppose the current version of Apple Safari (5.0.5) is our default web browser. If we put the above files in the same directory (on a local drive or a remote share) and double-click Test.html, what happens is the following:
- Safari gets launched and sets its current working directory to the location of Test.html. (Not intentionally - Windows Explorer sets the CWD this way for all launched applications.)
- Safari loads and renders Test.html from our directory.
- Test.html invokes a Java applet called Test.class, triggering the initialization of the Java virtual machine.
- jvm.dll, the Java Hotspot Client virtual machine running inside the Safari process, loads .hotspotrc from our directory, parses it and employs the OnOutOfMemoryError setting found inside.
- jvm.dll loads the Java applet Test.class from our directory and executes it inside the Safari process, causing an OutOfMemoryError error within seconds.
- jvm.dll responds to the OutOfMemoryError error according to the OnOutOfMemoryError setting and launches malicious.exe from our directory using a CreateProcess call.
The attack can be mounted in the same way through Mozilla Firefox (any version), with the slight difference that Firefox actually launches an external java.exe process, which then runs malicious.exe. Furthermore, this attack can also be mounted through Internet Explorer or Google Chrome, although these set their current working directory to some safe location, meaning extra work for the attacker. (More on this some other time.)
Similarly to binary planting attacks, this file planting attack can also be mounted from a remote share, even from a WebDAV share on an Internet server. Since the malicious executable is launched with CreateProcess, there will be no security warning due to launching a remote file.
Note that neither Safari nor Firefox, nor any other web browsers are at fault here. They merely play the role of an attack delivery vehicle, while the security error is in Oracle's code.
File Planting vs. Binary Planting
File planting has a common attribute with binary planting in that files (data files or binaries) are loaded from the current working directory, which the attacker can control and thus plant a malicious file. Two major differences between file planting an binary planting, however, are:
First, a binary planting exploit looks the same in 99% of cases. If an application is willing to load your DLL or launch your EXE, you simply plant a generic malicious DLL/EXE and it almost always works. In a file planting attack, you have to understand the context of the file, what the application does with it and how (if at all) your ability to plant the file can be leveraged to mount a decent attack.
Second, some binary planting attacks can be blocked by firewalls that don't let computers in internal networks download executables from the Internet (based on files' extensions or content), and by web browsers that block downloading of such potentially dangerous files. With file planting, there can be no predefined rule to recognize a potentially malicious data file.
There are also many other interesting, significant as well as subtle differences between the two, but let this be enough for now.
What Should Oracle Do To Fix This Bug?
JRE should stop loading its configuration files from the current working directory, at least on Windows. This may not be so easy to do as some developers and their applications likely depend on this feature and doing so might break these applications. A fairly risky compromise would be to prevent loading of configuration files from the current working directory when JRE is invoked from web browsers, which would address the scope presented here. The risk would be that some other applications may also launch or integrate JRE and may thus provide a similar attack vector. A thorough functional and security analysis of this issue is thus inevitable if Oracle wants to fix this bug properly.
(Credits for research presented here goes to my colleagues, security researchers at ACROS Security: Jure Skofic for developing the uber vulnerability detector and Simon Raner for a great analysis of this vulnerability.)