Verwenden Sie Trickest, um einfach Workflows zu erstellen und zu automatisieren, die von den fortschrittlichsten Community-Tools der Welt unterstützt werden.
Zugang heute erhalten:
Java Remote Method Invocation, oder Java RMI, ist ein objektorientierter RPC-Mechanismus, der es einem Objekt, das sich in einer Java-virtuellen Maschine befindet, ermöglicht, Methoden auf einem Objekt in einer anderen Java-virtuellen Maschine aufzurufen. Dies ermöglicht Entwicklern, verteilte Anwendungen unter Verwendung eines objektorientierten Paradigmas zu schreiben. Eine kurze Einführung in Java RMI aus einer offensiven Perspektive finden Sie in diesem Blackhat-Vortrag.
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
Üblicherweise sind nur die Standard-Java RMI-Komponenten (das RMI-Registry und das Activation System) an gängigen Ports gebunden. Die remote objects, die die tatsächliche RMI-Anwendung implementieren, sind normalerweise an zufällige Ports gebunden, wie im obigen Output gezeigt.
nmap hat manchmal Schwierigkeiten, SSL-geschützte RMI-Dienste zu identifizieren. Wenn Sie auf einen unbekannten SSL-Dienst an einem gängigen RMI-Port stoßen, sollten Sie weiter untersuchen.
RMI-Komponenten
Um es einfach auszudrücken, ermöglicht Java RMI einem Entwickler, ein Java-Objekt im Netzwerk verfügbar zu machen. Dies öffnet einen TCP-Port, über den Clients eine Verbindung herstellen und Methoden auf dem entsprechenden Objekt aufrufen können. Obwohl dies einfach klingt, gibt es mehrere Herausforderungen, die Java RMI lösen muss:
Um einen Methodenaufruf über Java RMI zu versenden, müssen die Clients die IP-Adresse, den lauschernden Port, die implementierte Klasse oder Schnittstelle und die ObjID des Zielobjekts kennen (die ObjID ist ein eindeutiger und zufälliger Identifikator, der erstellt wird, wenn das Objekt im Netzwerk verfügbar gemacht wird. Sie ist erforderlich, da Java RMI mehreren Objekten erlaubt, auf demselben TCP-Port zu lauschen).
Remote-Clients können Ressourcen auf dem Server zuweisen, indem sie Methoden auf dem exponierten Objekt aufrufen. Die Java Virtual Machine muss verfolgen, welche dieser Ressourcen noch verwendet werden und welche davon gesammelt werden können.
Die erste Herausforderung wird durch das RMI-Registry gelöst, das im Grunde ein Namensdienst für Java RMI ist. Das RMI-Registry selbst ist ebenfalls ein RMI-Dienst, aber die implementierte Schnittstelle und die ObjID sind fest und allen RMI-Clients bekannt. Dies ermöglicht es RMI-Clients, das RMI-Registry zu nutzen, indem sie nur den entsprechenden TCP-Port kennen.
Wenn Entwickler ihre Java-Objekte im Netzwerk verfügbar machen möchten, binden sie sie normalerweise an ein RMI-Registry. Das Registry speichert alle Informationen, die erforderlich sind, um eine Verbindung zum Objekt herzustellen (IP-Adresse, lauschernder Port, implementierte Klasse oder Schnittstelle und den ObjID-Wert) und macht sie unter einem menschenlesbaren Namen (dem gebundenen Namen) verfügbar. Clients, die den RMI-Dienst nutzen möchten, fragen das RMI-Registry nach dem entsprechenden gebundenen Namen, und das Registry gibt alle erforderlichen Informationen zur Verbindung zurück. Somit ist die Situation im Grunde die gleiche wie bei einem gewöhnlichen DNS-Dienst. Die folgende Auflistung zeigt ein kleines Beispiel:
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();}}}
Der zweite der oben genannten Herausforderungen wird durch den Distributed Garbage Collector (DGC) gelöst. Dies ist ein weiterer RMI-Dienst mit einem bekannten ObjID-Wert und er ist im Grunde an jedem RMI-Endpunkt verfügbar. Wenn ein RMI-Client beginnt, einen RMI-Dienst zu nutzen, sendet er eine Information an den DGC, dass das entsprechende remote object in Gebrauch ist. Der DGC kann dann die Referenzanzahl verfolgen und ist in der Lage, ungenutzte Objekte zu bereinigen.
Zusammen mit dem veralteten Activation System sind dies die drei Standardkomponenten von Java RMI:
Das RMI Registry (ObjID = 0)
Das Activation System (ObjID = 1)
Der Distributed Garbage Collector (ObjID = 2)
Die Standardkomponenten von Java RMI sind seit einiger Zeit bekannte Angriffsvektoren und mehrere Schwachstellen existieren in veralteten Java-Versionen. Aus der Perspektive eines Angreifers sind diese Standardkomponenten interessant, da sie bekannte Klassen / Schnittstellen implementiert haben und es leicht möglich ist, mit ihnen zu interagieren. Diese Situation ist anders bei benutzerdefinierten RMI-Diensten. Um eine Methode auf einem remote object aufzurufen, müssen Sie die entsprechende Methodensignatur im Voraus kennen. Ohne Kenntnis einer vorhandenen Methodensignatur gibt es keine Möglichkeit, mit einem RMI-Dienst zu kommunizieren.
RMI Enumeration
remote-method-guesser ist ein Java RMI-Schwachstellenscanner, der in der Lage ist, gängige RMI-Schwachstellen automatisch zu identifizieren. Wann immer Sie einen RMI-Endpunkt identifizieren, sollten Sie es versuchen:
$ 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
Die Ausgabe der Enumerationsaktion wird in den Dokumentationsseiten des Projekts näher erläutert. Je nach Ergebnis sollten Sie versuchen, identifizierte Schwachstellen zu überprüfen.
Die von remote-method-guesser angezeigten ObjID-Werte können verwendet werden, um die Betriebszeit des Dienstes zu bestimmen. Dies kann helfen, andere Schwachstellen zu identifizieren:
Selbst wenn während der Enumeration keine Schwachstellen identifiziert wurden, könnten die verfügbaren RMI Dienste dennoch gefährliche Funktionen offenbaren. Darüber hinaus ist die RMI Kommunikation zu RMI Standardkomponenten zwar durch Deserialisierungsfilter geschützt, jedoch sind solche Filter bei der Kommunikation mit benutzerdefinierten RMI Diensten normalerweise nicht vorhanden. Daher ist es wertvoll, gültige Methodensignaturen für RMI Dienste zu kennen.
Leider unterstützt Java RMI nicht die Enumeration von Methoden auf remote objects. Das gesagt, ist es möglich, Methodensignaturen mit Tools wie remote-method-guesser oder rmiscout zu bruteforcen:
Neben dem Raten sollten Sie auch in Suchmaschinen oder GitHub nach der Schnittstelle oder sogar der Implementierung eines gefundenen RMI Dienstes suchen. Der gebundene Name und der Name der implementierten Klasse oder Schnittstelle können hier hilfreich sein.
Bekannte Schnittstellen
remote-method-guesser kennzeichnet Klassen oder Schnittstellen als known, wenn sie in der internen Datenbank des Tools für bekannte RMI services aufgeführt sind. In diesen Fällen können Sie die known-Aktion verwenden, um weitere Informationen über den entsprechenden RMI service zu erhalten:
$ 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}
Verwenden Sie Trickest, um einfach Workflows zu erstellen und zu automatisieren, die von den fortschrittlichsten Community-Tools der Welt unterstützt werden.
Zugang heute erhalten: