Generally, there’ll be one major Java vulnerability making the news every three months or so, the last one I believe was in August, and I’ve been watching the advisories, watching the INFOSEC professionals give their stock advice on disabling/updating Java, watching pundits complain about how terrible the security of Java is without elaborating on why. It’s the ‘why’ that I’ve been asking myself for a while. How exactly does something like the Neutrino crimeware exploit Java to hold victims’ computers to ransom?
The First Steps to Understanding Java Vulnerabilities
Java uses a runtime environment (the JVM), an interpreter that enables programs written in the language to run on any host system, with a comprehensive library of classes, methods and functions that get interpreted into the host system’s native instructions. While Java applications themselves don’t interact directly with the host system, the JVM certainly does, and to make the Java interpreter reasonably secure, the implementation for each operation would need something like buffer overflow, input validation and format protection, and this is where I suspected there were problems.
This brings me to the next point: the Java runtime environment itself isn’t normally sandboxed or coded in Java, so it has roughly the same access to memory as other software applications on the system, plus the runtime environment might also run with system privileges, so it’s theoretically possible to get malcode running on the system by exploiting the JVM in the same way as any other program. The CERT Blog does suggest that C/C++ implementation exploits are common with Java.
In addition, the JRE/JVM is able to interact with the web browser through plugins, which gives the attacker a way of launching exploits from compromised web servers.
If the above type of exploit is common, it doesn’t mean the JVM is inherently insecure, or that it has more vulnerabilities per x lines of code. The problem is that attackers have more to gain by targeting it in preference to other applications. Sure, we could disable or remove Java, but then we’re left with Flash Player and other things the attackers could move onto. Basically that road leads to stripping down our browsers’ capabilities.
Reflection API Bugs
Java itself was designed to be more secure from the start, and has two security features that I’m aware of: ‘sandboxing’ and the System.securityManager API class (a class being just a template for creating methods/functions of a given type). According to the CERT Blog, the latter prevents untrusted Java applications accessing local files, loading additional code or communicating with Internet addresses other than those they originated from.
However, Java also has something called the ‘Reflection’ API, which has provided a way around these security features. What’s supposed to happen is the Reflection class enables a Java program or applet to reveal information about itself, and the SecurityManager would apply the usual access controls to protect private and JVM internal classes.
The other exploit, which occurred a few months before this, in August 2012, was similar. It also used Reflection to access private native JVM classes to disable SecurityManager before creating another object outside the sandbox.
Very specific methods were used for achieving this in both cases.
I examined Crimepack 2.0, which had 14 exploits in total. The following were listed for Java:
* javagetval (Java getValue Remote Code Execution)
* javanew (JRE ‘WebStart’ RCE)
* javaold (Java Deserialize)
A similar manifest probably exists for BlackHole, but as with half the crimeware kits I’ve looked at, its source is encrypted using ionCube, so we’d only know by running BlackHole on an isolated system (just in case there are any nasty surprises).
Java Web Start (JAWS)
One way of knowing that I’m barking up the right tree is the Crimepack reference to ‘Java Web Start’. This enables the user to click on some link in the browser and automatically execute whatever Java program it’s pointing to, along with a JNLP file that specifies other dependencies to fetch.
Theoretically this is safe, as the program is sandboxed and access is controlled again by SecurityManager. In practice, however, it’s another avenue for exploiting the kind of vulnerabilities I’ve already discussed. As I understand it, a recent exploit (code here) uses a string sanitation vulnerability in JNLP to add an option to an .exe command that fetches a malicious DLL from a remote source.
JDWP Arbitrary Java Code Execution
As it happens, the Java system has an optional feature allows for remote debugging with the JVM over port 8000, and on the local machine by another process connecting to that port. It’s as simple as establishing a connection to the target IP address then entering whatever other commands:
$jdb -attach x.x.x.x:8000
According to the Exploit DB entry I found, the classpath command will reveal the host OS and the Java programs currently loaded. Using the classes and methods commands, a list of available classes and their methods can be displayed, and if I’m reading the author correctly, it’s also possible to use breakpoints to interrupt a running thread (which could be for a trusted program) and insert whatever methods for an exploit.
One thing that isn’t mentioned is authentication. Since the Java Debug Wire Protocol is stateless, each packet communicated is a stand-alone command or reply, with apparently no way to determine which packets are part of a session.
I could be wrong, but from where I’m standing this looks very much like a backdoor that’s dangerously exposed.