assembly to include tests in jar

This commit is contained in:
Chris Frohoff
2019-04-25 08:20:07 -07:00
committed by Chris Frohoff
parent 47154e8c7f
commit 4543487154
26 changed files with 197 additions and 77 deletions
+28
View File
@@ -0,0 +1,28 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>fat-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
+8 -5
View File
@@ -39,10 +39,8 @@
<mainClass>ysoserial.GeneratePayload</mainClass> <mainClass>ysoserial.GeneratePayload</mainClass>
</manifest> </manifest>
</archive> </archive>
<descriptorRefs> <descriptor>assembly.xml</descriptor>
<descriptorRef>jar-with-dependencies</descriptorRef> </configuration>
</descriptorRefs>
</configuration>
<executions> <executions>
<execution> <execution>
<id>make-assembly</id> <id>make-assembly</id>
@@ -115,7 +113,7 @@
<dependency> <dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId> <groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId> <artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>2.1.1</version> <version>2.2.6</version>
<type>pom</type> <type>pom</type>
</dependency> </dependency>
<dependency> <dependency>
@@ -303,6 +301,11 @@
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>1.7.21</version> <version>1.7.21</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.21</version>
</dependency>
<dependency> <dependency>
<groupId>org.clojure</groupId> <groupId>org.clojure</groupId>
<artifactId>clojure</artifactId> <artifactId>clojure</artifactId>
+1 -1
View File
@@ -38,7 +38,7 @@ import ysoserial.payloads.util.Reflections;
* @author mbechler * @author mbechler
* *
*/ */
@PayloadTest ( harness = "ysoserial.payloads.RemoteClassLoadingTest" ) @PayloadTest ( harness="ysoserial.test.payloads.RemoteClassLoadingTest" )
@Dependencies( { "com.mchange:c3p0:0.9.5.2" ,"com.mchange:mchange-commons-java:0.2.11"} ) @Dependencies( { "com.mchange:c3p0:0.9.5.2" ,"com.mchange:mchange-commons-java:0.2.11"} )
@Authors({ Authors.MBECHLER }) @Authors({ Authors.MBECHLER })
public class C3P0 implements ObjectPayload<Object> { public class C3P0 implements ObjectPayload<Object> {
@@ -49,7 +49,6 @@ This only works in JDK 8u76 and WITHOUT a security manager
https://github.com/JetBrains/jdk8u_jdk/commit/af2361ee2878302012214299036b3a8b4ed36974#diff-f89b1641c408b60efe29ee513b3d22ffR70 https://github.com/JetBrains/jdk8u_jdk/commit/af2361ee2878302012214299036b3a8b4ed36974#diff-f89b1641c408b60efe29ee513b3d22ffR70
*/ */
//@PayloadTest(skip="need more robust way to detect Runtime.exec() without SecurityManager()")
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@PayloadTest ( precondition = "isApplicableJavaVersion") @PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies({"commons-collections:commons-collections:3.1"}) @Dependencies({"commons-collections:commons-collections:3.1"})
@@ -41,7 +41,7 @@ import ysoserial.payloads.util.Reflections;
"commons-fileupload:commons-fileupload:1.3.1", "commons-fileupload:commons-fileupload:1.3.1",
"commons-io:commons-io:2.4" "commons-io:commons-io:2.4"
} ) } )
@PayloadTest(harness="ysoserial.payloads.FileUploadTest", precondition = "isApplicableJavaVersion") @PayloadTest(harness="ysoserial.test.payloads.FileUploadTest", precondition = "isApplicableJavaVersion")
@Authors({ Authors.MBECHLER }) @Authors({ Authors.MBECHLER })
public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> { public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> {
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
@@ -42,7 +42,7 @@ import com.sun.rowset.JdbcRowSetImpl;
@SuppressWarnings ( { @SuppressWarnings ( {
"restriction" "restriction"
} ) } )
@PayloadTest(harness = "ysoserial.payloads.JRMPReverseConnectTest", precondition = "isApplicableJavaVersion") @PayloadTest(harness="ysoserial.test.payloads.JRMPReverseConnectTest", precondition = "isApplicableJavaVersion")
@Authors({ Authors.MBECHLER }) @Authors({ Authors.MBECHLER })
public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies { public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
@@ -49,7 +49,7 @@ import ysoserial.payloads.util.PayloadRunner;
@SuppressWarnings ( { @SuppressWarnings ( {
"restriction" "restriction"
} ) } )
@PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectSMTest") @PayloadTest( harness="ysoserial.test.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER }) @Authors({ Authors.MBECHLER })
public class JRMPClient extends PayloadRunner implements ObjectPayload<Registry> { public class JRMPClient extends PayloadRunner implements ObjectPayload<Registry> {
@@ -29,7 +29,7 @@ import ysoserial.payloads.util.PayloadRunner;
* *
* @author mbechler * @author mbechler
*/ */
@PayloadTest(harness = "ysoserial.payloads.MyfacesTest", precondition = "isApplicableJavaVersion") @PayloadTest(harness="ysoserial.test.payloads.MyfacesTest", precondition = "isApplicableJavaVersion")
@Authors({ Authors.MBECHLER }) @Authors({ Authors.MBECHLER })
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies { public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
public static boolean isApplicableJavaVersion() { public static boolean isApplicableJavaVersion() {
@@ -46,7 +46,7 @@ import ysoserial.payloads.util.Reflections;
* $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp * $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* blue lobster * blue lobster
*/ */
@PayloadTest(harness = "ysoserial.payloads.FileUploadTest", flaky="possible race condition") @PayloadTest(harness="ysoserial.test.payloads.FileUploadTest", flaky="possible race condition")
@Dependencies({"org.apache.wicket:wicket-util:6.23.0", "org.slf4j:slf4j-api:1.6.4"}) @Dependencies({"org.apache.wicket:wicket-util:6.23.0", "org.slf4j:slf4j-api:1.6.4"})
@Authors({ Authors.JACOBAINES }) @Authors({ Authors.JACOBAINES })
public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> { public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
@@ -1,4 +1,4 @@
package ysoserial; package ysoserial.test;
/** /**
@@ -1,4 +1,4 @@
package ysoserial; package ysoserial.test;
/** /**
@@ -1,4 +1,4 @@
package ysoserial; package ysoserial.test;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@@ -1,4 +1,4 @@
package ysoserial; package ysoserial.test;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@@ -1,4 +1,4 @@
package ysoserial.exploit; package ysoserial.test.exploit;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; import java.rmi.registry.LocateRegistry;
@@ -1,9 +1,9 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import org.junit.Assert; import org.junit.Assert;
import ysoserial.CustomTest; import ysoserial.test.CustomTest;
import ysoserial.util.Files; import ysoserial.test.util.Files;
import ysoserial.util.OS; import ysoserial.test.util.OS;
import java.io.File; import java.io.File;
import java.util.UUID; import java.util.UUID;
@@ -1,4 +1,4 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -9,8 +9,8 @@ import org.junit.Assert;
import com.google.common.io.Files; import com.google.common.io.Files;
import ysoserial.CustomTest; import ysoserial.test.CustomTest;
import ysoserial.util.OS; import ysoserial.test.util.OS;
/** /**
* @author mbechler * @author mbechler
@@ -1,10 +1,10 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.net.URL; import java.net.URL;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import ysoserial.WrappedTest; import ysoserial.test.WrappedTest;
import ysoserial.exploit.JRMPListener; import ysoserial.exploit.JRMPListener;
@@ -30,7 +30,7 @@ public class JRMPReverseConnectSMTest extends RemoteClassLoadingTest implements
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
* @see ysoserial.payloads.RemoteClassLoadingTest#createCallable(java.util.concurrent.Callable) * @see RemoteClassLoadingTest#createCallable(java.util.concurrent.Callable)
*/ */
@Override @Override
public Callable<Object> createCallable ( final Callable<Object> innerCallable ) { public Callable<Object> createCallable ( final Callable<Object> innerCallable ) {
@@ -1,4 +1,4 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@@ -7,7 +7,7 @@ import javax.management.BadAttributeValueExpException;
import org.junit.Assert; import org.junit.Assert;
import ysoserial.CustomTest; import ysoserial.test.CustomTest;
import ysoserial.exploit.JRMPListener; import ysoserial.exploit.JRMPListener;
@@ -1,4 +1,4 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.beans.FeatureDescriptor; import java.beans.FeatureDescriptor;
@@ -23,7 +23,7 @@ import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import ysoserial.CustomDeserializer; import ysoserial.test.CustomDeserializer;
import ysoserial.Deserializer; import ysoserial.Deserializer;
@@ -1,32 +1,44 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; 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;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Assert;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Test; import org.junit.Test;
import org.junit.internal.TextListener;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.Parameters;
import ysoserial.*; import ysoserial.*;
import ysoserial.util.Throwables; import ysoserial.payloads.DynamicDependencies;
import ysoserial.payloads.TestHarnessTest.ExecMockPayload; import ysoserial.payloads.ObjectPayload;
import ysoserial.payloads.TestHarnessTest.NoopMockPayload; import ysoserial.test.CustomTest;
import ysoserial.test.CustomDeserializer;
import ysoserial.test.CustomPayloadArgs;
import ysoserial.test.WrappedTest;
import ysoserial.test.payloads.TestHarnessTest.ExecMockPayload;
import ysoserial.test.payloads.TestHarnessTest.NoopMockPayload;
import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.ClassFiles; import ysoserial.payloads.util.ClassFiles;
import ysoserial.secmgr.ExecCheckingSecurityManager;
import ysoserial.secmgr.ExecCheckingSecurityManager.ExecException;
/* /*
@@ -65,18 +77,22 @@ public class PayloadsTest {
public static void testPayload ( final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader ) public static void testPayload ( final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader )
throws Exception { throws Exception {
System.out.println("Testing payload: " + payloadClass.getName());
String command = "hostname"; String command = "hostname";
PayloadTest t = payloadClass.getAnnotation(PayloadTest.class); PayloadTest t = payloadClass.getAnnotation(PayloadTest.class);
int tries = 1; int tries = 1;
if ( t != null ) { if ( t != null ) {
if ( !t.skip().isEmpty() ) { if (System.getProperty("forceTests") == null) {
Assume.assumeTrue(t.skip(), false); if ( !t.skip().isEmpty() ) {
} Assume.assumeTrue(t.skip(), false);
}
if ( !t.precondition().isEmpty() ) { if ( !t.precondition().isEmpty() ) {
Assume.assumeTrue("Precondition: " + t.precondition(), checkPrecondition(payloadClass, t.precondition())); Assume.assumeTrue("Precondition: " + t.precondition(), checkPrecondition(payloadClass, t.precondition()));
}
} }
if (! t.flaky().isEmpty()) { if (! t.flaky().isEmpty()) {
@@ -99,18 +115,18 @@ public class PayloadsTest {
testHarness = new CommandExecTest(); // default testHarness = new CommandExecTest(); // default
} }
if ( testHarness instanceof CustomPayloadArgs ) { if ( testHarness instanceof CustomPayloadArgs) {
payloadCommand = ( (CustomPayloadArgs) testHarness ).getPayloadArgs(); payloadCommand = ( (CustomPayloadArgs) testHarness ).getPayloadArgs();
} }
if ( testHarness instanceof CustomDeserializer ) { if ( testHarness instanceof CustomDeserializer) {
customDeserializer = ((CustomDeserializer)testHarness).getCustomDeserializer(); customDeserializer = ((CustomDeserializer)testHarness).getCustomDeserializer();
} }
// TODO per-thread secmgr to enforce no detonation during deserialization // TODO per-thread secmgr to enforce no detonation during deserialization
final byte[] serialized = makeSerializeCallable(payloadClass, payloadCommand).call(); final byte[] serialized = makeSerializeCallable(payloadClass, payloadCommand).call();
Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized, customDeserializer); Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized, customDeserializer);
if ( testHarness instanceof WrappedTest ) { if ( testHarness instanceof WrappedTest) {
callable = ( (WrappedTest) testHarness ).createCallable(callable); callable = ( (WrappedTest) testHarness ).createCallable(callable);
} }
@@ -184,7 +200,12 @@ public class PayloadsTest {
static Object deserializeWithDependencies ( byte[] serialized, final String[] dependencies, final Class<?>[] classDependencies, final Class<?> customDeserializer ) static Object deserializeWithDependencies ( byte[] serialized, final String[] dependencies, final Class<?>[] classDependencies, final Class<?> customDeserializer )
throws Exception { throws Exception {
File[] jars = dependencies.length > 0 ? Maven.resolver().resolve(dependencies).withoutTransitivity().asFile() : new File[0]; File[] jars = dependencies.length > 0
? Maven.configureResolver()
.withMavenCentralRepo(true)
.withRemoteRepo("jenkins", "http://repo.jenkins-ci.org/public/", "default")
.resolve(dependencies).withoutTransitivity().asFile()
: new File[0];
URL[] urls = new URL[jars.length]; URL[] urls = new URL[jars.length];
for ( int i = 0; i < jars.length; i++ ) { for ( int i = 0; i < jars.length; i++ ) {
urls[ i ] = jars[ i ].toURI().toURL(); urls[ i ] = jars[ i ].toURI().toURL();
@@ -230,4 +251,72 @@ public class PayloadsTest {
Thread.currentThread().setContextClassLoader(ccl); Thread.currentThread().setContextClassLoader(ccl);
} }
} }
public static void main(String[] args) {
JUnitCore junit = new JUnitCore();
PayloadListener listener = new PayloadListener();
junit.addListener(listener);
Result result = junit.run(PayloadsTest.class);
System.exit(result.wasSuccessful() ? 0 : 1);
}
public static class PayloadListener extends RunListener {
private static PrintStream realOut = System.out;
private static PrintStream realErr = System.err;
private Map<Description, ByteArrayOutputStream> outs = new HashMap<Description, ByteArrayOutputStream>();
//private Map<Description, ByteArrayOutputStream> errs = new HashMap<Description, ByteArrayOutputStream>();
@Override
public void testStarted(Description description) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
//ByteArrayOutputStream err = new ByteArrayOutputStream();
outs.put(description, out);
//errs.put(description, err);
setStreams(new PrintStream(out), new PrintStream(out));
//System.setErr(new PrintStream((err)));
}
@Override
public void testFinished(Description description) throws Exception {
outs.get(description).close();
//errs.get(description).close();
restoreStreams();
}
private void restoreStreams() {
setStreams(realOut, realErr);
}
private void setStreams(PrintStream realOut, PrintStream realErr) {
System.setOut(realOut);
System.setErr(realErr);
}
@Override
public void testFailure(Failure failure) throws Exception {
restoreStreams();
System.out.println(failure.getDescription().getDisplayName() + ": TEST-FAILED");
System.err.println(outs.get(failure.getDescription()).toString());
}
@Override
public void testAssumptionFailure(Failure failure) {
restoreStreams();
System.out.println(failure.getDescription().getDisplayName() + ": ASSUMPTION-FAILED");
}
@Override
public void testIgnored(Description description) throws Exception {
restoreStreams();
System.out.println(description.getDisplayName() + ": TEST-IGNORED");
}
}
} }
@@ -1,4 +1,4 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -12,7 +12,7 @@ import fi.iki.elonen.NanoHTTPD.Response.Status;
import javassist.ClassClassPath; import javassist.ClassClassPath;
import javassist.ClassPool; import javassist.ClassPool;
import javassist.CtClass; import javassist.CtClass;
import ysoserial.WrappedTest; import ysoserial.test.WrappedTest;
/** /**
@@ -1,4 +1,4 @@
package ysoserial.payloads; package ysoserial.test.payloads;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
@@ -7,6 +7,7 @@ import java.io.Serializable;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import ysoserial.payloads.ObjectPayload;
public class TestHarnessTest { public class TestHarnessTest {
// make sure test harness fails properly // make sure test harness fails properly
@@ -1,4 +1,4 @@
package ysoserial.util; package ysoserial.test.util;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@@ -1,4 +1,4 @@
package ysoserial.util; package ysoserial.test.util;
import java.io.File; import java.io.File;
@@ -1,4 +1,4 @@
package ysoserial.util; package ysoserial.test.util;
public enum OS { public enum OS {
WINDOWS, WINDOWS,
@@ -1,4 +1,4 @@
package ysoserial.util; package ysoserial.test.util;
public class Throwables { public class Throwables {
public static Throwable getInnermostCause(final Throwable t) { public static Throwable getInnermostCause(final Throwable t) {