Java Remote Method Invocation, or Java RMI, je mehanizam RPC orijentisan na objekte koji omogućava objektu smeštenom u jednoj Java virtuelnoj mašini da poziva metode na objektu smeštenom u drugoj Java virtuelnoj mašini. Ovo omogućava programerima da pišu distribuirane aplikacije koristeći objektno-orijentisani paradigm. Kratak uvod u Java RMI iz ofanzivne perspektive može se naći u ovom blackhat predavanju.
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
Obično su samo podrazumevani Java RMI komponenti (RMI Registry i Activation System) vezani za uobičajene portove. Remote objects koji implementiraju stvarnu RMI aplikaciju obično su vezani za nasumične portove kao što je prikazano u gornjem izlazu.
nmap ponekad ima problema sa identifikovanjem SSL zaštićenih RMI usluga. Ako naiđete na nepoznatu ssl uslugu na uobičajenom RMI portu, trebali biste dalje istražiti.
RMI Komponente
Da to pojednostavimo, Java RMI omogućava programeru da učini Java objekat dostupnim na mreži. Ovo otvara TCP port na kojem se klijenti mogu povezati i pozvati metode na odgovarajućem objektu. Iako ovo zvuči jednostavno, postoji nekoliko izazova koje Java RMI treba da reši:
Da bi poslali poziv metode putem Java RMI, klijenti treba da znaju IP adresu, slušajući port, implementiranu klasu ili interfejs i ObjID ciljanog objekta ( ObjID je jedinstveni i nasumični identifikator koji se kreira kada objekat postane dostupan na mreži. Potreban je jer Java RMI omogućava više objekata da slušaju na istom TCP portu).
Daljinski klijenti mogu alocirati resurse na serveru pozivajući metode na izloženom objektu. Java virtuelna mašina treba da prati koji od ovih resursa su još u upotrebi i koji od njih mogu biti prikupljeni kao smeće.
Prvi izazov rešava RMI registry, koji je u suštini servis za imenovanje za Java RMI. RMI registry sam po sebi je takođe RMI service, ali su implementirani interfejs i ObjID fiksni i poznati svim RMI klijentima. Ovo omogućava RMI klijentima da koriste RMI registry samo znajući odgovarajući TCP port.
Kada programeri žele da učine svoje Java objekte dostupnim unutar mreže, obično ih vezuju za RMI registry. Registry čuva sve informacije potrebne za povezivanje sa objektom (IP adresa, slušajući port, implementirana klasa ili interfejs i ObjID vrednost) i čini ih dostupnim pod ljudski čitljivim imenom ( bound name). Klijenti koji žele da koriste RMI service traže od RMI registry odgovarajuće bound name i registry vraća sve potrebne informacije za povezivanje. Tako je situacija u suštini ista kao sa običnom DNS uslugom. Sledeći spisak prikazuje mali primer:
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();}}}
Drugi od gore pomenutih izazova rešava Distributed Garbage Collector (DGC). Ovo je još jedna RMI usluga sa poznatom ObjID vrednošću i dostupna je na praktično svakoj RMI tački. Kada RMI klijent počne da koristi RMI uslugu, šalje informaciju DGC-u da je odgovarajući daleki objekat u upotrebi. DGC može pratiti broj referenci i sposobna je da očisti neiskorišćene objekte.
Zajedno sa zastarelim Activation System, ovo su tri podrazumevana komponenta Java RMI:
RMI Registry (ObjID = 0)
Activation System (ObjID = 1)
Distributed Garbage Collector (ObjID = 2)
Podrazumevane komponente Java RMI su poznati vektori napada već neko vreme i više ranjivosti postoje u zastarelim verzijama Java. Sa stanovišta napadača, ove podrazumevane komponente su zanimljive, jer implementiraju poznate klase / interfejse i lako je moguće interagovati sa njima. Ova situacija je drugačija za prilagođene RMI usluge. Da biste pozvali metodu na dalekom objektu, morate unapred znati odgovarajući potpis metode. Bez poznavanja postojećeg potpisa metode, ne postoji način da se komunicira sa RMI uslugom.
RMI Enumeration
remote-method-guesser je Java RMI skener ranjivosti koji je sposoban da automatski identifikuje uobičajene RMI ranjivosti. Kada god identifikujete RMI tačku, trebali biste to isprobati:
$ 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
Izlaz akcije enumeracije je objašnjen detaljnije na stranicama dokumentacije projekta. U zavisnosti od ishoda, trebali biste pokušati da verifikujete identifikovane ranjivosti.
Vrednosti ObjID koje prikazuje remote-method-guesser mogu se koristiti za određivanje vremena rada usluge. Ovo može omogućiti identifikaciju drugih ranjivosti:
Čak i kada nisu identifikovane ranjivosti tokom enumeracije, dostupne RMI usluge mogu i dalje izložiti opasne funkcije. Štaviše, iako je RMI komunikacija sa RMI podrazumevanim komponentama zaštićena filtrima za deserializaciju, kada se razgovara sa prilagođenim RMI uslugama, takvi filteri obično nisu prisutni. Poznavanje validnih potpisa metoda na RMI uslugama je stoga dragoceno.
Nažalost, Java RMI ne podržava enumeraciju metoda na daljinskim objektima. Ipak, moguće je bruteforcovati potpise metoda pomoću alata kao što su remote-method-guesser ili rmiscout:
Osim pogađanja, trebali biste takođe potražiti u pretraživačima ili GitHub-u za interfejs ili čak implementaciju susretnutog RMI servisa. Bound name i naziv implementirane klase ili interfejsa mogu biti od pomoći ovde.
Poznati interfejsi
remote-method-guesser označava klase ili interfejse kao poznate ako su navedene u internom bazi podataka alata o poznatim RMI uslugama. U tim slučajevima možete koristiti poznatu akciju da dobijete više informacija o odgovarajućoj RMI usluzi:
$ 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}
Koristite Trickest da lako izgradite i automatizujete radne tokove pokretane od strane najnaprednijih alata zajednice.
Pribavite pristup danas: