mirror of
https://github.com/frohoff/ysoserial.git
synced 2026-09-26 17:01:53 +08:00
refactors
This commit is contained in:
@@ -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/
|
|
||||||
@@ -2,10 +2,21 @@ package ysoserial;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
public class CiTest {
|
public class CiTest {
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
System.out.println("System.getProperties(): " + System.getProperties());
|
for (Map.Entry<Object,Object> e : new TreeMap<Object,Object>(System.getProperties()).entrySet()) {
|
||||||
System.out.println("System.getenv(): " + System.getenv());
|
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.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
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;
|
||||||
|
|
||||||
@@ -33,6 +35,7 @@ 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.test.util.Logging;
|
import ysoserial.test.util.Logging;
|
||||||
|
import ysoserial.test.util.OpenURLClassLoader;
|
||||||
import ysoserial.test.util.PayloadListener;
|
import ysoserial.test.util.PayloadListener;
|
||||||
import ysoserial.test.util.StdIoRedirection;
|
import ysoserial.test.util.StdIoRedirection;
|
||||||
|
|
||||||
@@ -140,11 +143,8 @@ public class PayloadsTest {
|
|||||||
}
|
}
|
||||||
if (ex != null) throw ex;
|
if (ex != null) throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static Callable<byte[]> makeSerializeCallable ( final Class<? extends ObjectPayload<?>> payloadClass, final String command ) {
|
private static Callable<byte[]> makeSerializeCallable ( final Class<? extends ObjectPayload<?>> payloadClass, final String command ) {
|
||||||
return new Callable<byte[]>() {
|
return new Callable<byte[]>() {
|
||||||
|
|
||||||
@@ -158,7 +158,6 @@ public class PayloadsTest {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps,
|
private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps,
|
||||||
final byte[] serialized, final Class<?> customDeserializer ) {
|
final byte[] serialized, final Class<?> customDeserializer ) {
|
||||||
return new Callable<Object>() {
|
return new Callable<Object>() {
|
||||||
@@ -169,14 +168,12 @@ public class PayloadsTest {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean checkPrecondition ( Class<? extends ObjectPayload<?>> pc, String precondition )
|
private static boolean checkPrecondition ( Class<? extends ObjectPayload<?>> pc, String precondition )
|
||||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Method precondMethod = pc.getMethod(precondition);
|
Method precondMethod = pc.getMethod(precondition);
|
||||||
return (Boolean) precondMethod.invoke(null);
|
return (Boolean) precondMethod.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static String[] buildDeps ( final Class<? extends ObjectPayload<?>> payloadClass ) throws Exception {
|
private static String[] buildDeps ( final Class<? extends ObjectPayload<?>> payloadClass ) throws Exception {
|
||||||
String[] baseDeps;
|
String[] baseDeps;
|
||||||
if ( DynamicDependencies.class.isAssignableFrom(payloadClass) ) {
|
if ( DynamicDependencies.class.isAssignableFrom(payloadClass) ) {
|
||||||
@@ -193,9 +190,52 @@ public class PayloadsTest {
|
|||||||
return baseDeps;
|
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 {
|
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
|
File[] jars = dependencies.length > 0
|
||||||
? Maven.configureResolver()
|
? Maven.configureResolver()
|
||||||
.withMavenCentralRepo(true)
|
.withMavenCentralRepo(true)
|
||||||
@@ -206,46 +246,7 @@ public class PayloadsTest {
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
return urls;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
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.Description;
|
||||||
import org.junit.runner.notification.Failure;
|
import org.junit.runner.notification.Failure;
|
||||||
import org.junit.runner.notification.RunListener;
|
import org.junit.runner.notification.RunListener;
|
||||||
|
import ysoserial.Strings;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class PayloadListener extends RunListener {
|
public class PayloadListener extends RunListener {
|
||||||
public enum Status {
|
public enum Status {
|
||||||
@@ -25,7 +25,7 @@ public class PayloadListener extends RunListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void testStarted(Description description) throws Exception {
|
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);
|
statuses.put(description, Status.SUCCESS);
|
||||||
|
|
||||||
@@ -46,8 +46,34 @@ public class PayloadListener extends RunListener {
|
|||||||
StdIoRedirection.restoreStreams();
|
StdIoRedirection.restoreStreams();
|
||||||
|
|
||||||
Status status = statuses.get(description);
|
Status status = statuses.get(description);
|
||||||
System.out.println(getPayload(description.getDisplayName()) + ": " + status);
|
String payload = getPayload(description.getDisplayName());
|
||||||
if (status == Status.FAILURE) System.err.println(outs.get(description).toString());
|
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
|
@Override
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import javassist.util.proxy.ProxyFactory;
|
|||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user