安全软件
点击放大

---
![maven CI]()
![maven CI]()
![]()
![]()
![]()
![]()
![]()
*remote-method-guesser* (*rmg*) is a *Java RMI* scanner and can be used to identify and common security
on *Java RMI* endpoints.
!Remote Method Guesser Example
![BHUSA Arsenal 2021]()
*remote-method-guesser* was presented at Black Hat USA2021
within the *Arsenal* sessions. The recording of the session and the corresponding slides are publicly a and can be found using the following links:
* Slides:
* Recording:
![example server]()
![ssrf server]()
![spring server]()
The *remote-method-guesser* repository contains three example servers that can be used to practice *Java RMI* enumeration and attacks.
The rmg-example-server exposes regular *RMI* services that can be enumerated and exploited using *remote-method-guesser*.
The rmg-ssrf-server exposes an *HTTP* service that is to *SSRF* attacks and runs *RMI* services that are only
listening on localhost. This can be used to practice with *remote-method-guesser's* `--ssrf and --ssrf-response options.
The spring-remoting-server exposes RMI interfaces created via *Spring Remoting*. These are a little bit different from
regular Java RMI and can be used to test the associated Spring Remoting integration of remote-method-guesser.
All servers are a as containers within the *GitHub Container Registry*:
* SSRF Ser Package
* Example Ser Package
* Spring Remoting Ser Package
----
------
*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:
You can also use prebuild packages that are created for each release.
Prebuild packages for the de branch are created automatically and can be found on the *GitHub* actions page.
*rmg* does not include *ysoserial* as a dependency. To enable *ysoserial* support, you need either specify the path
to your ysoserial.jar file as additional argument (e.g. --yso /opt/ysoserial.jar) or you change the
default path within the rmg configuration file before building the project.
*rmg* also supports autocompletion for *bash*. To take ad 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.
-----
In the following, short examples for each a operation are presented. For a more detailed description,
you should read the documentation folder that contains more detailed information on *rmg* and *Java RMI*
in general. All presented examples are based on the rmg-example-server
and the rmg-ssrf-server.
Both of them are contained within this repository in the docker folder and can be used to practice *Java RMI* enumeration.
You can either build the corresponding containers yourself or load them directly from the *GitHub Container Registry*.
#### bind, rebind and unbind
By using the bind, rebind or unbind action, it is possible to modify the a *bound names* within the *RMI registry*.
This is especially useful for C, which bypasses the localhost restrictions and enables remote users to perform
bind operations. When using the bind or rebind action *remote-method-guesser* binds the ja.remote.rmi.RMISer
*RemoteObject* by default, which is the *RemoteObject* used by *jmx* servers. Additionally, you need to specify the address of the corresponding
*TCP endpoint* where the *RemoteObject* can be found (address where clients should connect to, when they attempt to use your bound object).
By using *remote-method-guesser's Plugin System*, it is also possible to bind custom objects to the *RMI registry*. To learn more about
the *Plugin System*, please refer to the documentation folder.
#### call
Using *remote-method-guesser's* call action, you can invoke remote methods without writing any *Java code*. Consider the
method String execute(String cmd) exists on the remote server. This method sounds promising and you may want to invoke
it using a regular *Java RMI call*. This can be done by using the following command:
Notice that calling remote methods does not create any output by default. To process outputs generated by the call action, you need
to use *remote-method-guesser's* plugin system and register a ResponseHandler or use the defaultGenericPrint plugin. GenericPrint is inlcuded into *remote-method-guesser* by default and can be activated by using the --show-response
option.
During the call action, the provided arguments are e as *Ja* by inserting them into the following template:new Object[]{ arg1, arg2, arg3, ... }. Therefore, you need to make sure that your provided arguments fit into that pattern. E.g.
using "id" as an argument results in an error, as the argument is passed as id to *remote-method-guesser* and the resulting
expression new Object[]{ id } is not a valid *Ja*. Instead, you need to use '"id"' as this leads to new Object[]{ "id" },
which is valid.
Moreover, primiti need to be specified in their corresponding object representation (e.g. new Integer(5) instead of 5). Otherwise they
cannot be used within the Object[] array, that is created by the *Ja*. During the *RMI call*, the corresponding arguments are used
as intended and will fit your specified method signature. For more complex use cases, you can also define a custom ArgumentProvider by using
*remote-method-guessers* plugin system.
#### codebase
*Java RMI* supports a feature called *codebases*, where the client and the server can specify *URLs* during *RMI calls* that
may be used to load unknown classes dynamically. If an *RMI server* accepts a *client specified codebase*, this can lead to
*remote code execution* when the client provides a malicious *Ja during the *RMI communication*.
The codebase configuration on an *RMI server* can be different for the different components: *Activator*, *DGC*, *Registry* and *Application Level*.
*remote-method-guesser* allows you to test each component indi by using either --signature <method> (application level),--component act (activator), --component dgc (distributed garbage collector) or --component reg (RMI registry) together with thecodebase action.
*Application Level*:
*RMI Registry*:
*Distributed Garbage Collector*:
*Activator*:
#### enum
The enum action performs several checks on the specified *Java RMI* endpoint and prints the corresponding results. For a
more detailed explanation on the output generated by the enum action, you can read the corresponding documentation
page.
#### guess
When using the guess action, *remote-method-guesser* attempts to identify existing remote methods by sending method hashes
to the remote server. This operation requires a wordlist that contains the corresponding method definitions.
*remote-method-guesser* ships some default wordlists that are included into the .jar file during the build phase.
You can o wordlist locations by either modifying the rmg configuration file or by using the --wordlist-file
or --wordlist-folder options. Methods with zero arguments are skipped during guessing, as they lead to real method calls
on the server side. You can enable guessing on zero argument methods by using the --zero-arg switch.
#### known
When performing the enum action, *remote-method-guesser* marks a *bound names* on the *RMI registry* ever
as *known* or as *unknown*. This decision depends on the class that is implemented by the corresponding bound name and
whether the corresponding class is contained within the known endpoint list that is contained
within the *remote-method-guesser* repository. When a *bound name* is marked as *known*, you can use the known action
on the corresponding class. Doing so returns information on the corresponding class like the a remote methods,
a general description and possible :
The list of known classes, their description and the list of known is far from being complete.
It will hopefully grow in future and is driven by input from other users. If you encounter an *RMI endpoint*
that implements a currently missing class and you ha information (description and a methods),
feel free to create an issue or pull request.
#### listen
Sometimes it is required to provide a malicious *JRMPListener*, which ser payloads
to incoming *RMI* connections. Writing such a listener from scratch is not necessary, as it is already provided by the
ysoserial project.
*remote-method-guesser* provides a wrapper around the *ysoserial* implementation, which lets you spawn a *JRMPListener*
by using the usual *rmg* syntax:
#### objid
The objid action can be used to display more detailed information on an ObjID. Each *RemoteObject* gets assigned
an ObjID when it is exported by the *RMI runtime*. Knowledge of the ObjID value is required to communicate with
a *RemoteObject*, which is also the case why you usually need an *RMI registry*. The *RMI registry* contains the ObjID
for each *bound name* and *remote-method-guesser* displays them during the enum action.
ObjID consist out of different components. These components are displayed in human readable form when
using the objid action on the corresponding ObjID:
Most of the displayed information is not that useful, but the *Time* value can be interesting. This value contains
the time when the *RemoteObject* was created. Therefore, it allows you to determine things like the up-time of an
*RMI* server.
#### scan
Sometimes you identify services that are common to ship *Java RMI* components with them (*JBoss*, *Solr*, *Tomcat*, ...),
but you do not want to perform a full portscan on the corresponding host. In these situations, the scan action
can be useful. It performs a quick port scan for common *RMI* ports only and attempts to identify *RMI* services
on them:
By default, the scan actions uses a preconfigured list of common *RMI ports*. To customize the list of ports to scan,
you can use the --ports option. This option accepts plain numbers and number ranges for port specifications.
The dash character (-) can be used to reference the default port list.
Notice that the scan action is implemented in a simple and non reliable way. If possible, you should
always perform a dedicated portscan using tools like nmap. However, the scan action
can give you a quick heads-up on finding *RMI ports*.
#### roguejmx
The roguejmx actions creates a *JMX listener* on your system that captures credentials of incoming connections.
After creating the listener, *remote-method-guesser* prints the *ObjID* value that is required to interact with it.
Using the bind and rebind operations you can inject this listener into an *RMI registry* and wait for other
users connecting to your server:
Incoming connections are logged by the listener:
*remote-method-guesser* uses the *ObjID* value [6633018:17cb5d1bb57:-7ff8, -17646722] by default for *bind* operations
and the rouge *JMX* server. Specifying the *ObjID* manually as shown above is therefore not necessary. You can change the default
*ObjID* value either line arguments or within *remote-method-guesser's* configuration file.
The rogue *JMX* ser an access exception (invalid credentials) for each incoming connection by default, but
you can also forward incoming connections to a different *JMX* instance. This makes it possible to obtain credentials
from incoming client connections without disrupting any services. To forward connections, you have to specify the
corresponding target as an additional argument. Targets can be specified in two different ways:
1. The IP address and port of an RMI registry together with the bound name of the corresponding *JMX instance*:
2. The IP address and port of the *JMX* service itself together with it's *ObjID* value:
#### serial
*Java RMI* uses *Ja objects* within the client ser. This makes it potentially
to *deserialization attacks*. These attacks can target different *RMI components*:
* Well known *RMI components* (*RMI internals*)
* *RMI registry*
* *DGC*
* *Activator*
* User defined *RemoteObjects* (*application level*)
##### Well Known RMI Components
Whereas modern *RMI servers* apply *deserialization filters* on these *well known RMI components* (*JEP290*), older servers may still be to *deserialization
attacks*. *remote-method-guesser* allows to this by using the serial action, that can perform deserialization attacks on the *Activator*, *Distributed
Garbage Collector* (*DGC*) or the *RMI registry*.
In case of the *RMI registry*, the *deserialization filters* may be bypassed by using the JRMPClient
or the An Trinh bypass gadgets. These gadgets create an *outbound RMI channel*
that does no longer apply *deserialization filters*. On this channel, deserialization attacks can be applied as usual, but both bypasses were patched
in the most recent of *Java RMI*.
During it's enum action, *remote-method-guesser* informs you whether an *Activator* is present on an *RMI endpoint* (legacy *RMI component*).
The default implementation for the *Acti system* does not implement any deserialization filters for the *Activator RemoteObject*. Therefore,
deserialization attacks on an *Activator* endpoint should always work, even on most recent *Ja*.
##### Application Level
Whereas modern *Java RMI* implementations protect well known *RMI components* with *deserialization filters* per default, custom
*RemoteObjects* (actual *RMI applications*) are usually not protected. Remote methods that do not only use primiti within
their arguments can therefore be used for *deserialization attacks*.
This blog post by Hans-Martin Münch
explains this issue in more detail. *remote-method-guesser* can be used to easily such . As an example,
we can use the String login(java.util.HashMap dummy1) method of the *remote-method-guesser's* example server to perform a
deserialization attack:
*remote-method-guesser* includes many features that are not explained within this *README.md* file. Some
of them are listed below:
* Almost all operations can be used with the --ssrf option to create an *SSRF* payload for the corresponding
operation.
* If you obtained binary *RMI server* output (e.g. after an *SSRF* attack), you can feed it into *remote-method-guesser*
by using the --ssrf-response option. This parses the ser as it was obtained by the specified operation.
* *remote-method-guesser* can be extended by using it's *Plugin System*. Four interfaces (IPayloadProvider, IResponseHandler,
IArgumentProvider and ISocketFactoryProvider) can be used to adopt *remote-method-guesser* to more complex
usage scenarios.
* During the guess action, you can use the --create-samples option to generate *Java* code that can be used to
invoke successfully guessed methods.
More information on these features can be found within the documentation folder.
----
Since v4.4.0, *remote-method-guesser* is also a as docker image and can be pulled from the
GitHub Container Registry.
For each release, there is a *normal* and a *slim* a. Both provide a full working of
*remote-method-guesser*, but only the *normal* ships with ysoserial
included, resulting in a larger image size:
* docker pull ghcr.io/qtc-de/remote-method-guesser/rmg:4.4.0 - 121MBdocker pull ghcr.io/qtc-de/remote-method-guesser/rmg:4.4.0-slim
* - 61.9MB`
You can also build the container on your own by running the following commands:
----
*remote-method-guesser* was heavily influenced by the blog posts of Hans-Martin Münch
and Jake Miller. Furthermore, the rmiscout wordlist was ob copied from the rmiscout
project (as you can already tell by the different license agreement). Thanks *Jake*, for this awesome wordlist of *remote methods* collected from different *GitHub* repositories.
*Copyright 2023, Tobias Neitzel and the remote-method-guesser contributors.*
开发语言:Java
Star 数:935
该项目属于安全软件方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕Java RMI Vulnerability Scanner展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | remote-method-guesser - Java RMI Vulnerability Scanner |
| 所属分类 | 安全软件 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 22:35:01 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 86 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |