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.




Thursday, August 30, 2012

Java patched at least 4 bugs

The last couple of days there has been a big convulsion on the social networks about the Java zero days found in a Chinese attack campaign on the Internet.


After some deep analysis of the Jar used in the exploit, we found out that there were actually two bugs exploited in order to jump outside the Java security sandbox.


Oracle has just released a new update, Java JDK/JRE 7 update 7 is now
available at
http://www.oracle.com/technetwork/java/javase/downloads/index.html

The release notes say that this contains fixes for CVE-2012-4681. This seems to be a new move in the recent history of Java updates, since generally it takes months to QA a Java security bug fix - which may be how long this took, considering some researchers claim they sent these vulnerabilities to Oracle months ago.

While doing some fast analysis (keep in mind we only spent an hour and half on it), we find out that they patched at least 4 vulnerabilities in the Java code base: The two used by the Gondvv worm and two more on difference pieces of code. Just by simply running the Immunity CANVAS exploit that exploits this vulnerability we can see that this update is preventing it.
When we run the exploit we get the following exception:

java.security.AccessControlException: access denied
("java.lang.RuntimePermission" "accessClassInPackage.sun.awt")
 at
java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
 at
java.security.AccessController.checkPermission(AccessController.java:555)
 at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
 at
java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1529)
 at sun.applet.AppletSecurity.checkPackageAccess(AppletSecurity.java:283)
 at sun.reflect.misc.ReflectUtil.checkPackageAccess(ReflectUtil.java:134)
 at com.sun.beans.finder.ClassFinder.findClass(ClassFinder.java:100)
 at com.sun.beans.finder.ClassFinder.resolveClass(ClassFinder.java:170)
 at java.beans.Statement.invokeInternal(Statement.java:213)
 at java.beans.Statement.access$000(Statement.java:58)
 at java.beans.Statement$2.run(Statement.java:185)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.beans.Statement.invoke(Statement.java:182)
 at java.beans.Expression.execute(Expression.java:121)
 at Gondvv.GetClass(Gondvv.java:38)
 at Gondvv.SetField(Gondvv.java:46)
 at Gondvv.disableSecurity(Gondvv.java:30)
 at Gondvv.init(Gondvv.java:53)
 at sun.applet.AppletPanel.run(AppletPanel.java:434)
 at java.lang.Thread.run(Thread.java:722)


There isn't much information in the traceback about the exact changes that this update includes so taking a better look we can see that not only these 2 vulnerabilities used in the Gondvv exploit have been patched, but also some others.
The two vulnerabilities used in the exploit were located in com.sun.beans.finder.ClassFinder and com.sun.beans.finder.MethodFinder
The update also patched at least another 2 other vulnerabilities that were basically the same but related to Constructors and Fields and allowed an attacker to get any public constructor or any public field via reflection bypassing security checks. 

These 2 vulnerabilities were located in com.sun.beans.finder.ConstructorFinder and com.sun.beans.finder.FieldFinder and the underlying issue was the same "a trusted immedate caller".
These two "new" vulnerabilities patched combined with the MethodFinder weakness could allow you to bypass the Sandbox and obtain full execution on Linux, Windows and MacOSX.  Now Oracle has added proper checks by adding calls to methods of sun.reflect.misc.ReflectUtil class.
Another interesting change this update includes is that public static methods getField and getMethod in sun.awt.SunToolkit were removed which means that the technique used in the exploit to get a private field no longer works.

- Esteban Guillardoy
  @sagar38

Tuesday, August 28, 2012

Java 0day analysis (CVE-2012-4681)

