Java Remote Method Invocation, or Java RMI, είναι ένας αντικειμενοστραφής μηχανισμός RPC που επιτρέπει σε ένα αντικείμενο που βρίσκεται σε μια Java virtual machine να καλεί μεθόδους σε ένα αντικείμενο που βρίσκεται σε άλλη Java virtual machine. Αυτό επιτρέπει στους προγραμματιστές να γράφουν κατανεμημένες εφαρμογές χρησιμοποιώντας μια αντικειμενοστραφή παρα paradigma. Μια σύντομη εισαγωγή στο Java RMI από επιθετική προοπτική μπορεί να βρεθεί σε αυτή την ομιλία blackhat.
PORT STATE SERVICE VERSION
1090/tcp open ssl/java-rmi Java RMI
9010/tcp open java-rmi Java RMI
37471/tcp open java-rmi Java RMI
40259/tcp open ssl/java-rmi Java RMI
Συνήθως, μόνο τα προεπιλεγμένα Java RMI συστατικά (το RMI Registry και το Activation System) είναι δεσμευμένα σε κοινές θύρες. Τα remote objects που υλοποιούν την πραγματική RMI εφαρμογή είναι συνήθως δεσμευμένα σε τυχαίες θύρες όπως φαίνεται στην έξοδο παραπάνω.
Το nmap έχει μερικές φορές προβλήματα στην αναγνώριση SSL προστατευμένων RMI υπηρεσιών. Εάν συναντήσετε μια άγνωστη ssl υπηρεσία σε μια κοινή RMI θύρα, θα πρέπει να ερευνήσετε περαιτέρω.
RMI Components
Για να το θέσουμε απλά, το Java RMI επιτρέπει σε έναν προγραμματιστή να κάνει ένα Java object διαθέσιμο στο δίκτυο. Αυτό ανοίγει μια TCP θύρα όπου οι πελάτες μπορούν να συνδεθούν και να καλέσουν μεθόδους στο αντίστοιχο αντικείμενο. Παρά το γεγονός ότι αυτό ακούγεται απλό, υπάρχουν αρκετές προκλήσεις που πρέπει να επιλύσει το Java RMI:
Για να αποστείλουν μια κλήση μεθόδου μέσω Java RMI, οι πελάτες πρέπει να γνωρίζουν τη διεύθυνση IP, τη θύρα ακρόασης, την υλοποιημένη κλάση ή διεπαφή και το ObjID του στοχευμένου αντικειμένου (το ObjID είναι ένας μοναδικός και τυχαίος αναγνωριστής που δημιουργείται όταν το αντικείμενο καθίσταται διαθέσιμο στο δίκτυο. Είναι απαραίτητο επειδή το Java RMI επιτρέπει σε πολλαπλά αντικείμενα να ακούν στην ίδια TCP θύρα).
Οι απομακρυσμένοι πελάτες μπορεί να δεσμεύσουν πόρους στον διακομιστή καλώντας μεθόδους στο εκτεθειμένο αντικείμενο. Η Java virtual machine πρέπει να παρακολουθεί ποιοι από αυτούς τους πόρους είναι ακόμα σε χρήση και ποιοι μπορούν να συλλεχθούν ως σκουπίδια.
Η πρώτη πρόκληση επιλύεται από το RMI registry, το οποίο είναι βασικά μια υπηρεσία ονοματοδοσίας για το Java RMI. Το RMI registry είναι επίσης μια RMI service, αλλά η υλοποιημένη διεπαφή και το ObjID είναι σταθερά και γνωστά σε όλους τους RMI πελάτες. Αυτό επιτρέπει στους RMI πελάτες να καταναλώνουν το RMI registry απλά γνωρίζοντας την αντίστοιχη TCP θύρα.
Όταν οι προγραμματιστές θέλουν να κάνουν τα Java objects τους διαθέσιμα στο δίκτυο, συνήθως τα δεσμεύουν σε ένα RMI registry. Το registry αποθηκεύει όλες τις πληροφορίες που απαιτούνται για να συνδεθεί κανείς με το αντικείμενο (διεύθυνση IP, θύρα ακρόασης, υλοποιημένη κλάση ή διεπαφή και την τιμή ObjID) και τις καθιστά διαθέσιμες υπό ένα ανθρώπινα αναγνώσιμο όνομα (το bound name). Οι πελάτες που θέλουν να καταναλώσουν την RMI service ζητούν από το RMI registry το αντίστοιχο bound name και το registry επιστρέφει όλες τις απαιτούμενες πληροφορίες για τη σύνδεση. Έτσι, η κατάσταση είναι βασικά η ίδια με μια συνηθισμένη DNS υπηρεσία. Η παρακάτω καταχώρηση δείχνει ένα μικρό παράδειγμα:
importjava.rmi.registry.Registry;importjava.rmi.registry.LocateRegistry;importlab.example.rmi.interfaces.RemoteService;publicclassExampleClient {privatestaticfinalString remoteHost ="172.17.0.2";privatestaticfinalString boundName ="remote-service";publicstaticvoidmain(String[] args){try {Registry registry =LocateRegistry.getRegistry(remoteHost); // Connect to the RMI registryRemoteService ref = (RemoteService)registry.lookup(boundName); // Lookup the desired bound nameString response =ref.remoteMethod(); // Call a remote method} catch( Exception e) {e.printStackTrace();}}}
Η δεύτερη από τις παραπάνω προκλήσεις επιλύεται από τον Distributed Garbage Collector (DGC). Αυτή είναι μια άλλη RMI service με μια γνωστή τιμή ObjID και είναι διαθέσιμη σε βασικά κάθε RMI endpoint. Όταν ένας RMI client αρχίζει να χρησιμοποιεί μια RMI service, στέλνει μια πληροφορία στον DGC ότι το αντίστοιχο remote object είναι σε χρήση. Ο DGC μπορεί στη συνέχεια να παρακολουθεί τον αριθμό αναφορών και είναι σε θέση να καθαρίζει τα μη χρησιμοποιούμενα αντικείμενα.
Μαζί με το αποσυρθέν Activation System, αυτά είναι τα τρία προεπιλεγμένα συστατικά του Java RMI:
Ο RMI Registry (ObjID = 0)
Το Activation System (ObjID = 1)
Ο Distributed Garbage Collector (ObjID = 2)
Τα προεπιλεγμένα συστατικά του Java RMI είναι γνωστά επιθετικά σημεία εδώ και αρκετό καιρό και υπάρχουν πολλές ευπάθειες σε παλιές εκδόσεις του Java. Από την οπτική γωνία ενός επιτιθέμενου, αυτά τα προεπιλεγμένα συστατικά είναι ενδιαφέροντα, επειδή υλοποιούν γνωστές κλάσεις / διεπαφές και είναι εύκολο να αλληλεπιδράσετε μαζί τους. Αυτή η κατάσταση είναι διαφορετική για τις προσαρμοσμένες RMI services. Για να καλέσετε μια μέθοδο σε ένα remote object, πρέπει να γνωρίζετε την αντίστοιχη υπογραφή μεθόδου εκ των προτέρων. Χωρίς να γνωρίζετε μια υπάρχουσα υπογραφή μεθόδου, δεν υπάρχει τρόπος να επικοινωνήσετε με μια RMI service.
RMI Enumeration
remote-method-guesser είναι ένας σαρωτής ευπαθειών Java RMI που είναι ικανός να εντοπίζει αυτόματα κοινές RMI vulnerabilities. Όποτε εντοπίζετε ένα RMI endpoint, θα πρέπει να το δοκιμάσετε:
$ rmg enum 172.17.0.2 9010
[+] RMI registry bound names:
[+]
[+] - plain-server2
[+] --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+] Endpoint: iinsecure.dev:37471 TLS: no ObjID: [55ff5a5d:17e0501b054:-7ff7, 3638117546492248534]
[+] - legacy-service
[+] --> de.qtc.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class)
[+] Endpoint: iinsecure.dev:37471 TLS: no ObjID: [55ff5a5d:17e0501b054:-7ffc, 708796783031663206]
[+] - plain-server
[+] --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+] Endpoint: iinsecure.dev:37471 TLS: no ObjID: [55ff5a5d:17e0501b054:-7ff8, -4004948013687638236]
[+]
[+] RMI server codebase enumeration:
[+]
[+] - http://iinsecure.dev/well-hidden-development-folder/
[+] --> de.qtc.rmg.server.legacy.LegacyServiceImpl_Stub
[+] --> de.qtc.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 enmeration:
[+]
[+] - 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
Η έξοδος της ενέργειας αρίθμησης εξηγείται πιο λεπτομερώς στις σελίδες τεκμηρίωσης του έργου. Ανάλογα με το αποτέλεσμα, θα πρέπει να προσπαθήσετε να επαληθεύσετε τις αναγνωρισμένες ευπάθειες.
Οι τιμές ObjID που εμφανίζονται από το remote-method-guesser μπορούν να χρησιμοποιηθούν για να προσδιορίσουν τον χρόνο λειτουργίας της υπηρεσίας. Αυτό μπορεί να επιτρέψει την αναγνώριση άλλων ευπαθειών:
Ακόμα και όταν δεν έχουν εντοπιστεί ευπάθειες κατά τη διάρκεια της αρίθμησης, οι διαθέσιμες RMI υπηρεσίες θα μπορούσαν να εκθέσουν επικίνδυνες λειτουργίες. Επιπλέον, παρά το γεγονός ότι η επικοινωνία RMI με τα προεπιλεγμένα συστατικά RMI προστατεύεται από φίλτρα απο-serialization, όταν μιλάμε με προσαρμοσμένες RMI υπηρεσίες, τέτοια φίλτρα συνήθως δεν υπάρχουν. Γνωρίζοντας έγκυρες υπογραφές μεθόδων στις RMI υπηρεσίες είναι επομένως πολύτιμο.
Δυστυχώς, το Java RMI δεν υποστηρίζει την αρίθμηση μεθόδων σε απομακρυσμένα αντικείμενα. Παρ' όλα αυτά, είναι δυνατόν να γίνει bruteforce υπογραφών μεθόδων με εργαλεία όπως το remote-method-guesser ή το rmiscout:
Εκτός από την εκτίμηση, θα πρέπει επίσης να αναζητήσετε σε μηχανές αναζήτησης ή GitHub για τη διεπαφή ή ακόμη και την υλοποίηση μιας συναντηθείσας RMI υπηρεσίας. Το bound name και το όνομα της υλοποιημένης κλάσης ή διεπαφής μπορεί να είναι χρήσιμα εδώ.
Γνωστές Διεπαφές
remote-method-guesser σημειώνει τις κλάσεις ή τις διεπαφές ως known αν είναι καταχωρημένες στη εσωτερική βάση δεδομένων του εργαλείου για γνωστές RMI services. Σε αυτές τις περιπτώσεις μπορείτε να χρησιμοποιήσετε την ενέργεια known για να αποκτήσετε περισσότερες πληροφορίες σχετικά με την αντίστοιχη RMI service:
$ rmg enum 172.17.0.2 1090 | head -n 5
[+] RMI registry bound names:
[+]
[+] - jmxrmi
[+] --> javax.management.remote.rmi.RMIServerImpl_Stub (known class: JMX Server)
[+] Endpoint: localhost:41695 TLS: no ObjID: [7e384a4f:17e0546f16f:-7ffe, -553451807350957585]
$ 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
Protocol_Name: Java RMI #Protocol Abbreviation if there is one.
Port_Number: 1090,1098,1099,1199,4443-4446,8999-9010,9999 #Comma separated if there is more than one.
Protocol_Description: Java Remote Method Invocation #Protocol Abbreviation Spelled out
Entry_1:
Name: Enumeration
Description: Perform basic enumeration of an RMI service
Command: rmg enum {IP} {PORT}
Χρησιμοποιήστε Trickest για να δημιουργήσετε και να αυτοματοποιήσετε ροές εργασίας που υποστηρίζονται από τα πιο προηγμένα εργαλεία της κοινότητας.
Αποκτήστε πρόσβαση σήμερα: