Friday, November 23, 2012

AnonymousClassLoader Java Exploitation Technique

Author Information

This technical article was written by Immunity's Chief Java Interrogator,  Esteban (who you can follow: @sagar38)

Introduction

Not so long ago Oracle released a new Java update [1] that included 30 security fixes. Many of those fixes appear to be the result of the research conducted by Security Explorations [3] who in turn informed Oracle. The research paper clearly explains the vulnerabilities discovered and some generic exploitation scenarios and techniques. Instead of analyzing the vulnerabilities we'll discuss something that is really interesting and was recently used in the JAX-WS exploit (CVE-2012-5076) that was found in the wild [4].

This time besides killing bugs, Oracle also killed an “exploitation technique”.

We haven't seen any articles or papers explaining this technique, so now that it has been used in the wild and is publicly available, we think it is worth explaining in detail. This Oracle patch has changed a class that could be used to exploit a target if the right bug primitives were available. This technique will only work from JRE/JDK 7 up to JRE/JDK 7 update 7.

The technique explained here has been used in our two latest CANVAS Java exploits. And remember that if you want to learn this kind of Java stuff you can join us during the next Infiltrate at the Master Class being taught in part by Esteban!

Background

Is a well known fact that there are certain packages that are restricted when working with Applets. So any class inside sun.* package is a tempting destination if we have a vulnerability that bypasses the restrictions. Lets assume we have a couple of vulnerabilities which give us the primitives to:
    1) Create an instance of any class in any package (for example something in sun.*)

    2) Call any public method on the instance we create, for example by using reflection and bypassing security checks.

Even if we have all that, we need to find a way of fully exploiting the target because having access to restricted packages doesn't mean we can just disable the Security Manager.

In 2010 Sami Koivu explained [5] a really cool vulnerability class that worked because a “Trusted execution chain” was built. The security checks were then passed simply because all the callers in the stack were part of the JDK and had enough permissions. The first question is “how do we start a trusted chain?”

The trick Koivu used to “start” the trusted execution chain was to create a javax.swing.JList instance, passing an object to it and then adding the instance to the applet. What happens then is that an AWT thread (that is trusted) would render that JList instance and would eventually call the toString() method on the object we put inside the JList.

It is important to keep Koivu's technique in mind because it will help to better understand part of the AnonymousClassLoader technique.

Analyzing the Patch

A quick diff performed against the two latest JDK 7 versions: update 7 and update 9 will show that there are a lot of changes to several classes in order to fix may vulnerabilities and one class that gets our attention is sun.invoke.anon.AnonymousClassLoader. The differences between these JDKs can be obtained for example using reJ tool [6], but we can also find the patch by taking a look at the OpenJDK repositories [7] [8].

Although OpenJDK is not Sun's implementation it is really useful when auditing new JDK releases since parts of the Sun JDK source are not included in the releases. In the OpenJDK patch for CVE-2012-5088 [8] we can see the exact change made to the sun.invoke.anon.AnonymousClassLoader.

AnonymousClassLoader Technique

A curious thing to notice is that although this class seems to be a “class loader” it does not inherit from java.lang.ClassLoader. If we take a look at the java.lang.ClassLoader type hierarchy, the AnonymousClassLoader is not listed:

The changes made to this class show that its public constructors were removed together with other methods. We all know that ClassLoaders are important when it comes to exploitation so this “strange” class loader seems to be worth taking a look at.

According to its documentation and from what I've researched [9] [10] [11], this class does some weird things that will allow us (the attacker) to load classes that we can then use to bypass security checks. The classes that are loaded with AnonymousClassLoader appear not to be registered since this is not a normal class loader. The first thing we notice from the AnonymousClassLoader source code [12] is that it has an attribute called hostClass which is very important. The class documentation says:
The access permissions of the anonymous class are borrowed from a host class.  The new class behaves as if it were an inner class of the host class.  It can access the host's private members, if the creator of the class loader has permission to do so (or to create accessible reflective objects).
Depending on the hostClass, the classes that we load with AnonymousClassLoader could possibly inherit privileged protection domains!

If we take a look at the default constructor (the one without parameters), it calls sun.invoke.anon.AnonymousClassLoader.checkHostClass method with a null parameter. When that happens, the hostClass is set to the constructor's immediate caller. You can see this at the beginning of the checkHostClass implementation:

private static Class<?> checkHostClass(Class<?> hostClass) {
        // called only from the constructor
        // does a context-sensitive check on caller class
        // CC[0..3] = {Reflection, this.checkHostClass, this.<init>, caller}
        Class<?> caller = sun.reflect.Reflection.getCallerClass(CHC_CALLERS);

        if (caller == null) {
            // called from the JVM directly
            if (hostClass == null)
                return AnonymousClassLoader.class; // anything central will do
            return hostClass;
        }

        if (hostClass == null)
            hostClass = caller; // default value is caller itself

        [...]
 }

This means that if the AnonymousClassLoader default constructor is called from any class that is part of the JDK, then its immediate caller will be considered trusted and hostClass will have privileged protection domains.

And more importantly, any class that we load with the AnonymousClassLoader instance will have a privileged protection domain and if we use this with Koivu's JList rendering trick to start a “Trusted execution chain” [5] we'll be able to disable the Security Manager.

What we can do now is make use of the public method sun.invoke.anon.AnonymousClassLoader.loadClass(byte[]) that receives a byte array containing a class (this is just a valid .class file that we read and store in a byte array or a class file from our JAR file that is obtained as a stream and converted to a byte array). This loadClass method will return a Class object and after that we can simply call objclass.newInstance() on it.

Remember we mentioned we need two primitives, so the first one would be used to create an instance of AnonymousClassLoader which is in sun.* and satisfies our first requirement.
What would probably happen with a vulnerability that provides such primitive is that the instance we get is an Object reference and unfortunately AnonymousClassLoader does not implement an interface so we don't have anything to easily call the “loadClass” method and a cast operation would just fail. This is where the second primitive comes in play!

As we mentioned before, if we wanted to call any method in this object variable we would need to cast it like this:

((AnonymousClassLoader)obj).loadClass(bytes);

This will not work! :(

The cast operation will raise an exception because we cannot access sun.invoke.anon package from the applet. If we simply tried to call getMethod/getMethod on the instance we have, we would also get the same exception.

So the second primitive would have to allow us to bypass the security checks and get a Method instance that is a reference to that loadClass public method we want to call. An example of a such primitive is one of the vulnerabilities used in the CVE-2012-4681 exploit [13].
Using this vulnerability as the second primitive we would obtain the method reference and load any class we wanted with the following piece of code where the “acl” variable is our AnonymousClassLoader instance created with the first primitive:


Class objclazz = acl.getClass();
Method m = com.sun.beans.finder.MethodFinder.findMethod(objclazz, "loadClass", byte[].class); 
smd_class = (Class) m.invoke(cl, smd_bytes);
Object x = smd_class.newInstance();


What class should we load using this AnonymousClassLoader?


We need a fully trusted execution chain to disable the security manager and the only public trick that still works is the JList approach that calls a toString method on any object we pass it. We have to create a class with just a toString method that executes “System.setSecurityManager(null);”. Such a class is something as simple as this:

public class SecurityManagerDisabler {
 
 public String toString() {
  System.setSecurityManager(null);
  return "";
 }
}

That we compile that to generate a valid .class file and then read it to create a byte array we can hard-code in our exploit. This byte array would be the “smd_bytes” variable in the code snippet shown above when calling the loadClass method.

Once we have an instance of this class that disables the security manager we create a JList instance containing our object and add it to the applet so the AWT thread renders it and calls our toString method resulting in a trusted execution chain. The code to achieve this is just 2 lines (where “x” is this custom class instance we created in the previous code snippet):

JList l = new JList(new Object[] {x});
add(l);

This works and the complete call stack is trusted because our class was created with the AnonymousClassLoader and inherited the protection domain from a class that is part of the JDK.
An example of the complete stack call when using this technique would look like this:





Our custom class SecurityManagerDisabler is there and it has full privileges so the call to System.setSecurityManager will succeed.

An important thing to keep in mind about the AWT thread is that it may take a little bit until it effectively renders the Jlist object so we need to take this into consideration before executing our payload. One possibility is to launch another thread that sleeps for a bit and the executes the payload. Though we have to be careful not to call Thread.sleep directly in our applet init or start methods because the AWT thread may be delayed waiting for them.

Some of you may consider that using the JList trick is too much, so there is another more straight forward approach that can be used here. The class loaded with the AnonymousClassLoader could be something like this:

public class SecurityManagerDisabler implements PrivilegedExceptionAction
{
  public SecurityManagerDisabler() { }

  public Object run() throws Exception {
    System.setSecurityManager(null);
    return null;
  }

  public String toString() {
    try {
 AccessController.doPrivileged(this);
    } catch (PrivilegedActionException e) {}
    return "";
  }
}

The difference here is that the class is implementing the interface PrivilegedExceptionAction and the toString method is using a doPrivileged block.

If you remember how the security checks are performed – which are clearly explained in the Secure Code Guidelines, section 9 [14] – when there is a doPrivileged block only the immediate caller is considered. So in this case, the immediate caller would be the SecurityManagerDisabler.toString method which has full privileges because we loaded the class with the AnonymousClassLoader allowing this way to perform any action. Now instead of creating the JList and adding our SecurityManagerDisabler instance we could directly call its toString method and everything will work just fine.

One important thing about the AnonymousClassLoader is that it is only available since JDK 7 and it has been moved to different packages in different versions [15]. JDK 7 included the class in package sun.dyn.anon but since JDK 7 update 1 the class is now included in package sun.invoke.anon, so one must be careful when targeting different JRE/JDK versions in order to get the AnonymousClassLoader from the right package.


References

  1. Java 7 update 9 release notes - http://www.oracle.com/technetwork/java/javase/7u9-relnotes-1863279.html
  2. Oracle Java SE Critical Patch Update Advisory - October 2012 - http://www.oracle.com/technetwork/topics/security/javacpuoct2012-1515924.html
  3. SE-2012-01 Security vulnerabilities in Java SE - http://www.security-explorations.com/en/SE-2012-01.html
  4. CVE-2012-5076 Java sample from "Cool" exploit pack - http://contagiodump.blogspot.com.ar/2012/11/cve-2012-5076-java-sample-from-cool.html
  5. Sami Koivu's Blog - Java Trusted Method Chaining (CVE-2010-0840/ZDI-10-056) - http://slightlyrandombrokenthoughts.blogspot.com.ar/2010/04/java-trusted-method-chaining-cve-, 2010.html
  6. reJ - http://rejava.sourceforge.net/
  7. CVE-2012-5088 OpenJDK: MethodHandle insufficient access control checks (Libraries, 7196190) - https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-5088
  8. 7196190: Improve method of handling MethodHandles - http://icedtea.classpath.org/hg/release/icedtea7-forest-2.3/jdk/rev/43113374306c
  9. Da Vinci project - http://openjdk.java.net/projects/mlvm/subprojects.html
  10. John Rose Oracle Blog entries: https://blogs.oracle.com/jrose/entry/notes_on_an_architecture_for, https://blogs.oracle.com/jrose/entry/dynamic_invocation_in_the_vm
  11. A First Taste of InvokeDynamic - http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
  12. Sun.invoke.anon.AnonymousClassLoader - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/invoke/anon/AnonymousClassLoader.java#AnonymousClassLoader
  13. Java 0day analysis (CVE-2012-4681) - http://immunityproducts.blogspot.com/2012/08/java-0day-analysis-cve-2012-4681.html
  14. Secure Coding Guidelines for the Java Programming Language, Version 4.0 - http://www.oracle.com/technetwork/java/seccodeguide-139067.html#9
  15. Move JSR 292 to package java.lang.invoke and adjust names - http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2011-March/004961.html

Monday, November 19, 2012

Updating the SILICA Virtual Machine

We have been asked a few times if the SILICA virtual machine can be updated. While this is mainly a general Ubuntu Linux question it can affect the usability of SILICA. Before getting into any details it is important to understand how the updating mechanism of Ubuntu works, more specifically how the updating process can affect the operational part of SILICA.

SILICA leverages Ubuntu 12.04 LTS 64bit and is supplied as a virtual machine.

The core operating system consists of a few components such as:
  • Applications
  • Kernel
  • Drivers
  • Firmware

A lot of sub-categorizing could be done in the above list but this simplified for the purpose of this post. The components we care about are the kernel, drivers and firmware. If any of those are updated this could result into an unexpected behavior of the software. Having said that a lot of users may wish to update their applications which is a big portion of the operating system and that includes packages such as the web-browser, editors and the X-environment.

Before explaining how a user may want to proceed into updating the operating system, I would like to mention that it is a good idea at this point to use the snapshot feature of VMware. This will keep a good state of the virtual machine and you will allow reverting back to the original easy, if something goes wrong. In free versions of VMware such as player this feature may not be available so you can just copy the entire virtual machine in a separate folder in your drive as a backup.

Since we have a safe way to recover our original image it is now safe to go ahead and explain how one may want to update the operating system. As mentioned above some of the packages which are of importance are the firmware, kernel and drivers. In this case we will utilize an Ubuntu tool called apt-mark which will help us prevent accidental updates of the system.

In particular we can issue the command:

apt-mark hold linux-firmware

This will mark the package linux-firmware as hold which means it will not be updated in the next system upgrade. This package may have other dependencies so this may prevent other packages of being updated, the good news is that you do not have to worry about this since Ubuntu handles it for you.

Next we need to verify that the command succeeded by executing:

dpkg --get-selections linux-firmware

That should return something like 'hold' next to the package name, which means it has successfully completed. A similar process should be followed for the rest of the packages such as the kernel files, the drivers and any other packages the user wishes to preserve. Using dpkg -l |grep 'package-name' may help identify anything of interest. For example finding the kernel package the user can issue: dpkg -l |grep -i kernel and that will return a list of kernel packages that can be preserved. One does not have to mark them all as hold. Ubuntu will protect the rest of the packages because of the dependency checking mechanism.

Finally performing a system upgrade is as simple as running apt-get upgrade. The user can also specifically update a package such as a web browser using apt-get install package-name.

The reason we do not update the kernel, driver and firmware is beyond the scope of this post but I will be glad to get into more details if someone is interested.

Friday, October 12, 2012

Resolving Hostapd issues in the new SILICA VM

[Editor's Note]

There are a lot of layers in SILICA - from the VM's hypervisor, to the Linux kernel, to the firmware and card itself. And, of course, there's SILICA (which is a pure-Python program, as you know). We often get requests to enable SILICA to run on "any card" but we've found that not having control of all parts of the stack leads to very difficult to diagnose issues - things you can't have in the wild as you are in the middle of a penetration test. Below, Alex describes in gruesome detail the process of fixing one such bug...

Resolving Hostapd issues in the new SILICA VM


Recently we moved SILICA into a new virtual machine that is based on Ubuntu 12.04. With a little bit of fine tuning SILICA is running great. However I noticed that our fake access point / impersonation wasn't working as expected. Our code leverages the hostapd daemon that allows you to create a software AP.

My first thought was that there was some kind of problem with the version of hostapd so I started by trying to update the Ubuntu version of hostapd. After a few attempts I got it to compile with the right config file and it was up and running. The problem was that for some mysterious reason the access point that I had created was not broadcasting any beacon packets. So that took me to my second thought of trying to downgrade the version of hostapd to the latest stable 0.7.3 at the time. I was previously trying 1.0. A few minutes later after compiling all the dependencies I still had the same results; no beacon packets were being sent out.

Looking a bit deeper into the issue I started checking my configuration file to see if there was some misconfiguration or change between the versions. I did notice that hostapd was utilizing a driver which was a layer of communication with the host operating systems driver. After trying different options I did not get anywhere but at this point I started thinking that there may be more to it than just a user space daemon not functioning properly. My thought was to see what will happen if I was to use the old carl9170 SILICA driver but it didn't work.

I promptly downloaded the compat-wireless drivers that matched the old version and I was up and running with a freshly built driver code base. The card was identified and loaded fine and most of the basic functionality was working and everything seemed to be back to normal so I loaded up SILICA to see if the issue was still there. I created a fake AP like I did earlier and waited on Wireshark to see if there any broadcast packets being sent out but the issue was still there. At this point I was completely lost so I decided to take up the issue with other people to see if someone else had any ideas.

After asking around a few of the kernel wireless developers and giving them a lot of dmesg outputs in Pastebin I was told that there may be some incompatibility between my card and the driver version I was using and to try and update to the latest compat-wireless. So I updated to the latest compat-wireless even though I already knew at this point that this was system related and not hostapd related.

The problem was still there no matter what version or configuration I tried.

So being left with my last resort I decided there was nothing left to do but to dive into the driver code base and see what is really happening (unfortunately). A few hours later and a lot of printk's I realized that the code that exposes the access point mode lived inside the firmware and if the firmware did not support that then the driver will give you access to all the other features but that. Luckily the firmware for carl9170 is open source and I already had the latest git checked out on my system. I went through the build configuration and I enabled some features and cross-compiled the code. The driver handles the uploading into the device so I quickly reloaded the kernel module.

At this point I had a fresh firmware that I had built from the git running on my wireless card. I loaded up SILICA again and started the Fake AP option. A minute later I started to see beacons being broadcasted from my card! I loaded an attack just to make sure everything still worked and the feature was fully functional and that succeeded. I did a quick run through the entire feature set of SILICA and everything works as expected. So there it was - a new firmware solved the problem.

The new update of SILICA is going to automatically replace the old firmware.

Tuesday, October 9, 2012


So we occasionally we try to go a bit away from our office and see if a different antenna produces better results. Personally, I never have good luck with antennas. First of all, the knobs on various cards (including the one we ship with SILICA) come off if you pull too hard on the antenna, and that ruins the card.

But if you take a butter knife and carefully lever the old antenna off, you can put a new one on, which we did.

Result: The exact same signal strength as the original antennas we ship with SILICA. This makes me sad on one hand, and happy on the other. There's a balance to be kept between "Great Antenna" and "Antenna that makes me look super fishy everywhere I use it". So far, the ones you get with the card are the best of both worlds...


Wednesday, October 3, 2012

STALKER, SILICA, and Megacorp System Integrators

So one thing we are finding with SILICA is that you notice policy weaknesses more than anything else. For example, many large system integration companies have an "internal" wireless network in their office which is set up as WPA, and has a properly configured non WPS-vulnerable, difficult key.

Which is great.

But because of the way these system integrators do business, they also have a Open network called "SysInt_Guest" or just "Guest" which is how their contractors all do business while in their spaces.

The attack here is to simply sit on the Open network with SILICA, and then take your PCAPs and run them through STALKER. In a half hour, you'll (theoretically) have access to their poorly secured, veteran owned partner, who is doing the actual work. If you don't have straight up access via POP3 or some other unencrypted protocol, then you'll definitely have the websites they've visited (allowing you to client-side them with one click from SILICA, of course), and Facebook access, which will allow you to social engineer your way into their network. These things are now brutally simple to do.

So our advice of the day for system integrators is "Use a strong WPA key on your guest network! Put it on postit-notes if you have to, in the conference room. Change the key occasionally, if you can spare the cycles (and the post-it notes)."  Because you're hiring that certified 8a veteran owned small business because of the access they have, but that access can be used against you.