Back to Articles

BaRMIe: Exploiting Java's Invisible Attack Surface in RMI Services

[ View on GitHub ]

BaRMIe: Exploiting Java's Invisible Attack Surface in RMI Services

Hook

Java RMI services have a 64-bit object identifier space—that's 9 quintillion possibilities to brute force. BaRMIe sidesteps this entirely by exploiting something more valuable: knowledge.

Context

Java Remote Method Invocation has been a staple of enterprise architectures since the late 1990s, enabling distributed object communication across JVMs. While REST APIs and gRPC dominate modern microservices, countless legacy enterprise systems still expose RMI services—often on port 1099, sometimes hidden behind custom ports, and frequently forgotten in security assessments.

The challenge for penetration testers has always been enumeration. Unlike HTTP endpoints that respond with helpful 404s or directory listings, RMI registries are opaque by design. Early tools from 2008 attempted brute-force approaches or disappeared entirely from the security landscape. Meanwhile, the 2015 discovery of widespread deserialization vulnerabilities in Java applications created a new urgency: RMI services became high-value targets because they inherently deserialize data from network calls. BaRMIe emerged to fill this gap, combining knowledge-based enumeration with modern deserialization attack techniques to systematically test what had become an under-examined attack surface in enterprise Java applications.

Technical Insight

Extract Remote

Object References

Remote Stubs

Match Signatures

Identified Interfaces

Insecure Methods

Object Parameters

Any Method

Admin Commands

Malicious Payload

Illegal Parameter

Injection

Gadget Chains

Gadget Chains

Target RMI Registry

Port 1099

Registry Scanner

Interface Matcher

Known Interface Library

JMX/JBoss/WebLogic

Attack Vector

Selection

Direct Method

Invocation

Deserialization

Attack Generator

TCP Proxy

Parameter Swap

Code Execution

Payload Library

ysoserial

System architecture — auto-generated

BaRMIe's architecture revolves around three core attack vectors, each exploiting different aspects of Java RMI's design. The tool begins by connecting to an RMI registry and extracting remote object references—essentially stubs that clients use to invoke methods on remote objects. Rather than attempting to brute-force the 64-bit object identifier space, BaRMIe uses a library of partial RMI interfaces compiled from known software (JMX, JBoss, WebLogic, etc.) to interact with services directly.

The first attack vector is the most straightforward: direct invocation of insecure methods. Many enterprise applications expose administrative functionality through RMI without proper authentication. BaRMIe attempts to call these methods directly when it recognizes the interface:

// Example of an insecure RMI interface that BaRMIe would detect
public interface AdminService extends Remote {
    void deployApplication(String warPath) throws RemoteException;
    String executeCommand(String cmd) throws RemoteException;
    void shutdownServer() throws RemoteException;
}

When BaRMIe identifies such interfaces through its attack module library, it can invoke these methods directly, potentially gaining code execution or administrative control without requiring any deserialization exploits.

The second and more sophisticated attack vector exploits Java's type erasure in RMI parameter handling. When an RMI method declares parameters of type Object, BaRMIe can pass malicious serialized objects that trigger deserialization gadget chains. This works because Java deserializes the parameter before the remote method even executes:

// Vulnerable RMI interface with Object parameter
public interface DataProcessor extends Remote {
    void processData(Object data) throws RemoteException;
}

// BaRMIe sends a ysoserial payload instead of expected data
// The server deserializes it, triggering gadget chains like:
// CommonsCollections, Spring, Rome, etc.

The third attack vector is where BaRMIe truly innovates. It exploits a fundamental flaw in Java RMI: the server doesn't verify that received parameters match the method signature's declared types. BaRMIe operates a TCP proxy that intercepts RMI calls, modifies parameters in transit, and replaces them with malicious serialized objects. Even if a method declares primitive or specific object types, the proxy can substitute a deserialization payload:

// Original method signature with String parameter
public interface UserService extends Remote {
    User getUser(String username) throws RemoteException;
}

// BaRMIe's TCP proxy intercepts the call:
// 1. Client sends: getUser("admin")
// 2. Proxy modifies stream, replacing String with malicious Object
// 3. Server deserializes the malicious Object before type checking
// 4. Gadget chain executes during deserialization

This attack succeeds because Java's RMI implementation deserializes parameters from the network stream before validating types, creating a window for exploitation. The proxy approach means BaRMIe can attack virtually any RMI method, not just those explicitly accepting Object types.

BaRMIe's reliability rating system provides crucial context for penetration testers. Methods rated [+++] target insecure application-specific functionality (like the executeCommand example above)—these are high-reliability attacks that don't depend on gadget chains. Methods rated [+] rely on deserialization attacks, which require vulnerable dependencies in the classpath. This rating system helps testers prioritize their efforts and set realistic expectations for exploit success rates.

The tool's architecture is multi-threaded, allowing it to scan multiple targets concurrently and parse input from nmap XML output or plain text files. Attack modules are implemented as separate classes, making it straightforward to extend BaRMIe with custom attacks for proprietary RMI services you encounter in your assessments.

Gotcha

BaRMIe's effectiveness is directly proportional to its knowledge base. Without partial interfaces for the specific RMI services you're targeting, the tool can only attempt generic deserialization attacks—it won't be able to enumerate specific methods or invoke application-specific functionality. If you're facing a proprietary enterprise application with custom RMI services, you'll need source code, JAR files, or the patience to reverse-engineer and contribute attack modules yourself. The community-contributed attack module library helps, but it primarily covers well-known products like JBoss, WebLogic, and standard JMX implementations.

The tool's success also depends entirely on the presence of exploitable conditions. For direct method invocation attacks, the application must expose genuinely insecure methods—many modern RMI implementations have learned to authenticate and authorize remote calls properly. For deserialization attacks, the target's classpath must contain vulnerable gadget chains (Commons Collections, Spring, etc.), and these are increasingly being patched or removed from production deployments. If you're testing a recently updated Java application with minimal dependencies, BaRMIe may successfully enumerate services but fail to achieve code execution. The tool provides the ammunition, but you still need vulnerable targets. Additionally, as a specialized penetration testing tool, BaRMIe assumes you have authorization to perform active exploitation—it's not designed for passive reconnaissance, and its probing activities will likely be logged by any competent security monitoring system.

Verdict

Use if: You're conducting authorized security assessments of enterprise Java applications that expose RMI services (look for port 1099 or custom ports in your reconnaissance), particularly legacy systems or applications using JMX for management. BaRMIe excels when you've identified RMI endpoints and need to systematically enumerate and exploit them without spending days manually brute-forcing object identifiers or crafting custom RMI clients. It's especially valuable if you're comfortable with Java deserialization concepts and willing to contribute attack modules for new targets you discover. Skip if: You're testing modern cloud-native microservices (which overwhelmingly use REST, gRPC, or message queues instead of RMI), performing only passive reconnaissance where active exploitation isn't authorized, or working in environments where you lack the Java expertise to interpret results and extend the tool's capabilities. Also skip it if you're hoping for a fully automated "point-and-pwn" experience—BaRMIe is a specialist's tool that requires understanding RMI internals, deserialization attack chains, and the specific enterprise software you're targeting.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/nickstadb-barmie.svg)](https://starlog.is/api/badge-click/developer-tools/nickstadb-barmie)