Add custom test infrastructure.

This commit is contained in:
mbechler
2016-03-06 14:54:49 +01:00
parent 7157d5e297
commit 8dfce7ed73
5 changed files with 150 additions and 13 deletions
+24
View File
@@ -0,0 +1,24 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author mbechler
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface PayloadTest {
String skip() default "";
String precondition() default "";
String harness() default "";
}
@@ -6,6 +6,7 @@ import java.util.LinkedHashSet;
import javax.xml.transform.Templates;
import ysoserial.PayloadTest;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
@@ -52,6 +53,7 @@ LinkedHashSet.readObject()
@SuppressWarnings({ "rawtypes", "unchecked" })
@Dependencies()
@PayloadTest ( precondition = "isApplicableJavaVersion")
public class Jdk7u21 implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
@@ -77,6 +79,21 @@ public class Jdk7u21 implements ObjectPayload<Object> {
return set;
}
public static boolean isApplicableJavaVersion() {
String property = System.getProperties().getProperty("java.version");
if ( property == null ) {
return false;
}
String parts[] = property.split("\\.|_|-");;
int major = Integer.parseInt(parts[1]);
int minor = Integer.parseInt(parts[2]);
int update = Integer.parseInt(parts[3]);
if ( major < 7 || (major == 7 && update <= 21) ) {
return true;
}
return false;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(Jdk7u21.class, args);
+16
View File
@@ -0,0 +1,16 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial;
/**
* @author mbechler
*
*/
public interface CustomTest extends Runnable {
}
+23
View File
@@ -0,0 +1,23 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial;
import java.util.concurrent.Callable;
/**
* @author mbechler
*
*/
public interface WrappedTest {
/**
* @param innerCallable
* @return a wrapped callable
*/
Callable<Object> createCallable ( Callable<Object> innerCallable );
}
@@ -3,6 +3,8 @@ package ysoserial.payloads;
import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
@@ -12,6 +14,7 @@ import java.util.concurrent.Callable;
import org.hamcrest.CoreMatchers;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ProvideSecurityManager;
@@ -19,9 +22,12 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import ysoserial.CustomTest;
import ysoserial.Deserializer;
import ysoserial.PayloadTest;
import ysoserial.Serializer;
import ysoserial.Throwables;
import ysoserial.WrappedTest;
import ysoserial.payloads.TestHarnessTest.ExecMockPayload;
import ysoserial.payloads.TestHarnessTest.NoopMockPayload;
import ysoserial.payloads.annotation.Dependencies;
@@ -62,21 +68,37 @@ public class PayloadsTest {
public static void testPayload(final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader) throws Exception {
final String command = "hostname";
final String[] deps = buildDeps(payloadClass);
PayloadTest t = payloadClass.getAnnotation(PayloadTest.class);
if ( t != null ) {
if ( !t.skip().isEmpty()) {
Assume.assumeTrue(t.skip(), false);
}
if ( !t.precondition().isEmpty()) {
Assume.assumeTrue("Precondition", checkPrecondition(payloadClass, t.precondition()));
}
}
Object wrapper = null;
if ( t != null && !t.harness().isEmpty() ) {
wrapper = Class.forName(t.harness()).newInstance();
if ( wrapper instanceof CustomTest ) {
( (CustomTest) wrapper ).run();
return;
}
}
ExecCheckingSecurityManager sm = new ExecCheckingSecurityManager();
final byte[] serialized = sm.wrap(new Callable<byte[]>(){
public byte[] call() throws Exception {
ObjectPayload<?> payload = payloadClass.newInstance();
final Object f = payload.getObject(command);
return Serializer.serialize(f);
}});
final byte[] serialized = sm.wrap(makeSerializeCallable(payloadClass, command));
try {
Object deserialized = sm.wrap(new Callable<Object>(){
public Object call() throws Exception {
return deserializeWithDependencies(serialized, deps, addlClassesForClassLoader);
}
});
Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized);
if ( wrapper instanceof WrappedTest ){
callable = ((WrappedTest)wrapper).createCallable(callable);
}
Object deserialized = sm.wrap(callable);
Assert.fail(ASSERT_MESSAGE); // should never get here
} catch (Throwable e) {
// hopefully everything will reliably nest our ExecException
@@ -87,6 +109,41 @@ public class PayloadsTest {
Assert.assertEquals(Arrays.asList(command), sm.getCmds());
}
/**
* @param payloadClass
* @param command
* @return
*/
private static Callable<byte[]> makeSerializeCallable ( final Class<? extends ObjectPayload<?>> payloadClass, final String command ) {
return new Callable<byte[]>(){
public byte[] call() throws Exception {
ObjectPayload<?> payload = payloadClass.newInstance();
final Object f = payload.getObject(command);
return Serializer.serialize(f);
}};
}
/**
* @param t
* @param addlClassesForClassLoader
* @param deps
* @param serialized
* @return
*/
private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps, final byte[] serialized ) {
return new Callable<Object>(){
public Object call() throws Exception {
return deserializeWithDependencies(serialized, deps, addlClassesForClassLoader);
}
};
}
private static boolean checkPrecondition ( Class<? extends ObjectPayload<?>> pc, String precondition ) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method precondMethod = pc.getMethod(precondition);
return (Boolean) precondMethod.invoke(null);
}
/**
* @param payloadClass
* @return