Remote Method Guesser | Tool For Java RMI Enumeration And Bruteforce Of Remote Methods

Remote Method Guesser

remote-method-guesser (rmg) is a command line utility written in Java and can be used to identify security vulnerabilities on Java RMI endpoints. Currently, the following operations are supported:

  • List available bound names and their corresponding interface class names
  • List codebase locations (if exposed by the remote server)
  • Check for known vulnerabilities (enabled class loader, missing JEP290, localhost bypass)
  • Identify existing remote methods by using a bruteforce (wordlist) approach
  • Call remote methods with ysoserial gadgets within the arguments
  • Call remote methods with a client specified codebase (remote class loading attack)
  • Perform DGC and registry calls with ysoserial gadgets or a client specified codebase
  • Perform bind, unbind and rebind operations against a registry
  • Extend ysoserial gadgets with An Trinhs registry bypass
  • Enumerate the unmarshalling behavior of java.lang.String
  • Create Java code dynamically to invoke remote methods manually

During remote method guessing, deserialization and codebase attacks, the argument types of remote method calls are confused to prevent method invocation on the server side. This technique is not unique to remote-method-guesser and was used first (to the best of my knowledge) by Jake Miller in the rmiscout project.

Remote Method Guesser Example

Installation

rmg is a maven project and installation should be straight forward. With maven installed, just execute the following commands to create an executable .jar file:

$ git clone https://github.com/qtc-de/remote-method-guesser
$ cd remote-method-guesser
$ mvn package

rmg also supports autocompletion for bash. To take advantage of autocompletion, you need to have the completion-helpers project installed. If setup correctly, just copying the completion script to your ~/.bash_completion.d folder enables autocompletion.

$ cp resources/bash_completion.d/rmg ~/bash_completion.d/

Supported Operations

In the following, short examples for each available operation are presented. For a more detailed description you should read the documentation folder. All presented examples are based on the rmg-example-server which is also contained within this project. You can also modify and rebuild the example server yourself, by using the sources within the docker folder.

[qtc@kali ~]$ rmg --help
usage: rmg [options] <ip> <port> <action>

rmg v3.1.0 - Identify common misconfigurations on Java RMI endpoints.

Positional Arguments:
    ip                              IP address of the target
    port                            Port of the RMI registry
    action                          One of the possible actions listed below

Possible Actions:
    act <gadget> <command>          Performs Activator based deserialization attacks
    bind <boundname> <listener>     Binds an object to the registry thats points to listener
    codebase <classname> <url>      Perform remote class loading attacks
    dgc <gadget> <command>          Perform DGC based deserialization attacks
    enum                            Enumerate bound names, classes, SecurityManger and JEP290
    guess                           Guess methods on bound names
    listen <gadget> <command>       Open ysoserials JRMP listener
    method <gadget> <command>       Perform method based deserialization attacks
    rebind <boundname> <listener>   Rebinds boundname as object that points to listener
    reg <gadget> <command>          Perform registry based deserialization attacks
    unbind <boundName>              Removes the specified bound name from the registry

Optional Arguments:
    --argument-position <int>       select argument position for deserialization attacks
    --bound-name <name>             guess only on the specified bound name
    --config <file>                 path to a configuration file
    --create-samples                create sample classes for identified methods
    --dgc-method <method>           method to use during dgc operations (clean|dirty)
    --follow                        follow redirects to different servers
    --force-legacy                  treat all classes as legacy stubs
    --help                          display help message
    --localhost-bypass              attempt localhost bypass for registry operations (CVE-2019-2684)
    --no-color                      disable colored output
    --no-legacy                     disable automatic legacy stub detection
    --reg-method <method>           method to use during registry operations (bind|lookup|unbind|rebind)
    --sample-folder <folder>        folder used for sample generation
    --signature <method>            function signature or one of (dgc|reg|act)
    --ssl                           use SSL for the rmi-registry connection
    --stack-trace                   display stack traces for caught exceptions
    --template-folder <folder>      location of the template folder
    --threads <int>                 maximum number of threads (default: 5)
    --trusted                       disable bound name filtering
    --update                        update wordlist file with method hashes
    --wordlist-file <file>          wordlist file to use for method guessing
    --wordlist-folder <folder>      location of the wordlist folder
    --yso <file>                    location of ysoserial.jar for deserialization attacks
    --zero-arg                      allow guessing on void functions (dangerous)

Enumeration (enum)

The enum action performs several checks on the specified RMI registry endpoint. It provides a list of all available bound names, displays the servers codebase (if existent), checks for missing JEP290 and some other common vulnerabilities. enum is the default action of remote-method-guesser and can either be invoked by only specifying the port and IP address of a target or by specifying enum as action explicitly.

[qtc@kali ~]$ rmg --ssl 172.18.0.2 1090
[+] RMI registry bound names:
[+] 
[+] 	- plain-server
[+] 		--> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+] 	- ssl-server
[+] 		--> de.qtc.rmg.server.interfaces.ISslServer (unknown class)
[+] 	- secure-server
[+] 		--> de.qtc.rmg.server.interfaces.ISecureServer (unknown class)
[+] 
[+] RMI server codebase enumeration:
[+] 
[+] 	- http://iinsecure.dev/well-hidden-development-folder/
[+] 		--> de.qtc.rmg.server.interfaces.ISslServer
[+] 		--> de.qtc.rmg.server.interfaces.IPlainServer
[+] 		--> javax.rmi.ssl.SslRMIClientSocketFactory
[+] 		--> de.qtc.rmg.server.interfaces.ISecureServer
[+] 
[+] RMI server String unmarshalling enumeration:
[+] 
[+] 	- Caught MalformedURLException during lookup call.
[+] 	  --> The type java.lang.String is unmarshalled via readObject().
[+] 	  Configuration Status: Outdated
[+] 
[+] RMI server useCodebaseOnly enumeration:
[+] 
[+] 	- Caught MalformedURLException during lookup call.
[+] 	  --> The server attempted to parse the provided codebase (useCodebaseOnly=false).
[+] 	  Configuration Status: Non Default
[+] 
[+] RMI registry localhost bypass enumeration (CVE-2019-2684):
[+] 
[+] 	- Caught NotBoundException during unbind call (unbind was accepeted).
[+] 	  Vulnerability Status: Vulnerable
[+] 
[+] RMI DGC enumeration:
[+] 
[+] 	- Security Manager rejected access to the class loader.
[+] 	  --> The DGC uses most likely a separate security policy.
[+] 	  Configuration Status: Current Default
[+] 
[+] RMI server JEP290 enumeration:
[+] 
[+] 	- DGC rejected deserialization of java.util.HashMap (JEP290 is installed).
[+] 	  Vulnerability Status: Non Vulnerable
[+] 
[+] RMI registry JEP290 bypass enmeration:
[+] 
[+] 	- Caught IllegalArgumentException after sending An Trinh gadget.
[+] 	  Vulnerability Status: Vulnerable
[+] 
[+] RMI ActivationSystem enumeration:
[+] 
[+] 	- Caught NoSuchObjectException during activate call (activator not present).
[+] 	  Configuration Status: Current Default

Bind Operations (bind|rebind|unbind)

By using the bind, rebind or unbind action, it is possible to modify the available bound names within the RMI registry. This is especially useful for verifying CVE-2019-2684, which bypasses the localhost restrictions and enables remote users to perform bind operations. Whereas the unbind action only requires the bound name that should be removed, the bind and rebind operations also require a RemoteObject that should be bound. remote-method-guesser always uses javax.management.remote.rmi.RMIServerImpl_Stub for this purpose, which is the RemoteObject used by jmx. You need also to specify the address of the corresponding TCP endpoint (address where clients should connect to, when they attempt to use your bound object).

Continue readingโ€ฆ

GitHub:

https://github.com/qtc-de/remote-method-guesser

3 Likes