refactors

This commit is contained in:
Chris Frohoff
2022-03-20 20:24:28 -07:00
parent d022c995e7
commit 87785d2000
6 changed files with 110 additions and 82 deletions
-25
View File
@@ -1,25 +0,0 @@
name: Java CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Upload artifact
uses: actions/[email protected]
with:
# Artifact name
name: ysoserial
# Directory containing files to upload
path: /home/runner/work/ysoserial/ysoserial/target/
+13 -2
View File
@@ -2,10 +2,21 @@ package ysoserial;
import org.junit.Test;
import java.util.Map;
import java.util.TreeMap;
public class CiTest {
@Test
public void test() {
System.out.println("System.getProperties(): " + System.getProperties());
System.out.println("System.getenv(): " + System.getenv());
for (Map.Entry<Object,Object> e : new TreeMap<Object,Object>(System.getProperties()).entrySet()) {
System.out.println("System property " + e.getKey() + " : " + e.getValue());
}
for (Map.Entry<String,String> e : new TreeMap<String,String>(System.getenv()).entrySet()) {
System.out.println("System env " + e.getKey() + " : " + e.getValue());
}
}
public static void main(String[] args) {
new CiTest().test();
}
}
@@ -5,9 +5,11 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -33,6 +35,7 @@ import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.ClassFiles;
import ysoserial.test.util.Logging;
import ysoserial.test.util.OpenURLClassLoader;
import ysoserial.test.util.PayloadListener;
import ysoserial.test.util.StdIoRedirection;
@@ -71,7 +74,7 @@ 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 {
System.out.println("Testing payload: " + payloadClass.getName());
@@ -140,11 +143,8 @@ public class PayloadsTest {
}
if (ex != null) throw ex;
}
}
private static Callable<byte[]> makeSerializeCallable ( final Class<? extends ObjectPayload<?>> payloadClass, final String command ) {
return new Callable<byte[]>() {
@@ -158,7 +158,6 @@ public class PayloadsTest {
};
}
private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps,
final byte[] serialized, final Class<?> customDeserializer ) {
return new Callable<Object>() {
@@ -169,14 +168,12 @@ public class PayloadsTest {
};
}
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);
}
private static String[] buildDeps ( final Class<? extends ObjectPayload<?>> payloadClass ) throws Exception {
String[] baseDeps;
if ( DynamicDependencies.class.isAssignableFrom(payloadClass) ) {
@@ -193,9 +190,52 @@ public class PayloadsTest {
return baseDeps;
}
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 {
URL[] urls = getDependencyUrls(dependencies);
Map<String, byte[]> addlClasses = new HashMap<String, byte[]>();
for ( Class<?> clazz : classDependencies ) {
byte[] classAsBytes = ClassFiles.classAsBytes(clazz);
addlClasses.put(clazz.getName(), classAsBytes);
}
addlClasses.put(Deserializer.class.getName(), ClassFiles.classAsBytes(Deserializer.class));
if (customDeserializer != null) {
try {
Method method = customDeserializer.getMethod("getExtraDependencies");
for (Class extra : (Class[]) method.invoke(null)) {
addlClasses.put(extra.getName(), ClassFiles.classAsBytes(extra));
}
} catch (NoSuchMethodException e) {}
addlClasses.put(customDeserializer.getName(), ClassFiles.classAsBytes(customDeserializer));
}
OpenURLClassLoader isolatedClassLoader = new OpenURLClassLoader(urls, null);
for (Map.Entry<String, byte[]> e : addlClasses.entrySet()) {
isolatedClassLoader.defineNewClass(e.getKey(), e.getValue());
}
Class<?> deserializerClass = isolatedClassLoader.loadClass(customDeserializer != null ? customDeserializer.getName() : Deserializer.class.getName());
Callable<Object> deserializer = (Callable<Object>) deserializerClass.getConstructors()[0].newInstance(serialized);
// set CCL for Clojure https://groups.google.com/forum/#!topic/clojure/F3ERon6Fye0
return callWithContextClassLoader(isolatedClassLoader, deserializer);
}
private static Object callWithContextClassLoader(ClassLoader classLoader, Callable<Object> callable) throws Exception {
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return callable.call();
} finally {
Thread.currentThread().setContextClassLoader(ccl);
}
}
private static URL[] getDependencyUrls(String[] dependencies) throws MalformedURLException {
File[] jars = dependencies.length > 0
? Maven.configureResolver()
.withMavenCentralRepo(true)
@@ -206,46 +246,7 @@ public class PayloadsTest {
for ( int i = 0; i < jars.length; i++ ) {
urls[ i ] = jars[ i ].toURI().toURL();
}
URLClassLoader isolatedClassLoader = new URLClassLoader(urls, null) {
{
for ( Class<?> clazz : classDependencies ) {
byte[] classAsBytes = ClassFiles.classAsBytes(clazz);
defineClass(clazz.getName(), classAsBytes, 0, classAsBytes.length);
}
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)) {
deserializerClassBytes = ClassFiles.classAsBytes(extra);
defineClass(extra.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
}
} catch ( NoSuchMethodException e ) { }
deserializerClassBytes = ClassFiles.classAsBytes(customDeserializer);
defineClass(customDeserializer.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
}
}
};
Class<?> deserializerClass = isolatedClassLoader.loadClass(customDeserializer != null ? customDeserializer.getName() : Deserializer.class.getName());
Callable<Object> deserializer = (Callable<Object>) deserializerClass.getConstructors()[ 0 ].newInstance(serialized);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
try {
// set CCL for Clojure https://groups.google.com/forum/#!topic/clojure/F3ERon6Fye0
Thread.currentThread().setContextClassLoader(isolatedClassLoader);
final Object obj = deserializer.call();
return obj;
} finally {
Thread.currentThread().setContextClassLoader(ccl);
}
return urls;
}
public static void main(String[] args) throws IOException {
@@ -0,0 +1,14 @@
package ysoserial.test.util;
import java.net.URL;
import java.net.URLClassLoader;
public class OpenURLClassLoader extends URLClassLoader {
public OpenURLClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
public Class<?> defineNewClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
@@ -3,10 +3,10 @@ package ysoserial.test.util;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import ysoserial.Strings;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
public class PayloadListener extends RunListener {
public enum Status {
@@ -25,7 +25,7 @@ public class PayloadListener extends RunListener {
@Override
public void testStarted(Description description) throws Exception {
System.out.println(getPayload(description.getDisplayName()) + ": STARTED");
// System.out.println(getPayload(description.getDisplayName()) + ": STARTED");
statuses.put(description, Status.SUCCESS);
@@ -46,8 +46,34 @@ public class PayloadListener extends RunListener {
StdIoRedirection.restoreStreams();
Status status = statuses.get(description);
System.out.println(getPayload(description.getDisplayName()) + ": " + status);
if (status == Status.FAILURE) System.err.println(outs.get(description).toString());
String payload = getPayload(description.getDisplayName());
String out = outs.get(description).toString();
Map<String,String> props = new HashMap<String, String>();
props.put("payload", payload);
props.put("status", status.toString());
// props.put("out", out);
for (String k : Arrays.asList("java.version", "java.vendor", "java.vm.version", "java.runtime.version", "os.arch", "os.name", "os.version")) {
props.put(k, System.getProperty(k));
}
List<String> pairs = new ArrayList<String>();
for (Map.Entry<String, String> e : props.entrySet()) {
StringBuilder sb = new StringBuilder();
sb.append("\"")
.append(e.getKey().replace("\\", "\\\\").replace("\"", "\\\""))
.append("\"")
.append(": ")
.append("\"")
.append(e.getValue().replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\b", "\\b"))
.append("\"");
pairs.add(sb.toString());
}
String obj = "{" + Strings.join(pairs, ", ", "", "") + "}";
System.out.println(obj);
// System.out.println(payload + ": " + status);
}
@Override
@@ -5,6 +5,7 @@ import javassist.util.proxy.ProxyFactory;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*