Tuesday, October 13, 2009

com.sun.corba.se.impl.orbutil.ObjectUtility

Back to security.

Sun's strategy of prioritizing backwards compatibility is something I always appreciated as a developer. Less headaches. Yet, from a security perspective the ensuing "bloatedness" is rather challenging: The attack surface keeps on growing all the time.

So it's not all that surprising to find an applet security problem in an obscure CORBA class buried in the dark depths of the standard libraries.

On the other hand, it's the problems you find in the public java.util, java.io, etc classes that make you really appreciate how very difficult it is to build something secure.

But let's look at one of the aforementioned, obscure CORBA classes today :)

com.sun.corba.se.impl.orbutil.ObjectUtility

It has a problem I found rather interesting, but as far as I could tell, at least in the applet world, it is not exploitable in any serious way. Of course it could be just my lack of ingenuity.

ObjectUtility has two basic functionalities:
-Offer toString functionality to classes that don't implement toString. It recursively lists all the instance field names and their values using reflection and formats the output neatly. I actually use it sometimes as a quick-and-dirty debug to vomiting out object contents. When there is no security manager present it lists all the fields, but with a security manager present it sticks to the public fields (less useful).

-Offer equals functionality to classes that don't implement an equals method. It recursively compares all the instance fields of two objects following somewhat complicated rules.

Let's look at the equals functionality a little bit closer. The logic goes something like this: You give it two objects and it returns true or false depending on perceived equality, with the following details.
-in the case of object fields, recursion is used to compare the two values
-static fields are ignored
-Maps, Sets, Lists and arrays have special handling, where the Collection/array contents are compared individually
-objects x and y of the exact same class (ie. x.getClass() == y.getClass() ) are compared by comparing all the non-static fields individually
-doPrivileged is used to allow access to private fields even with a security manager enabled
-objects x and y of different classes (for example, Object instance and a String instance) are compared by calling equals of the first object, ie. x.equals(y)

Pause for a moment. Absorb the logic. Do you see a problem?

...

This implementation leaks private information. If you compare a malicious object to a sensitive object, in specific cases you can extract references to objects stored in private fields of said sensitive object.

Here's a semi-concrete example. Let's preface it a bit: If you've ever written a Java applet, you'll have noticed that when you use System.out to print some debug information, the output goes to the Java console. How does this happen? The type of System.out is PrintStream. The applet environment sets the System.out as a PrintStream instance which contains contains a Java plugin class TracePrintStream instance, which takes everything written to it and forwards it to be printed in the console.

PrintStream has no method for accessing the inherited (from superclass FilterOutputStream) "out" field, but we can create a new PrintStream and put our own OutputStream inside it. Then compare our PrintStream to System.out. Like this:

001 
002 
003 import java.applet.Applet;
004 
import java.io.IOException;
005 
import java.io.OutputStream;
006 
import java.io.PrintStream;
007 
008 
import com.sun.corba.se.impl.orbutil.ObjectUtility;
009 
010 
public class StealConsole extends Applet {
011 
012     
public void start() {
013         PrintStream syso = System.
out;
014         PrintStream stealer = new PrintStream(new OutputStream() {
015             
016             
public void write(int b) throws IOException {
017             }
018             
019             
020             
public boolean equals(Object obj) {
021                 System.out.println(
"Stole: " + obj.getClass());
022                 
return super.equals(obj);
023             }
024         }, false);
025         
026         
boolean eq = ObjectUtility.equals(stealer, syso);
027     }
028     
029 }

So we can get our hands on the TracePrintStream object contained within the PrintStream. I did a quick PoC using this and a thread which kept polling the buffer of the TracePrintStream and on my other laptop with two processors it worked pretty good, it was an incredible CPU hog, but it intercepted everything written to the console by any applet. So if you'd happen to be running a sensitive applet at the same time in the same browser that printed sensitive data in the console it'd be a bad thing. I guess this turned out to be a rather theoretical example anyway.

Other examples that I've tried this on with success: The Collections class has utility methods which return immutable versions of Lists, Maps and Sets. The way they work is that they keep a copy of the original list hidden away in a private field and the getter methods operate on this list and the setter methods throw exceptions. But comparing these immutable collections to malicious collections it is possible to access the collection contained within and modify it. However I couldn't find anything in the core Java where the security depended on the immutability of these collections.

No comments: