Java Uzak Yöntem Çağrısı, veya Java RMI, bir Java sanal makinesi içinde bulunan bir nesnenin, başka bir Java sanal makinesi içinde bulunan bir nesne üzerindeki yöntemleri çağırmasına olanak tanıyan nesne yönelimli bir RPC mekanizmasıdır. Bu, geliştiricilerin nesne yönelimli bir paradigma kullanarak dağıtık uygulamalar yazmalarını sağlar. Saldırgan bir perspektiften Java RMI hakkında kısa bir tanıtım bu blackhat konuşmasında bulunabilir.
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) yaygın portlara bağlanır. Gerçek RMI uygulamasını uygulayan uzaktan nesneler genellikle yukarıdaki çıktıda gösterildiği gibi rastgele portlara bağlanır.
nmap, bazen SSL korumalı RMI hizmetlerini tanımlamakta zorluklar yaşayabilir. Yaygın bir RMI portunda bilinmeyen bir ssl hizmeti ile 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 ilgili nesne üzerinde yöntemleri çağırabileceği bir TCP portu açar. Bu basit görünse de, Java RMI'nin çözmesi gereken birkaç zorluk vardır:
Java RMI üzerinden bir yöntem çağrısını iletmek için, istemcilerin hedef nesnenin IP adresini, dinleme portunu, uygulanan sınıfı veya arayüzü ve ObjID'sini bilmesi gerekir ( ObjID, nesne ağda kullanılabilir hale getirildiğinde oluşturulan benzersiz ve rastgele bir tanımlayıcıdır. Java RMI, birden fazla nesnenin aynı TCP portunda dinlemesine izin verdiği için gereklidir).
Uzaktan istemciler, maruz bırakılan nesne üzerinde yöntemleri çağırarak sunucuda kaynak tahsis edebilir. Java sanal makinesi, bu kaynaklardan hangilerinin hala kullanıldığını ve hangilerinin çöp toplanabileceğini takip etmelidir.
İlk zorluk, temelde Java RMI için bir adlandırma hizmeti olan RMI registry tarafından çözülür. RMI registry kendisi de bir _RMI hizmeti_dir, ancak uygulanan arayüz ve ObjID sabittir ve tüm RMI istemcileri tarafından bilinir. Bu, RMI istemcilerinin yalnızca ilgili TCP portunu bilerek RMI kaydını tüketmelerine olanak tanır.
Geliştiriciler, Java nesnelerini ağ içinde kullanılabilir hale getirmek istediklerinde, genellikle bunları bir RMI registry ile bağlarlar. Registry, nesneye bağlanmak için gereken tüm bilgileri (IP adresi, dinleme portu, uygulanan sınıf veya arayüz ve ObjID değeri) depolar ve bunu insan tarafından okunabilir bir ad altında (bağlı ad) kullanılabilir hale getirir. RMI hizmetini tüketmek isteyen istemciler, ilgili bağlı adı almak için RMI registry ile iletişime geçer ve registry, bağlanmak için gereken tüm bilgileri döner. Böylece, durum temelde sıradan bir DNS hizmeti ile aynıdır. Aşağıdaki liste küçük bir örnek göstermektedir:
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();}}}
Yukarıda bahsedilen ikinci zorluk, Dağıtılmış Çöp Toplayıcı (DGC) tarafından çözülmektedir. Bu, iyi bilinen bir ObjID değerine sahip başka bir _RMI servisi_dir ve temelde her RMI uç noktasında mevcuttur. Bir RMI istemcisi bir RMI servisini kullanmaya başladığında, ilgili _uzaktan nesne_nin kullanıldığını DGC'ye bildirir. DGC daha sonra referans sayısını takip edebilir ve kullanılmayan nesneleri temizleyebilir.
Eski Aktivasyon Sistemi ile birlikte, bunlar Java RMI'nin üç varsayılan bileşenidir:
RMI Kaydı (ObjID = 0)
Aktivasyon Sistemi (ObjID = 1)
Dağıtılmış Çöp Toplayıcı (ObjID = 2)
Varsayılan bileşenlerJava RMI'nin bilinen saldırı vektörleri olmuştur ve eski Java sürümlerinde birden fazla güvenlik açığı bulunmaktadır. Bir saldırgan perspektifinden, bu varsayılan bileşenler ilginçtir çünkü bilinen sınıfları / arayüzleri uygulamışlardır ve onlarla etkileşimde bulunmak oldukça kolaydır. Bu durum, özel RMI servisleri için farklıdır. Bir uzaktan nesne üzerinde bir yöntemi çağırmak için, ilgili yöntem imzasını önceden bilmeniz gerekir. Mevcut bir yöntem imzasını bilmeden, bir RMI servisi ile iletişim kurmanın bir yolu yoktur.
RMI Enumeration
remote-method-guesser , yaygın RMI güvenlik açıklarını otomatik olarak tanımlama yeteneğine sahip bir Java RMI güvenlik açığı 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 ayrıntılı olarak açıklanmıştır. Sonuca bağlı olarak, tespit edilen zafiyetleri doğrulamaya çalışmalısınız.
remote-method-guesser tarafından görüntülenen ObjID değerleri, hizmetin çalışma süresini belirlemek için kullanılabilir. Bu, diğer zafiyetleri tanımlamayı mümkün kılabilir:
Enumeration sırasında hiçbir zayıflık tespit edilmemiş olsa bile, mevcut RMI hizmetleri hala tehlikeli işlevler açığa çıkarabilir. Dahası, RMI iletişimi RMI varsayılan bileşenlerine karşı deserialization filtreleriyle korunmasına rağmen, özel RMI hizmetleriyle konuşurken bu filtreler genellikle mevcut değildir. Bu nedenle, RMI hizmetlerindeki geçerli yöntem imzalarını bilmek değerlidir.
Ne yazık ki, Java RMI uzak nesnelerdeki yöntemleri listelemeyi desteklememektedir. Bununla birlikte, remote-method-guesser veya rmiscout gibi araçlarla yöntem imzalarını bruteforce etmek mümkündür:
Tahmin etmenin yanı sıra, karşılaşılan RMI hizmetinin arayüzü veya hatta uygulaması için arama motorlarında veya GitHub üzerinde de arama yapmalısınız. Bağlı ad ve uygulanan sınıf veya arayüzün adı burada yardımcı olabilir.
Bilinen Arayüzler
remote-method-guesser sınıfları veya arayüzleri, eğer araçtaki bilinen RMI hizmetleri iç veritabanında listelenmişse known olarak işaretler. Bu durumlarda, ilgili RMI hizmeti 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
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}
Dünyanın en gelişmiş topluluk araçlarıyla desteklenen iş akışlarını kolayca oluşturmak ve otomatikleştirmek için Trickest kullanın.
Bugün Erişim Alın: