mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/deserialization/basic-java-deserializati
This commit is contained in:
parent
62e8a00d2a
commit
664abe6dbe
@ -1,15 +1,27 @@
|
||||
# Basic Java Deserialization with ObjectInputStream readObject
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Bu POST'ta `java.io.Serializable` kullanarak bir örnek açıklanacaktır.
|
||||
Bu POST'ta `java.io.Serializable` kullanarak bir örnek açıklanacak **ve neden `readObject()`'in geçerli bir akış saldırgan kontrolündeyse son derece tehlikeli olabileceği** anlatılacak.
|
||||
|
||||
# Serializable
|
||||
## Serializable
|
||||
|
||||
Java `Serializable` arayüzü (`java.io.Serializable`, sınıflarınızın **serileştirilmesi** ve **deserileştirilmesi** için uygulaması gereken bir işaretçi arayüzüdür. Java nesne serileştirmesi (yazma) [ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html) ile yapılır ve deserileştirme (okuma) [ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html) ile yapılır.
|
||||
Java `Serializable` arayüzü (`java.io.Serializable`), sınıflarınızın **serileştirilmesi** ve **serileştirilmesinin geri alınması** için uygulaması gereken bir işaretçi arayüzüdür. Java nesne serileştirmesi (yazma) [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) ile yapılır ve serileştirilmenin geri alınması (okuma) [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html) ile yapılır.
|
||||
|
||||
**Serileştirilebilir** bir **Person sınıfı** ile bir örneğe bakalım. Bu sınıf **readObject** fonksiyonunu **geçersiz kılar**, böylece bu **sınıfın** **herhangi bir nesnesi** **deserileştirildiğinde** bu **fonksiyon** **çalıştırılacaktır**.\
|
||||
Örnekte, Person sınıfının **readObject fonksiyonu**, evcil hayvanının `eat()` fonksiyonunu çağırır ve bir Köpek için `eat()` fonksiyonu (bir sebepten dolayı) bir **calc.exe** çağırır. **Bu hesap makinesini çalıştırmak için bir Person nesnesini nasıl serileştireceğimizi ve deserileştireceğimizi göreceğiz:**
|
||||
### Hatırlatma: Serileştirilmenin geri alınması sırasında hangi yöntemler örtük olarak çağrılır?
|
||||
|
||||
**Aşağıdaki örnek [https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649) adresinden alınmıştır.**
|
||||
1. `readObject()` – sınıfa özgü okuma mantığı (eğer uygulanmışsa ve *özel* ise).
|
||||
2. `readResolve()` – serileştirilen nesneyi başka bir nesne ile değiştirebilir.
|
||||
3. `validateObject()` – `ObjectInputValidation` geri çağırmaları aracılığıyla.
|
||||
4. `readExternal()` – `Externalizable` uygulayan sınıflar için.
|
||||
5. Yapıcılar **çalıştırılmaz** – bu nedenle gadget zincirleri yalnızca önceki geri çağırmalara dayanır.
|
||||
|
||||
O zincirdeki herhangi bir yöntem, saldırgan kontrolündeki verileri (komut yürütme, JNDI aramaları, yansıma vb.) çağırırsa, serileştirme rutini bir RCE gadget'ına dönüşür.
|
||||
|
||||
**Serileştirilebilir** olan bir **Person** sınıfı ile bir örneğe bakalım. Bu sınıf **readObject** fonksiyonunu **geçersiz kılar**, bu nedenle bu **sınıfın** **herhangi bir nesnesi** **serileştirildiğinde** bu **fonksiyon** **çalıştırılacaktır**.\
|
||||
Örnekte, Person sınıfının **readObject** fonksiyonu, evcil hayvanının `eat()` fonksiyonunu çağırır ve bir Köpek'in `eat()` fonksiyonu (bir sebepten dolayı) **calc.exe**'yi çağırır. **Bu hesap makinesini çalıştırmak için bir Person nesnesini nasıl serileştirip serileştireceğimizi göreceğiz:**
|
||||
|
||||
**Aşağıdaki örnek <https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649> adresinden alınmıştır.**
|
||||
```java
|
||||
import java.io.Serializable;
|
||||
import java.io.*;
|
||||
@ -80,8 +92,63 @@ payloadTest("test.ser");
|
||||
}
|
||||
}
|
||||
```
|
||||
## Sonuç
|
||||
### Sonuç (klasik senaryo)
|
||||
|
||||
Bu çok temel örnekte görebileceğiniz gibi, buradaki "açıklık" **readObject** fonksiyonu **diğer savunmasız fonksiyonları çağırdığı** için ortaya çıkmaktadır.
|
||||
Bu çok temel örnekte görüldüğü gibi, buradaki “zayıflık” **readObject()** metodunun **başka bir saldırgan kontrolündeki kodu çağırmasından** kaynaklanmaktadır. Gerçek dünyadaki gadget zincirlerinde, dış kütüphanelerde (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, vb.) bulunan binlerce sınıf kötüye kullanılabilir – saldırganın yalnızca *bir* erişilebilir gadget'a ihtiyacı vardır.
|
||||
|
||||
---
|
||||
|
||||
## 2023-2025: Java deserialization saldırılarında neler yeni?
|
||||
|
||||
* 2023 – CVE-2023-34040: `checkDeserExWhen*` bayrakları etkinleştirildiğinde Spring-Kafka hata kayıt başlıklarının deserialization'ı, saldırgan tarafından yayımlanan konulardan keyfi gadget inşasına izin verdi. 3.0.10 / 2.9.11'de düzeltildi. ¹
|
||||
* 2023 – CVE-2023-36480: Aerospike Java istemcisi güvenilir sunucu varsayımı kırıldı – kötü niyetli sunucu yanıtları, istemci tarafından deserialized edilen serileştirilmiş yükler içeriyordu → RCE. ²
|
||||
* 2023 – CVE-2023-25581: `pac4j-core` kullanıcı profili öznitelik ayrıştırması `{#sb64}` ile başlayan Base64 blob'larını kabul etti ve `RestrictedObjectInputStream` olmasına rağmen bunları deserialized etti. 4.0.0 veya üstü sürüme yükseltin.
|
||||
* 2023 – CVE-2023-4528: JSCAPE MFT Manager Service (port 10880) XML kodlu Java nesnelerini kabul etti ve bu da root/SYSTEM olarak RCE'ye yol açtı.
|
||||
* 2024 – Bazı eski filtreleri atlayan Hibernate5, TomcatEmbed ve SnakeYAML 2.x sınıflarını içeren yeni gadget zincirleri ysoserial-plus(mod) ile eklendi.
|
||||
|
||||
## Uygulamanız gereken modern önlemler
|
||||
|
||||
1. **JEP 290 / Serileştirme Filtreleme (Java 9+)**
|
||||
*Sınıfların bir izin listesi veya yasak listesi ekleyin:*
|
||||
```bash
|
||||
# Sadece DTO'larınızı ve java.base'ı kabul edin, diğer her şeyi reddedin
|
||||
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"
|
||||
```
|
||||
Programatik örnek:
|
||||
```java
|
||||
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
2. **JEP 415 (Java 17+) Bağlama Özel Filtre Fabrikaları** – her yürütme bağlamı için (örneğin, her RMI çağrısı, her mesaj kuyruğu tüketicisi) farklı filtreler uygulamak için bir `BinaryOperator<ObjectInputFilter>` kullanın.
|
||||
3. **Ham `ObjectInputStream`'i ağda açığa çıkarmayın** – kod yürütme anlamı taşımayan JSON/Binary kodlamalarını tercih edin (Jackson `DefaultTyping` devre dışı bırakıldıktan sonra, Protobuf, Avro, vb.).
|
||||
4. **Derinlikte Savunma sınırları** – maksimum dizi uzunluğu, derinlik, referanslar ayarlayın:
|
||||
```bash
|
||||
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
|
||||
```
|
||||
5. **Sürekli gadget taraması** – tehlikeli bir gadget erişilebilir hale gelirse inşaatı başarısız kılmak için CI'nizde `gadget-inspector` veya `serialpwn-cli` gibi araçları çalıştırın.
|
||||
|
||||
## Güncellenmiş araçlar kılavuzu (2024)
|
||||
|
||||
* `ysoserial-plus.jar` – > 130 gadget zinciri içeren topluluk çatallaması:
|
||||
```bash
|
||||
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
|
||||
```
|
||||
* `marshalsec` – JNDI gadget üretimi için hala referans.
|
||||
* `gadget-probe` – ağ hizmetlerine karşı hızlı siyah kutu gadget keşfi.
|
||||
* `SerialSniffer` – `ObjectInputStream` tarafından okunan her sınıfı yazdıran JVMTI ajanı (filtreleri oluşturmak için yararlıdır).
|
||||
* **Tespit ipucu** – filtre kararlarını ve reddedilen sınıfları günlüğe kaydetmek için `-Djdk.serialDebug=true` (JDK 22+) etkinleştirin.
|
||||
|
||||
## Güvenli `readObject()` uygulamaları için hızlı kontrol listesi
|
||||
|
||||
1. Metodu `private` yapın ve `@Serial` anotasyonunu ekleyin (statik analize yardımcı olur).
|
||||
2. Kullanıcı tarafından sağlanan metodları asla çağırmayın veya metod içinde I/O gerçekleştirmeyin – yalnızca alanları okuyun.
|
||||
3. Doğrulama gerekiyorsa, bunu deserialization'dan **sonra**, `readObject()` dışında gerçekleştirin.
|
||||
4. Varsayılan serileştirme yerine `Externalizable` uygulamayı tercih edin ve açık alan okumaları yapın.
|
||||
5. İç hizmetler için bile sertleştirilmiş bir `ObjectInputFilter` kaydedin (uzlaşma dayanıklı tasarım).
|
||||
|
||||
## Referanslar
|
||||
|
||||
1. Spring Security Advisory – CVE-2023-34040 Java Deserialization in Spring-Kafka (Ağu 2023)
|
||||
2. GitHub Security Lab – GHSL-2023-044: Unsafe Deserialization in Aerospike Java Client (Tem 2023)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user