1098/1099/1050 - Pentesting Java RMI - RMI-IIOP

👉 Overview


👀 What ?

Java's Remote Method Invocation (RMI) is a Java API that performs the object-oriented equivalent of remote procedure calls (RPC), with support for direct transfer of serialized Java objects and distributed garbage collection. RMI-IIOP (RMI over Internet Inter-Orb Protocol) is a version of RMI that allows for interoperability with CORBA (Common Object Request Broker Architecture) objects. Pentesting, or penetration testing, is a method of evaluating the security of a computer system, network or web application by simulating attacks by a malicious actor.

🧐 Why ?

Understanding and being able to exploit Java RMI and RMI-IIOP is crucial because they are widely used in enterprise environments. The ability to test and exploit these services can provide valuable entry points into a network or system during a penetration test. A successful RMI/RMI-IIOP exploit could potentially lead to full compromise of the target system.

⛏️ How ?

Pentesting Java RMI and RMI-IIOP typically involves several steps. First, the tester must identify and locate the service, which usually involves scanning and enumeration. Once the service is located, the tester must determine if the service is vulnerable, typically by attempting to call methods or access data that should be restricted. If the service is vulnerable, the tester will then attempt to exploit the vulnerability to gain unauthorized access or data. The specific techniques and tools used will vary depending on the details of the target system and the vulnerability being exploited.

⏳ When ?

Pentesting of Java RMI and RMI-IIOP is typically performed during a penetration test of a network or system that is known to use these technologies. It can also be performed as part of regular security audits or when a new system is being deployed or an existing system is being upgraded or modified.

⚙️ Technical Explanations


Java Remote Method Invocation (RMI) and RMI over Internet Inter-Orb Protocol (RMI-IIOP) are technologies that allow objects in one Java virtual machine to call methods on objects in another, potentially on a different machine entirely. This is enabled by the use of stub and skeleton objects which act as intermediaries between the client and server objects.

In more detail, the client-side stub and server-side skeleton are key players in this process. The stub is responsible for initiating the call to the remote object and for forwarding the request to the server-side skeleton, which then invokes the method on the actual server object. The results are then returned to the client via the same route.

This communication is achieved using a specific protocol. In the case of Java RMI, it's Java's native RMI protocol, whereas RMI-IIOP uses the IIOP protocol of CORBA (Common Object Request Broker Architecture), a platform- and language-neutral distributed object system. This IIOP compatibility allows for interoperability with CORBA objects, meaning that RMI objects can interact with non-Java CORBA objects.

When it comes to pentesting these services, the tester looks to invoke methods on the server object that have not been properly secured. This could potentially allow the tester to execute arbitrary code or access sensitive data. The process involves several steps. Firstly, the service must be located, usually through scanning and enumeration. Then, the tester determines if the service is vulnerable, often by attempting to call restricted methods or access restricted data. If a vulnerability is found, the tester will try to exploit it to gain unauthorized access or retrieve data.

Remember that the specific techniques and tools used in pentesting Java RMI and RMI-IIOP can vary greatly, depending on the specifics of the target system and the vulnerability being exploited. As such, a thorough understanding of these technologies and how they work is crucial for effective penetration testing.

Let's consider a simple example of a Java RMI service that we will pentest. This service has a single remote method named fetchData() that retrieves sensitive data.

First, we locate the service. We can use a tool like nmap to do this:

nmap -p 1099 target_ip

Here, 1099 is the default port for RMI services, and target_ip is the IP address of the system we're testing.

If the service is running, we should see something like:

PORT     STATE SERVICE
1099/tcp open  rmiregistry

Next, we want to understand what methods are available. We can use the rmic tool that comes with the Java SDK:

rmic -classpath path_to_classes target_class_name

If fetchData() is not properly secured, we could invoke it. Let's assume we have a client stub class targetClass_Stub. We can then create a client as follows:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.getRegistry("target_ip");
            targetClass_Stub targetObject = (targetClass_Stub) registry.lookup("targetObjectName");
            System.out.println(targetObject.fetchData());
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

In this code, target_ip is the IP address of the target system, targetClass_Stub is the client stub class, and targetObjectName is the name of the remote object. If fetchData() is improperly secured, this could print sensitive data.

Remember, this is a simplified example for educational purposes. Real-world systems may require more complex techniques and tools, and you should have permission before pentesting any system.

We use cookies

We use cookies to ensure you get the best experience on our website. For more information on how we use cookies, please see our cookie policy.