(This post brought to you by Esteban, Immunity's in-house Java friend)

Summary

A couple of days ago, a Java 0day was found running like crazy in the wild. While a lot of defense bunnies where asking "WWMAD" (What will my Antivirus do?), we decide to dive into Java for the details of the vulnerability and as we expected, the unpatched vulnerabilities used in the Gondvv exploit were more than one (When we said, "dive deep into Java", we actually meant open our new Infiltrate 2013 Master Class slide deck which will include a full day of Java auditing).

The first bug was used to get a reference to sun.awt.SunToolkit class that is restricted to applets while the second bug invokes the getField public static method on SunToolkit using reflection with a trusted immediate caller bypassing a security check.

The beauty of this bug class is that it provides 100% reliability and is multiplatform. Hence this will shortly become the penetration test Swiss knife for the next couple of years (as did its older brother CVE-2008-5353). 

As a final note, the bug was introduced in Java 7.0 released in July 28, 2011. While you are feeling the rush of blood going through your veins while by getting all those shell being pop, think that somewhere not far way (Probably a 10hs flight from some of the major airports in Norte Americana) was enjoying it non-stop for quite some time now.

Introduction

As the “Secure Coding Guidelines” document [1] states, it is important to understand how the permissions are checked in the Java security model. (Please readguideline 9-1).

Many operations in the JDK perform permission checks before executing. Whenever a call to java.security.AccessController.checkPermission method is performed, the complete call stack that exists at that moment is analyzed.

If any of the callers in the stack do not have the required privileged an exception is raised.
When we are running code in an Applet in our browser, there is a context that has very restricted permissions.

This means that if there is any caller in the stack that is part of our applet, the permission checks will fail (unless there is a doPrivileged code block, but let's leave that out for now).
Section “9 – Access Control” in the “Secure Coding Guidelines” document [1] together with the “Java Security Architecture” document [2] will give you a complete insight on how all this works.


The Gondvv exploit

A PoC for this 0 day exploit quickly began to spread when Joshua J. Drake posted it on Twitter https://twitter.com/jduck1337/status/239875285913317376.

By analyzing this implementation we can clearly see how the exploitation is done and where the vulnerabilities are really located.

The first thing we notice, is that most of the online analysis talks about one vulnerability where we saw two 2 vulnerabilities being exploited to achieve full execution on a target.

Basically the exploit is creating an java.security.AccessControlContext instance with a java.security.ProtectionDomain that has full permissions and then replace the actual AccessControlContext of a java.beans.Statement instance to be able to execute code with full privileges.
So let's take a better look at each part to understand what is happening under the hood.
In the java.beans.Statement implementation we can see that the AccessControlContext instance is a private final field and it gets its value by calling AccessController.getContext().




public class Statement {

private static Object[] emptyArray = new Object[]{};

static ExceptionListener defaultExceptionListener = new ExceptionListener() {
public void exceptionThrown(Exception e) {
System.err.println(e);
System.err.println("Continuing ...");
}
};

private final AccessControlContext acc = AccessController.getContext();
private final Object target;
private final String methodName;
private final Object[] arguments;
ClassLoader loader;

[...]

}


That call to the getContext method will set the AccessControlContext to an applet context that has restrictions with a limited ProtectionDomain which of course is not privileged at all.

Back in 2010 Sami Koivu published information about a Java vulnerability (CVE-2010-0840) that built a “trusted method chain” [4].

You can see in the article that the exploitation of that vulnerability also made use of the java.beans.Statement class.

The article also explains that the fix was to add an AccessControlContext field to the Statement class setting its value to the applet context when creating an instance thus avoiding the full trusted chain.

This AccessControllContext field added in that fix is exactly what this new 0 day exploit is replacing in order to be able to execute code with full permissions.


But how can a private field be changed?
The trick here is to use the sun.awt.SunToolkit class which contains a very interesting public static method:
public static Field getField(final Class klass, final String fieldName) {
return AccessController.doPrivileged(new PrivilegedAction<Field>() {
public Field run() {
try {
Field field = klass.getDeclaredField(fieldName);
assert (field != null);
field.setAccessible(true);
return field;
} catch (SecurityException e) {
assert false;
} catch (NoSuchFieldException e) {
assert false;
}
return null;
}
});
}



We can see that it is using reflection to get fields and the complete implementation is inside a doPrivileged block. This getField method can be used to get any field on a class and the good thing is that it can even retrieve private ones.



Well this is of course very useful, it's important to notice that the classes that are part of certain packages are restricted for applets and cannot be accessed or used. Such packages are:
  • com.sun.deploy.*
  • com.sun.imageio.*
  • com.sun.javaws.*
  • com.sun.jnlp.*
  • com.sun.xml.internal.bind.*
  • com.sun.xml.internal.ws.*
  • sun.*
Trying to instantiate or use classes in these packages will result in an AccessControlException.
This means that we are not able to get a reference to the sun.awt.SunToolkit class from our applet.
But the basic thing we need to know is that calls to certain methods can potentially bypass the SecurityManager checks depending on the immediate caller's class loader.

This is explained in detail in the “Secure Coding Guidelines” document by Sun [1] in guidelines 9-8 and 9-9.

This exploit is abusing this situation taking advantage of the immediate caller to bypass security checks.

Vulnerabilities

There are 2 different zero-day vulnerabilities used in this exploit: one is used to obtain a reference to the sun.awt.SunToolkit class and the other is used to invoke the public getField method on that class.
The exploit is making use of the java.beans.Expression which is a java.beans.Statement subclass.
There are 2 Expression instances that are used to trigger these 2 different bugs.

When the Expression.execute method is called it ends up calling Statement.invokeInternal method, so let's check the implementation:


private Object invokeInternal() throws Exception {
Object target = getTarget();
String methodName = getMethodName();

if (target == null || methodName == null) {
throw new NullPointerException((target == null ? "target" :
"methodName") + " should not be null");
}

Object[] arguments = getArguments();
if (arguments == null) {
arguments = emptyArray;
}
// Class.forName() won't load classes outside
// of core from a class inside core. Special
// case this method.
if (target == Class.class && methodName.equals("forName")) {
return ClassFinder.resolveClass((String)arguments[0], this.loader);
}
Class[] argClasses = new Class[arguments.length];
for(int i = 0; i < arguments.length; i++) {
argClasses[i] = (arguments[i] == null) ? null : arguments[i].getClass();
}

AccessibleObject m = null;
if (target instanceof Class) {
/*
For class methods, simluate the effect of a meta class
by taking the union of the static methods of the
actual class, with the instance methods of "Class.class"
and the overloaded "newInstance" methods defined by the
constructors.
This way "System.class", for example, will perform both
the static method getProperties() and the instance method
getSuperclass() defined in "Class.class".
*/
if (methodName.equals("new")) {
methodName = "newInstance";
}
// Provide a short form for array instantiation by faking an nary-constructor.
if (methodName.equals("newInstance") && ((Class)target).isArray()) {
Object result = Array.newInstance(((Class)target).getComponentType(), arguments.length);
for(int i = 0; i < arguments.length; i++) {
Array.set(result, i, arguments[i]);
}
return result;
}
if (methodName.equals("newInstance") && arguments.length != 0) {
// The Character class, as of 1.4, does not have a constructor
// which takes a String. All of the other "wrapper" classes
// for Java's primitive types have a String constructor so we
// fake such a constructor here so that this special case can be
// ignored elsewhere.
if (target == Character.class && arguments.length == 1 &&
argClasses[0] == String.class) {
return new Character(((String)arguments[0]).charAt(0));
}
try {
m = ConstructorFinder.findConstructor((Class)target, argClasses);
}
catch (NoSuchMethodException exception) {
m = null;
}
}
if (m == null && target != Class.class) {
m = getMethod((Class)target, methodName, argClasses);
}
if (m == null) {
m = getMethod(Class.class, methodName, argClasses);
}
}
else {
/*
This special casing of arrays is not necessary, but makes files
involving arrays much shorter and simplifies the archiving infrastrcure.
The Array.set() method introduces an unusual idea - that of a static method
changing the state of an instance. Normally statements with side
effects on objects are instance methods of the objects themselves
and we reinstate this rule (perhaps temporarily) by special-casing arrays.
*/
if (target.getClass().isArray() &&
(methodName.equals("set") || methodName.equals("get"))) {
int index = ((Integer)arguments[0]).intValue();
if (methodName.equals("get")) {
return Array.get(target, index);
}
else {
Array.set(target, index, arguments[1]);
return null;
}
}
m = getMethod(target.getClass(), methodName, argClasses);
}
if (m != null) {
try {
if (m instanceof Method) {
return MethodUtil.invoke((Method)m, target, arguments);
}
else {
return ((Constructor)m).newInstance(arguments);
}
}
catch (IllegalAccessException iae) {
throw new Exception("Statement cannot invoke: " +
methodName + " on " + target.getClass(),
iae);
}
catch (InvocationTargetException ite) {
Throwable te = ite.getTargetException();
if (te instanceof Exception) {
throw (Exception)te;
}
else {
throw ite;
}
}
}
throw new NoSuchMethodException(toString());
}



And the Statement.getMethod implementation is:
static Method getMethod(Class<?> type, String name, Class<?>... args) {
try {
return MethodFinder.findMethod(type, name, args);
}
catch (NoSuchMethodException exception) {
return null;
}
}


Highlighted in the code you'll see the calls to com.sun.beans.finder.ClassFinder.resolveClass and com.sun.beans.finder.MethodFinder.findMethod methods.

com.sun.beans.finder.ClassFinder.findClass vulnerability

The Statement.invokeInternal method is calling com.sun.beans.finder.ClassFinder.resolveClass and if we take a look a its implementation we'll see that it ends up calling the com.sun.beans.finder.ClassFinder.findClass method:
public static Class<?> resolveClass(String name, ClassLoader loader) throws ClassNotFoundException {
Class<?> type = PrimitiveTypeMap.getType(name);
return (type == null) ? findClass(name, loader): type;
}



public static Class<?> findClass(String name) throws ClassNotFoundException {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
if (loader != null) {
return Class.forName(name, false, loader);
}
} catch (ClassNotFoundException exception) {
// use current class loader instead
} catch (SecurityException exception) {
// use current class loader instead
}
return Class.forName(name);
}



This code shows that if an exception is captured, then the default is to simply call Class.forName and this is exaclty what happens here.

As it is explained in the Guideline 9-9: “Safely invoke standard APIs that perform tasks using the immediate caller's class loader instance” on the “Secure Code Guidelines” documentation [1], a call to Class.forName will use the immediate caller ClassLoader and in this case the caller is part of the JDK which is trusted thus allowing us to get any class on any package.

The caller's stack can be seen by simply debugging the applet:



MethodFinder.findMethod vulnerability

According to the “Secure Code Guidelines” document in guideline 9.8 the java.lang.Class.getMethod and java.lang.Class.getMethods only take the immediate caller into account when performing security checks.
These methods can be used to get a Method reference via reflection but only “public” ones.

Even though we have a reference to the sun.awt.SunToolkit class we cannot call any of its methods directly because is part of a restricted package and a security exception will be raised.

What is needed here is a way of getting a method reference via reflection but having a “trusted” immediate caller in the stack in order to bypass security checks.

The implementation of com.sun.beans.finder.MethodFinder.findMethod is this:

public static Method findMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
if (name == null) {
throw new IllegalArgumentException("Method name is not set
}
PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
Signature signature = new Signature(type, name, args);

Method method = CACHE.get(signature);
if (method != null) {
return method;
}
method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
CACHE.put(signature, method);
return method;
}


The call to findAccessibleMethod ends up calling java.lang.Class.getMethods and the immediate caller in the stack is com.sun.beans.finder.MethodFinder which is trusted since is part of the JDK thus bypassing the security checks.


Once again we can see the callers stack by debugging the applet:



Affected Versions

The com.sun.beans.finder.MethodFinder and com.sun.beans.finder.ClassFinder classes are available only since JDK 7.

Putting all together

So this exploit is performing the following steps:
  • Creates a Statement instance that will call System.setSecurityManager(null) method using reflection.
  • Creates a custom AccessControlContext with full permissions.
  • With one bug it gets a reference to the sun.awt.SunToolkit class that is restricted to applets.
  • With the other bug it invokes the getField public static method on sun.awt.SunToolkit using reflection with a trusted immediate caller that bypasses the security checks.
  • With the getField method it is getting a reference to Statement.acc private field and setting its value to the custom AccessControlContext instance previously created.
  • Finally it executes the Statement that will disable the Security Manager bypassing all security checks because it has full permissions set in its AccessControlContext.

Author

Esteban Guillardoy
esteban@immunityinc.com
twitter: @sagar38

References

[1] - Secure Coding Guidelines for the Java Programming Language, Version 4.0 - http://www.oracle.com/technetwork/java/seccodeguide-139067.html


[2] - Java SE 7 Security Architecture - http://docs.oracle.com/javase/7/docs/technotes/guides/security/spec/security-specTOC.fm.html

[3] - Java SE 7 Security Documents - http://docs.oracle.com/javase/7/docs/technotes/guides/security/

[4] - Sami Koivu 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