Bölüm 11
Unsafe Deserialization & PHP Object Injection
Bölüm 1 (tehlikeli fonksiyonlar, ikinci derece açıklar), Bölüm 8/9 (RCE kavramı).
Güvensiz deserializasyonu, "veriyi geri yükleme"nin masum görünen ama en tehlikeli PHP açıklarından birine dönüşmesi olarak kavrayacak; unserialize'ın neden yalnızca veri değil nesne ürettiğini, magic method'ların bu nesneleri nasıl otomatik "canlandırdığını" ve gadget/POP zincirlerinin nasıl kod çalıştırmadan mevcut kodu silah olarak kullandığını göreceksiniz.
1. Giriş
Deserializasyon açıkları, bu kitaptaki en "kavramsal olarak zarif" ve aynı ölçüde tehlikeli sınıftır. Diğer enjeksiyonların çoğunda saldırgan bir dizeye kötü niyetli içerik enjekte eder. Object injection'da ise saldırgan hiç yeni kod enjekte etmez; bunun yerine uygulamada zaten var olan sınıfları ve metotları bir zincirde birleştirerek istenmeyen bir sonuç üretir. Bu, ikili sömürüdeki ROP (Return-Oriented Programming) tekniğinin nesne yönelimli karşılığıdır ve bu yüzden "POP — Property-Oriented Programming" adını alır.
PHP, bu açık sınıfına özellikle yatkındır çünkü iki özelliği birleştirir: unserialize() fonksiyonu, bir dizeden rastgele sınıflardan nesneler üretebilir; ve magic method'lar (__wakeup, __destruct, __toString gibi) bu nesneler oluşturulurken veya yok edilirken otomatik çalışır. Bu ikisi bir araya geldiğinde, güvenilmeyen bir dizeyi unserialize'a vermek, saldırganın belirlediği nesneleri canlandırıp onların otomatik metotlarını tetikler.
Bu bölüm enjeksiyon ailesini (Kısım II) kapatır ve önceki tüm bölümlerin ortak dersini doruğa taşır: güvenilmeyen veriyi, onu "yorumlayan" güçlü bir mekanizmaya vermek felakettir — burada mekanizma PHP'nin nesne canlandırma motorudur.
2. Temel Teori
Serializasyon nedir? PHP nesnelerini/dizilerini saklanabilir/iletilebilir bir dizeye çevirmek serialize(), geri çevirmek unserialize() ile yapılır. Serileştirilmiş bir nesne, sınıf adını, özellik adlarını ve değerlerini metin olarak kodlar:
O:4:"User":2:{s:4:"name";s:3:"ali";s:5:"admin";b:0;}
│ │ │ └ özellik sayısı ve içerikleri
│ │ └ sınıf adı uzunluğu/adı
└ "Object", tür işareti
Neden tehlikeli? unserialize($data) çalıştığında PHP, $data içinde belirtilen sınıftan bir nesne oluşturur ve özelliklerini $data'daki değerlerle doldurur. Kritik nokta: saldırgan $data'yı kontrol ediyorsa, hangi sınıftan nesne üretileceğini ve o nesnenin hangi özelliklere sahip olacağını da kontrol eder. Bu tek başına bir bilgi değil, bir yetenektir.
Magic method'lar — otomatik tetikleyiciler. PHP sınıfları, belirli olaylarda otomatik çağrılan özel metotlar tanımlayabilir:
| Magic method | Ne zaman çalışır |
|---|---|
__wakeup() |
unserialize sırasında, nesne canlandırılırken |
__destruct() |
Nesne yok edilirken (script sonunda dahi) |
__toString() |
Nesne dizeye çevrilirken (echo, birleştirme) |
__call() / __get() |
Tanımsız metot/özellik erişiminde |
Saldırgan bir nesneyi unserialize ettirdiğinde, o nesnenin __wakeup/__destruct'ı otomatik çalışır — saldırgan bir metot çağırmasa bile. İşte kök neden: saldırgan, hangi sınıfın magic method'unun, hangi özellik değerleriyle çalışacağını seçebilir.
Gadget / POP zinciri. Tek bir magic method genelde doğrudan zarar vermez. Ama bir magic method, sahip olduğu bir özelliğin başka bir metodunu çağırıyorsa, saldırgan o özelliğe başka bir nesne koyabilir; onun magic method'u da başka bir çağrı yapar... Bu zincir, sonunda tehlikeli bir "sink"e (dosya yazma, eval, komut çalıştırma, SQL) ulaşır. Bu birbirine bağlı sınıf parçalarına gadget, zincire POP zinciri denir. Zincir tamamen mevcut kodu kullanır; yeni kod enjekte edilmez.
Araç bağlamı. Güvenlik araştırmacıları, popüler framework'ler için hazır gadget zincirlerini PHPGGC gibi araçlarda toplar. Bu, savunmacı için önemli bir sinyaldir: kullandığınız framework için bilinen gadget zincirleri mevcutsa, unserialize'a ulaşan her güvenilmeyen veri anında sömürülebilir demektir.
phar:// vektörü. Sinsi bir varyant: bir Phar arşivinin meta verisi serileştirilmiş PHP nesnesi içerir. file_exists, is_file, fopen gibi dosya fonksiyonları bir phar:// yoluna uygulandığında, PHP eski sürümlerde meta veriyi otomatik unserialize ederdi. Yani görünürde hiç unserialize() çağrısı olmadan object injection tetiklenebilirdi (PHP 8'de bu davranış sıkılaştırıldı ama dikkat gerektirir).
3. Mimarisel Bakış
GÜVENSİZ (güvenilmeyen veri unserialize ediliyor):
Saldırgan → serileştirilmiş kötü nesne (başlık/cookie/DB)
↓ ╳ güven sınırı
unserialize($data)
↓
PHP: saldırganın seçtiği SINIFTAN nesne oluşturur + özellikleri doldurur
↓
__wakeup / __destruct OTOMATİK çalışır
↓ (POP zinciri)
Gadget A.__destruct → B.__toString → C.write() ... → SINK
↓
Dosya yazma / komut / eval → RCE
GÜVENLİ (JSON / allowed_classes):
Saldırgan → JSON veya serileştirilmiş dize
↓
json_decode($data) → yalnızca dizi/stdClass, NESNE CANLANDIRMA YOK
veya unserialize($data, ['allowed_classes' => false])
↓
Hiçbir kullanıcı sınıfı örneklenmez → magic method tetiklenmez → zincir yok
Öğretici gözlem: güven sınırı unserialize'ın kendisindedir. unserialize, güvenilmeyen veriyle asla buluşmamalıdır — çünkü onun işi, veriyi çalıştırılabilir nesne grafiğine çevirmektir.
4. Güvensiz Kod
Gerçekçi bir "kullanıcı tercihlerini cookie'de saklama" ve "önbellek" özelliği:
<?php
// ⚠️ GÜVENSİZ — güvenilmeyen veri unserialize ediliyor
declare(strict_types=1);
// 1) Cookie'den kullanıcı tercihleri (saldırgan cookie'yi tümüyle kontrol eder)
$prefs = unserialize($_COOKIE['prefs'] ?? ''); // klasik object injection
applyTheme($prefs->theme ?? 'light');
// 2) İkinci derece: DB'den okunan "session/meta" verisi
$row = $pdo->query("SELECT data FROM sessions WHERE id = ...")->fetch();
$session = unserialize($row['data']); // veri daha önce kullanıcıdan gelmişse
// 3) phar:// vektörü — görünürde unserialize YOK ama tetiklenebilir
$uploaded = $_GET['file']; // "phar://..." olabilir
if (file_exists($uploaded)) { // dosya fonksiyonu phar meta'yı çözebilir
echo "Dosya mevcut";
}
5. Açığın Analizi
unserialize($_COOKIE['prefs']) — Ders kitabı object injection. Cookie tamamen istemci kontrolündedir (Bölüm 1); saldırgan buraya istediği serileştirilmiş nesneyi koyar. unserialize, o sınıftan bir nesne canlandırır ve __wakeup/__destruct'ını çalıştırır. Uygulamada (veya bağımlılıklarında) uygun bir gadget zinciri varsa, sonuç RCE'dir. Geliştiricinin niyeti "bir tercih dizisi okumak"tı, ama unserialize yalnızca dizi değil nesne de üretebilir.
unserialize($row['data']) (ikinci derece) — Daha sinsi. Veri bir veritabanından okunuyor, dolayısıyla "içeriden, güvenilir" sanılıyor. Ama o veri oraya daha önce bir kullanıcı tarafından (örneğin bir başlık, form ya da session üzerinden) yazıldıysa, güvenilmezdir (Bölüm 1, ikinci derece açıklar). Joomla CVE-2015-8562 (Bölüm 11) tam olarak budur: kullanıcı başlığı DB session'ına depolanır, sonra okunup unserialize edilir.
file_exists($_GET['file']) (phar) — En sinsi vektör. Kodda hiç unserialize() görünmez; ama $_GET['file'] bir phar:// yolu olabilir ve dosya fonksiyonu, arşiv meta verisini (serileştirilmiş nesne) çözebilir. Object injection, "unserialize aramak"la yakalanamayabilir; dosya fonksiyonlarına ulaşan güvenilmeyen yollar da risktir.
Ortak kök: Üçünde de saldırgan-kontrollü veri, PHP'nin nesne canlandırma motoruna ulaşıyor. Sorun verinin içeriğinde değil, unserialize'ın ona uygulanmasındadır.
6. Hacker Bakış Açısı
Saldırgan object injection'ı nasıl arar?
unserialize'a ulaşan girdiyi arar. Cookie'ler, gizli form alanları, HTTP başlıkları, session verisi, önbellek dosyaları, kuyruk mesajları — serileştirilmiş veri taşıyabilecek her yer. Serileştirilmiş PHP'nin karakteristik biçimi (O:, a:, s: önekleri) bir imzadır; saldırgan yanıtlarda/cookie'lerde bu biçimi görürse unserialize kullanıldığını tahmin eder.
Framework'ü ve sürümü belirler. Object injection'ın sömürülebilirliği, ortamda uygun bir gadget zincirinin varlığına bağlıdır. Saldırgan hangi framework/kütüphanelerin (Laravel, Symfony, Guzzle, Monolog, Doctrine...) yüklü olduğunu belirler ve o bileşenler için bilinen POP zincirleri olup olmadığına bakar (PHPGGC kapsamı bir yol gösterici).
Tetikleyiciyi test eder. Bir magic method'un çalışıp çalışmadığını doğrulamak için, gözlemlenebilir bir yan etki (bir hata, bir zamanlama farkı, bir OOB istek) üreten iyi bilinen bir zincir dener. Görünür çıktı yoksa, kör object injection için OOB tekniklere geçer.
phar'ı düşünür. Doğrudan unserialize bulamazsa, dosya adı/yol alan fonksiyonlara phar:// enjekte edip meta veri deserializasyonunu tetiklemeyi dener — özellikle dosya yükleme özellikleriyle birleştirerek (kendi phar'ını yükleyip sonra ona bir dosya fonksiyonu tetikleterek).
Savunmacı dersi: Object injection'ın sömürülebilirliği "sizin kodunuz + tüm bağımlılıklarınızdaki gadget'lar" toplamına bağlıdır. Kendi kodunuzda tehlikeli bir sink olmasa bile, bir bağımlılık zinciri onu sağlayabilir. Bu yüzden tek gerçek savunma, güvenilmeyen veriyi unserialize'a hiç vermemektir.
7. Exploit Mantığı
Bu bölüm çalıştırılabilir gadget zincirleri içermez. Object injection'ın neden bu kadar güçlü olduğu kavramsaldır:
- Kod enjeksiyonu değil, kod yeniden kullanımı. Saldırgan yeni PHP yazmaz; mevcut sınıfların magic method'larını, kendi seçtiği özellik değerleriyle bir zincirde birleştirir. Bu yüzden "sadece veri okuyorum" diye görülen bir
unserialize, tam RCE ilkelidir. - Otomatik tetikleme.
__wakeup/__destructsaldırgan bir şey "çağırmadan" çalışır; nesnenin canlanması veya yok olması yeter. Bu, saldırının neden tek birunserializeçağrısıyla tetiklendiğini açıklar. - Zincirleme = sink'e ulaşma. POP zinciri, zararsız görünen bir magic method'tan başlayıp, özelliklere yerleştirilen nesneler aracılığıyla adım adım tehlikeli bir yeteneğe (dosya yazma → web shell, çağrılabilir → komut) ilerler. Zincirin uzunluğu, ortamdaki gadget zenginliğine bağlıdır.
- Bağımlılık = saldırı yüzeyi. Framework/kütüphaneler ne kadar zenginse, kullanılabilir gadget da o kadar çoktur. Bu, bağımlılık yönetiminin (Bölüm 30) neden bir güvenlik konusu olduğunu gösterir.
Araştırmacının çerçevesi: (a) güvenilmeyen veri unserialize'a ulaşıyor mu, (b) ortamda uygun bir gadget zinciri var mı, (c) zincir hangi sink'e varıyor. Savunma, (a)'yı hiç mümkün kılmayarak (b) ve (c) ne olursa olsun zinciri kaynağında kırar.
8. Güvenli Kod
Altın kural: güvenilmeyen veriyi asla unserialize etme; JSON kullan.
<?php
// ✅ GÜVENLİ — JSON: nesne canlandırma yok, magic method yok
declare(strict_types=1);
// 1) Tercihler: serialize yerine JSON
$prefs = json_decode($_COOKIE['prefs'] ?? '{}', true); // yalnızca dizi döner
$theme = is_array($prefs) && ($prefs['theme'] ?? '') === 'dark' ? 'dark' : 'light';
applyTheme($theme);
// 2) unserialize zorunluysa (legacy veri): allowed_classes = false
$data = unserialize($row['data'], ['allowed_classes' => false]);
// Kullanıcı sınıfları örneklenmez; nesneler __PHP_Incomplete_Class olur → magic method tetiklenmez
// 3) Bütünlük gerekiyorsa: HMAC ile imzala (kurcalamayı yakala)
function packSigned(array $data, string $key): string {
$payload = base64_encode(json_encode($data));
$mac = hash_hmac('sha256', $payload, $key);
return $mac . '.' . $payload;
}
function unpackSigned(string $blob, string $key): ?array {
[$mac, $payload] = explode('.', $blob, 2) + [null, null];
if ($payload === null || !hash_equals(hash_hmac('sha256', $payload, $key), $mac)) {
return null; // kurcalanmış → reddet
}
return json_decode(base64_decode($payload), true);
}
phar:// vektörüne karşı:
// ✅ Dosya fonksiyonlarına giden yolların şemasını kısıtla
$file = $_GET['file'] ?? '';
if (preg_match('#^[a-z]+://#i', $file)) { // phar:// dahil sarmalayıcıları reddet
http_response_code(400);
exit('Sarmalayıcı yasak');
}
Öne çıkan modern kalıplar:
- JSON tercih et: json_decode, yalnızca skaler/dizi/stdClass üretir; kullanıcı sınıfı örneklemez, magic method tetiklemez. Object injection'ı tanım gereği imkânsız kılar.
- unserialize($x, ['allowed_classes' => false]): unserialize kaçınılmazsa (PHP 7+), sınıf örneklemeyi kapatır; ya da ['allowed_classes' => ['SafeClass']] ile beyaz liste.
- HMAC imzalama: Serileştirilmiş veriyi dışarı verip geri alıyorsanız (nadir), hash_hmac + hash_equals (Bölüm 1) ile kurcalamayı yakala. Yine de tercih JSON'dır.
- Sarmalayıcı şema kısıtlaması: Dosya fonksiyonlarına giden yollarda phar:// gibi şemaları reddet.
9. Patch Analizi
Neden işe yarar? json_decode, tasarımı gereği nesne canlandırmaz; çıktısı yalnızca veri yapılarıdır. Dolayısıyla magic method tetiklenecek bir nesne hiç oluşmaz ve POP zinciri başlayamaz. allowed_classes => false ise unserialize'a "hiçbir kullanıcı sınıfını örnekleme" der; sonuçta gelen nesneler __PHP_Incomplete_Class olur ve magic method'ları çalışmaz. Her iki durumda da saldırganın kontrol ettiği tek şey "veri" kalır, "hangi kod çalışacak" değil.
Alternatiflerin karşılaştırması:
| Yaklaşım | Object injection riski | Not |
|---|---|---|
JSON (json_decode) |
Yok | Varsayılan doğru çözüm |
unserialize(..., ['allowed_classes'=>false]) |
Yok (sınıf örneklenmez) | Legacy unserialize zorunluysa |
allowed_classes beyaz listesi |
Düşük | Yalnızca güvenli sınıflara izin |
| HMAC imzalı serialize | Düşük (kurcalama yakalanır) | Anahtar sızarsa risk sürer; JSON yeğdir |
Ham unserialize(girdi) |
Kritik (RCE) | Asla |
Performans: json_decode genelde unserialize kadar hızlı, çoğu durumda daha taşınabilirdir. Güvenlik ve performans burada çakışmaz; JSON hem güvenli hem pratiktir. HMAC ek bir hash maliyeti getirir ama ihmal edilebilir.
10. Gerçek Hayat Senaryosu
Kurgu — bir çok-kiracılı SaaS "alışveriş sepeti". Uygulama, sepet durumunu performans için serileştirip bir cookie'de saklıyor ve her istekte unserialize ediyor. Geliştirici "sepet kendi verimiz" diye güveniyor. Ama cookie istemci kontrolündedir (Bölüm 1, 16). Uygulama Guzzle, Monolog gibi yaygın kütüphaneler kullandığından, saldırgan bu bileşenler için bilinen bir POP zincirini cookie'ye yerleştiriyor. Tek bir istekle unserialize tetikleniyor, zincir bir dosya-yazma gadget'ına ulaşıp web shell bırakıyor (Bölüm 34) ve saldırgan tüm kiracıların verisine erişen bir RCE elde ediyor. Dersler: (1) "kendi verimiz" bir güven sınırı değildir; cookie daima güvenilmezdir; (2) object injection'ın gücü, sizin kodunuzdan çok bağımlılıklarınızdaki gadget'lardan gelir; (3) serialize yerine JSON, tüm zinciri baştan imkânsız kılardı.
11. Gerçek CVE Analizi — Joomla Object Injection RCE (CVE-2015-8562)
MITRE/NVD, Joomla güvenlik merkezi, Sucuri ve bağımsız araştırmacı analizleriyle doğrulanmıştır. Silahlaştırılmış payload verilmez.
Özet. Aralık 2015'te, Joomla 1.5.0–3.4.5 sürümlerinde kimlik doğrulaması gerektirmeyen bir uzaktan kod çalıştırma açığı, yaban ortamda 0-gün olarak sömürülürken keşfedildi (Sucuri). Saldırgan, HTTP User-Agent (veya X-Forwarded-For) başlığı üzerinden PHP object injection gerçekleştirip keyfi PHP çalıştırabiliyordu. Joomla milyonlarca siteyi çalıştırdığından etki devasaydı; açık 3.4.6 ile düzeltildi.
Teknik neden — object injection'ın tüm zincirini özetler. Joomla, gelen HTTP başlıklarını (User-Agent dahil) veritabanındaki session tablosuna kaydediyordu. Session verisi PHP'nin serileştirilmiş biçimindeydi ve okunurken unserialize ediliyordu. Zincir şöyle işledi:
- Depolama (ikinci derece). Saldırgan,
User-Agentbaşlığına serileştirilmiş kötü bir nesne yerleştirir; Joomla bunu session satırına yazar. Veri "içeriden" gelmiş gibi görünse de kaynağı saldırgandır (Bölüm 1). - Truncation (kesme) hilesi. Joomla'nın session verisi MySQL'de
utf8_general_ciile saklanıyordu. Bu charset, 4 baytlık bir UTF-8 karakteriyle karşılaşınca veriyi o noktada keser. Saldırgan bu kesmeyi kullanarak meşru session verisini sonlandırıp kendi serileştirilmiş nesnesini geçerli bir serileştirme dizesi olarak enjekte edebildi. Bu, "HTTP başlıkları null bayt taşıyamaz" kısıtını aşmanın yaratıcı yoluydu. - Tetikleme. Session bir sonraki istekte DB'den okunup
unserializeedildiğinde, saldırganın nesnesi canlandı ve magic method'u (yaban PoC'deJDatabaseDriverMysqli/SimplePie sınıfları üzerinden bir POP zinciri) tetiklenerek kod çalıştı.
Ayrıca açığın belirli PHP sürümlerini (5.4.45, 5.5.29, 5.6.13 öncesi) hedeflemesi öğreticidir: PHP çekirdeğindeki bir deserializasyon davranışıyla birleşen zincir, sürüm bağımlıydı — birden çok hatanın (Joomla + charset kesme + PHP unserialize davranışı) bir araya gelmesiyle RCE oluştu. Tek başına zararsız görünen parçalar zincirlenince kritik oldu (Bölüm 2, tehdit zincirleme).
Etki. Kimlik doğrulamasız, uzaktan, tam RCE (www-data bağlamında). Joomla'nın yaygınlığı nedeniyle kitlesel olarak sömürüldü; yama öncesi kurulumlar kısa sürede ele geçirildi.
Çıkarılacak dersler:
1. HTTP başlıkları güvenilmeyen girdidir ve depolanıp sonra işlendiklerinde ikinci derece açık kaynağı olurlar (Bölüm 1).
2. unserialize'a giden her yol tehlikelidir — veri bir DB session satırından gelse bile. "İçeriden geldi" güvence değildir.
3. Zincirleme, küçük kusurları felakete çevirir. Charset kesme davranışı tek başına önemsizken, object injection'ı mümkün kılan anahtar oldu. Savunma katmanlı düşünülmeli; tek bir "önemsiz" hata görmezden gelinmemeli.
12. Detection
Kod incelemede: unserialize'a ulaşan güvenilmeyen veriyi ve phar-tetikleyebilecek dosya fonksiyonlarını arayın:
grep -rn 'unserialize(' src/
grep -rnE 'unserialize\((\$_GET|\$_POST|\$_COOKIE|\$_REQUEST|\$_SERVER)' src/ # doğrudan
grep -rnE 'file_exists|is_file|fopen|file_get_contents|md5_file' src/ # phar vektörü olabilir
Her unserialize için: girdi güvenilmeyen mi? allowed_classes verilmiş mi? JSON'a çevrilebilir mi?
SAST: Kaynaktan unserialize sink'ine taint izini bulur; allowed_classes olmadan unserialize kullanımını işaretler. Gadget zinciri varlığı için bağımlılık-farkında (SCA) analiz gerekir.
DAST: Cookie/başlık/parametrelere bilinen gadget imzaları veya gözlemlenebilir (OOB) zincirler göndererek object injection'ı tespit edebilir; kör senaryolar için OOB geri çağrı izler.
WAF: Serileştirilmiş PHP nesne imzalarını (O:, __destruct, sınıf adları) yakalayabilir; ama kodlama ve varyasyonla atlatılabilir. Ek katman.
Loglar/SIEM: Cookie/başlıklarda O:<n>:"..." gibi serileştirilmiş nesne kalıpları; ve object injection genelde RCE'ye vardığından, web sürecinden beklenmeyen alt süreçler / yeni dosya oluşumu (web shell) en güçlü sinyaldir (Bölüm 8, 34). Dosya bütünlüğü izleme (FIM) web dizininde yeni .php dosyalarını yakalar.
13. Prevention
- Altın kural: Güvenilmeyen veriyi
unserializeetme. JSON kullan (json_decode). unserializezorunluysa:['allowed_classes' => false]veya sıkı beyaz liste (PHP 7+).- Serileştirilmiş veriyi dışarı verme; zorunluysa HMAC ile imzala (
hash_hmac+hash_equals). phar://yüzeyini kapat: Dosya fonksiyonlarına giden yollarda sarmalayıcı şemalarını reddet; kullanıcı yüklemelerini dosya fonksiyonlarına yol olarak verme.- Bağımlılıkları yönet: Gadget zincirleri bağımlılıklardan gelir; bileşenleri azalt, güncel tut, tara (Bölüm 30).
- En az yetki + FIM: RCE'ye tırmanırsa hasarı sınırla; web dizinine yazmayı engelle, yeni dosyaları izle.
14. Mitigation
- Acil:
unserialize'a güvenilmeyen veri veren uç noktayı devre dışı bırak veyaallowed_classes => falseekle; mümkünse JSON'a çevir. WAF'ta serileştirilmiş-nesne imzası için geçici kural. - Geçici: FIM ve process logları ile RCE/web shell olup olmadığını belirle; bulunan backdoor'ları temizle (Bölüm 34); sızmış sırları döndür; session'ları geçersiz kıl.
- Kalıcı: Serialize'ı JSON'la değiştir; bağımlılıkları güncelle; en az yetki + FIM'i kalıcılaştır; testler ve SAST/SCA ekle.
15. Checklist
- [ ] Güvenilmeyen veri (cookie, başlık, form, DB'deki kullanıcı-kaynaklı veri)
unserializeediliyor mu? (Edilmemeli.) - [ ] Serileştirme yerine JSON (
json_decode) kullanılabilir mi? - [ ]
unserializezorunluysaallowed_classes => false/beyaz liste var mı? - [ ] Dışarı verilen serileştirilmiş veri HMAC ile imzalı mı?
- [ ] Dosya fonksiyonlarına giden yollarda
phar:///sarmalayıcı şemaları engelleniyor mu? - [ ] İkinci derece kaynaklar (DB session, önbellek) güvenilmeyen sayılıyor mu?
- [ ] Bağımlılıklar (gadget kaynağı) minimize edilip güncel tutuluyor mu?
- [ ] Web dizinine yazma engelli ve FIM ile izleniyor mu?
16. Laboratuvar
Lab 11.1 — Magic method tetikleme. İzole ortamda __wakeup/__destruct içinde gözlemlenebilir (log yazan) bir sınıf tanımla; onun serileştirilmiş hâlini unserialize ederek magic method'un çağrılmadan çalıştığını gözlemle. Sonra allowed_classes => false ile aynı verinin neden magic method tetiklemediğini doğrula.
Lab 11.2 — JSON vs serialize. Aynı veri yapısını serialize/unserialize ve json_encode/json_decode ile gidip gel. json_decode'un neden nesne canlandırmadığını (dolayısıyla object injection'ı imkânsız kıldığını) açıkla.
Lab 11.3 — HMAC imzalama. Bölümdeki packSigned/unpackSigned'ı kur; imzalı veriyi kurcalayıp hash_equals'ın kurcalamayı nasıl yakaladığını gözlemle.
Lab 11.4 — İkinci derece farkındalık. Bir başlığı DB'ye yazıp sonra okuyup işleyen bir akış kur; verinin "DB'den geldi" diye neden güvenli sayılamayacağını (Joomla dersine atıfla) yaz.
17. Quiz
- Object injection, diğer enjeksiyonlardan hangi temel açıdan farklıdır (kod enjeksiyonu vs. yeniden kullanım)?
unserialize,json_decode'dan güvenlik açısından neden çok daha tehlikelidir?- Magic method nedir?
__wakeupve__destructobject injection'da neden kritiktir? - POP (gadget) zinciri nedir ve neden ROP'a benzetilir?
- Bir object injection'ın sömürülebilirliği neden yalnızca sizin kodunuza değil, bağımlılıklarınıza da bağlıdır?
unserialize(..., ['allowed_classes' => false])ne yapar ve neden güvenlidir?phar://vektörü nedir ve neden "unserialize aramak" onu her zaman yakalamaz?- İkinci derece object injection nasıl oluşur? Joomla CVE-2015-8562 bunu nasıl örnekler?
- CVE-2015-8562'deki "charset truncation" hilesi neyi başardı ve tek başına neden önemsiz görünürdü?
- Serileştirilmiş veriyi dışarı vermek zorundaysanız hangi önlem gerekir ve neden JSON yine de tercih edilir?
- Neden "veri DB'den/session'dan geldi" ifadesi bir güven güvencesi değildir?
- SIEM'de object injection sonrası RCE için en güçlü tespit sinyalleri nelerdir?
18. Kaynakça
- OWASP, Deserialization Cheat Sheet; PHP Object Injection (WSTG / Community).
- MITRE, CWE-502: Deserialization of Untrusted Data.
- MITRE / NVD, CVE-2015-8562 (Joomla); Joomla Developer Security Centre, 20151214 Core RCE.
- Sucuri, Joomla 0-Day (CVE-2015-8562) teknik analizi.
- PHP Manual,
unserialize(allowed_classes seçeneği),json_decode,hash_hmac, magic method'lar (__wakeup,__destruct) referansları. - PHPGGC projesi dokümantasyonu (gadget zinciri kavramı — savunma/tespit bağlamında).
- PHP Manual, Phar akış sarmalayıcısı ve güvenlik notları.