mirror of
https://github.com/frohoff/ysoserial.git
synced 2026-09-26 17:01:53 +08:00
Add custom test infrastructure.
This commit is contained in:
@@ -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 javax.xml.transform.Templates;
|
||||||
|
|
||||||
|
import ysoserial.PayloadTest;
|
||||||
import ysoserial.payloads.annotation.Dependencies;
|
import ysoserial.payloads.annotation.Dependencies;
|
||||||
import ysoserial.payloads.util.Gadgets;
|
import ysoserial.payloads.util.Gadgets;
|
||||||
import ysoserial.payloads.util.PayloadRunner;
|
import ysoserial.payloads.util.PayloadRunner;
|
||||||
@@ -52,6 +53,7 @@ LinkedHashSet.readObject()
|
|||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@Dependencies()
|
@Dependencies()
|
||||||
|
@PayloadTest ( precondition = "isApplicableJavaVersion")
|
||||||
public class Jdk7u21 implements ObjectPayload<Object> {
|
public class Jdk7u21 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(final String command) throws Exception {
|
public Object getObject(final String command) throws Exception {
|
||||||
@@ -77,6 +79,21 @@ public class Jdk7u21 implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
return set;
|
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 {
|
public static void main(final String[] args) throws Exception {
|
||||||
PayloadRunner.run(Jdk7u21.class, args);
|
PayloadRunner.run(Jdk7u21.class, args);
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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 static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -12,6 +14,7 @@ import java.util.concurrent.Callable;
|
|||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
|
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.contrib.java.lang.system.ProvideSecurityManager;
|
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;
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
import ysoserial.CustomTest;
|
||||||
import ysoserial.Deserializer;
|
import ysoserial.Deserializer;
|
||||||
|
import ysoserial.PayloadTest;
|
||||||
import ysoserial.Serializer;
|
import ysoserial.Serializer;
|
||||||
import ysoserial.Throwables;
|
import ysoserial.Throwables;
|
||||||
|
import ysoserial.WrappedTest;
|
||||||
import ysoserial.payloads.TestHarnessTest.ExecMockPayload;
|
import ysoserial.payloads.TestHarnessTest.ExecMockPayload;
|
||||||
import ysoserial.payloads.TestHarnessTest.NoopMockPayload;
|
import ysoserial.payloads.TestHarnessTest.NoopMockPayload;
|
||||||
import ysoserial.payloads.annotation.Dependencies;
|
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 {
|
public static void testPayload(final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader) throws Exception {
|
||||||
final String command = "hostname";
|
final String command = "hostname";
|
||||||
final String[] deps = buildDeps(payloadClass);
|
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();
|
ExecCheckingSecurityManager sm = new ExecCheckingSecurityManager();
|
||||||
final byte[] serialized = sm.wrap(new Callable<byte[]>(){
|
final byte[] serialized = sm.wrap(makeSerializeCallable(payloadClass, command));
|
||||||
public byte[] call() throws Exception {
|
|
||||||
ObjectPayload<?> payload = payloadClass.newInstance();
|
|
||||||
final Object f = payload.getObject(command);
|
|
||||||
return Serializer.serialize(f);
|
|
||||||
}});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object deserialized = sm.wrap(new Callable<Object>(){
|
Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized);
|
||||||
public Object call() throws Exception {
|
if ( wrapper instanceof WrappedTest ){
|
||||||
return deserializeWithDependencies(serialized, deps, addlClassesForClassLoader);
|
callable = ((WrappedTest)wrapper).createCallable(callable);
|
||||||
}
|
}
|
||||||
});
|
Object deserialized = sm.wrap(callable);
|
||||||
|
|
||||||
Assert.fail(ASSERT_MESSAGE); // should never get here
|
Assert.fail(ASSERT_MESSAGE); // should never get here
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// hopefully everything will reliably nest our ExecException
|
// hopefully everything will reliably nest our ExecException
|
||||||
@@ -87,6 +109,41 @@ public class PayloadsTest {
|
|||||||
Assert.assertEquals(Arrays.asList(command), sm.getCmds());
|
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
|
* @param payloadClass
|
||||||
* @return
|
* @return
|
||||||
|
|||||||
Reference in New Issue
Block a user