Harika bir önceki derste, bir kod tabanında tam bir zafiyetten ziyade, daha büyük bir saldırının yapı taşı olarak hizmet edebilecek "gadget" ve "primitive" adı verilen kod parçacıklarını nasıl tespit edeceğimizi öğrendik. Bir bilgi sızıntısının, bir mantık hatasının veya nesne manipülasyonu gibi kısmi bir kontrolün, tek başına düşük etkili görünse de, bir istismar zincirinin ilk halkası olabileceğini gördük.
Bu derste, bu yapı taşlarını birleştirme sanatına odaklanacağız. Önceki derste bulduğumuz o "kötüye kullanılabilir" kod parçalarını alıp, onları mantıksal bir sıra ile birbirine bağlayarak sonuca ulaşan bir saldırı senaryosu oluşturacağız. Bugünkü öğrenme hedefimiz, iki veya daha fazla farklı kod bulgusunu birleştirerek mantıksal bir istismar yolu oluşturmak ve bu yolu adım adım açıklayan bir kavram kanıtı (Proof of Concept - PoC) anlatısı yazmaktır. Bu ders, kod denetiminin zirve noktasıdır: bulguları sadece listelemek değil, onların bir araya geldiğinde yarattığı kümülatif riski ve gerçek dünya etkisini bir hikaye anlatarak göstermektir.
İstismar Zincirinin Anatomisi
Bir istismar zinciri (exploit chain), her bir adımın bir sonraki adımı mümkün kıldığı bir dizi eylemden oluşur. Bir bulgunun çıktısı, bir sonraki bulgunun girdisi haline gelir. Bu, domino taşlarını dizmeye benzer; ilk taşı devirirsiniz ve o da sırayla diğerlerini tetikleyerek nihai hedefe ulaşır.
Bu zincirleme mantığını görselleştirmek için basit bir akış şemasıyla başlayalım.

Bu şema, birden fazla ve farklı türdeki zafiyetin nasıl birleştirildiğini gösteren mükemmel bir örnektir. Zincir şu adımlardan oluşur: 1) A uygulamasındaki bir XSS zafiyeti (ilk primitive), 2) C uygulamasının session cookie'sindeki HttpOnly bayrağının eksik olması (ikinci primitive) sayesinde, XSS ile bu cookie'nin çalınmasını sağlar. 3) Çalınan bu oturum, C uygulamasındaki RCE zafiyetini (üçüncü primitive, örneğin açık bir Spring Actuator endpoint'i) tetiklemek için kullanılır ve tam yönetici erişimi elde edilir.
Gördüğünüz gibi, tek başına XSS, HttpOnly eksikliği veya RCE zafiyeti farklı risk seviyelerindedir. Ancak bir araya geldiklerinde, senaryo çok daha tehlikeli bir hal alır.
Bu zincirleme mantığının en bilinen ve yıkıcı örneklerinden biri, Log4j (CVE-2021-44228) zafiyetidir. Bu zafiyet, tek bir adımdan değil, en az iki aşamalı bir zincirden oluşur.
Log4j (CVE-2021-44228) Ultra Kapsamlı Teknik Analiz
Bu makale, Log4j istismar zincirinin nasıl çalıştığını teknik olarak derinlemesine açıklıyor. Bir JNDI lookup 'primitive'inin, uzaktaki bir sunucudan zararlı bir Java sınıfı yükleyen bir 'gadget'ı nasıl tetiklediğini anlamak için harika bir kaynak.
Lütfen makaleyi okurken bir istismar zincirinin nasıl kurulduğuna odaklanın: İlk Halka (Primitive): JNDI Lookup. "Çok Basit Bir Payload ile RCE Sağlanabilmesi" başlığı altında, saldırganın loglanan herhangi bir alana ${jndi:ldap://...} gibi bir ifade enjekte ederek zafiyeti nasıl tetiklediğini okuyun. Bu, zincirin başlangıç noktasıdır. Zincirin Kurulması. Bu bölümde özetlenen 5 adımlı zinciri dikkatlice inceleyin: Log4j'nin JNDI'ı tetiklemesi, JNDI'ın LDAP/RMI sunucusuna bağlanması ve bu sunucunun zararlı bir sınıf referansı dönmesi. Teknik Detaylar. "Exploit Server’ın Teknik İşleyişi ve Saldırı Zinciri" başlığı altında, saldırganın genellikle iki ayrı sunucu (bir LDAP yönlendiricisi ve bir HTTP payload sunucusu) kullandığı bu saldırı akışını adım adım takip edin. Bu, iki farklı sistemin (hedef uygulama ve saldırganın altyapısı) bir zincirde nasıl etkileşime girdiğini gösterir. Bu senaryoda, Log4j kütüphanesindeki lookup özelliği bir "primitive"dir. Java'nın uzaktan sınıf yükleme (remote class loading) yeteneği ise bu "primitive"in RCE'ye dönüşmesini sağlayan "gadget"dır. Kod denetçisi olarak görevimiz, bu iki parçayı kodda görüp, "Bu ikisi birleşirse ne olur?" sorusunu sormaktır. Vaka Analizi: Gerçek Bir İstismar Zincirinin Doğuşu ve PoC Anlatısı Şimdi, birden fazla düşük ve orta seviyeli bulgunun birleştirilerek kritik bir RCE zafiyetine nasıl dönüştürüldüğünü gösteren, gerçek bir güvenlik araştırmasına dayalı karmaşık bir senaryoyu inceleyeceğiz. Bu analiz, sadece zinciri kurmakla kalmayıp, aynı zamanda bulgularınızı paydaşlara sunmak için nasıl etkili bir "PoC anlatısı" yazılacağını da gösterecektir. Bu vaka, Mehmet İnce'nin bir ürün güvenlik analizi sırasında yaşadığı deneyimleri temel almaktadır.
Bu senaryoda, Log4j kütüphanesindeki lookup özelliği bir "primitive"dir. Java'nın uzaktan sınıf yükleme (remote class loading) yeteneği ise bu "primitive"in RCE'ye dönüşmesini sağlayan "gadget"dır. Kod denetçisi olarak görevimiz, bu iki parçayı kodda görüp, "Bu ikisi birleşirse ne olur?" sorusunu sormaktır.
Vaka Analizi: Gerçek Bir İstismar Zincirinin Doğuşu ve PoC Anlatısı
Şimdi, birden fazla düşük ve orta seviyeli bulgunun birleştirilerek kritik bir RCE zafiyetine nasıl dönüştürüldüğünü gösteren, gerçek bir güvenlik araştırmasına dayalı karmaşık bir senaryoyu inceleyeceğiz. Bu analiz, sadece zinciri kurmakla kalmayıp, aynı zamanda bulgularınızı paydaşlara sunmak için nasıl etkili bir "PoC anlatısı" yazılacağını da gösterecektir.
Bu vaka, Mehmet İnce'nin bir ürün güvenlik analizi sırasında yaşadığı deneyimleri temel almaktadır.
Bir Hacker’ın Günlüğü: Gerçek Bir ‘Product Security’ Hikâyesi - Mehmet Dursun İnce - Meetup #58
Bu video, bir güvenlik araştırmacısının metodik olarak bir ürünü nasıl analiz ettiğini, farklı katmanlarda bulduğu zafiyetleri nasıl birbirine bağladığını ve sonunda tam teşekküllü bir RCE zinciri oluşturduğunu baştan sona anlatıyor. Bu, "PoC anlatısı yazma" hedefimiz için mükemmel bir pratik örnektir.
Videoyu izlerken, bir kod denetçisinin bulguları nasıl birleştirdiğine odaklanın. Zincirin halkalarını adım adım takip edelim: Primitive #1: SSRF (Sunucu Tarafı İstek Sahteciliği). Bu bölümde, üründeki bir "Webhook" özelliğinin, kullanıcıdan bir URL aldığını fark ediyoruz. İlk başta localhost gibi iç ağ adreslerine yapılan istekler engellenmiş. Ancak bu kontrolün, URL'in kaydedildiği başka bir endpoint'te (/project/settings) eksik olduğu keşfediliyor. Bu, bize iç ağdaki herhangi bir servise HTTP isteği gönderme yeteneği kazandıran ilk "primitive"imizi veriyor. Araştırmacının bu bulguyu nasıl doğruladığını ve aynı mantığın farklı yerlerde nasıl atlanabildiğini gözlemleyin. Primitive #2: SQL Enjeksiyonu (Zero-day). SSRF ile artık iç ağa konuşabiliyoruz. Peki kiminle? Mimari analizi, ClickHouse adında bir analitik veritabanı servisi olduğunu gösteriyor. Bu bölümde, araştırmacı ClickHouse'un dokümantasyonunu ve kodunu okuyarak onun da başka bir veritabanı olan PostgreSQL ile konuşabildiğini keşfediyor. Daha da önemlisi, ClickHouse'un PostgreSQL'e sorgu gönderirken tablo adını yanlış şekilde escape ettiğini, bunun da bir SQL enjeksiyonu zafiyetine yol açtığını buluyor. Bu, kendi başına kritik bir zero-day zafiyetidir ve bizim ikinci, çok daha güçlü "primitive"imizdir. Zinciri Birleştirmek: Ara Parçalar. Elimizde SSRF ve SQLi var. Ama hala eksikler var: PostgreSQL Kimlik Bilgileri: SQLi'yi tetiklemek için ClickHouse'un PostgreSQL'e bağlanması gerekiyor. Bu kısımda, kurulum betiklerinin varsayılan (default) kimlik bilgileri kullandığı keşfediliyor. Bu, tek başına düşük etkili bir bulgudur ama zincirimiz için kritik bir anahtardır. POST'tan GET'e Dönüşüm: Bir sorun daha var. Bizim SSRF primitive'imiz POST isteği gönderirken, ClickHouse'un API'si GET isteği bekliyor. Bu zekice çözümde, saldırgan webhook URL'ini kendi sunucusuna yönlendiriyor. Kendi sunucusu gelen POST isteğini alıp, hedefe (ClickHouse) bir 302 Redirect ile GET olarak yönlendiriyor. Bu, zincirin çalışmasını sağlayan mantıksal bir "köprü"dür. PoC Anlatısı: Tam Saldırı Senaryosu. Videonun bu son bölümü, öğrendiğimiz her şeyi bir araya getirerek tam bir PoC anlatısı sunar. Bu anlatı, bir güvenlik raporunda "Impact" veya "Reproduction Steps" bölümünde yer alacak metnin ta kendisidir: Adım 1: Saldırgan, ürünün API'sini kullanarak Webhook URL'ini kendi kontrolündeki http://saldırgan.com/redirect adresine ayarlar. Adım 2: Saldırgan, Webhook'u tetikleyecek bir olay yaratır. Adım 3: Ürünün arkaplan işçisi (worker), saldırganın sunucusuna bir POST isteği gönderir. Adım 4: Saldırganın sunucusu, gelen isteğe 302 Found yanıtı ile Location: http://internal-clickhouse:8123/?query=<SQLi_Payload> başlığını ekleyerek cevap verir. Adım 5: Arkaplan işçisi, bu yönlendirmeyi takip ederek iç ağdaki ClickHouse servisine, içinde SQL enjeksiyonu yükü barındıran bir GET isteği gönderir. Adım 6: ClickHouse, bu isteği işlerken PostgreSQL'e hatalı bir sorgu oluşturur ve SQL enjeksiyonu tetiklenir. Adım 7: Enjekte edilen SQL kodu, varsayılan kimlik bilgilerini kullanarak PostgreSQL sunucusu üzerinde bir komut çalıştırır ve saldırganın sunucusuna bir reverse shell bağlantısı açar. Sonuç: Uzaktan Kod Çalıştırma (RCE).
Bu vaka, kod denetiminde parçaları birleştirme sanatının ne kadar güçlü olduğunu gösteriyor. SSRF, varsayılan parolalar, SQLi ve mantıksal bir yönlendirme hilesi... Her biri farklı bir kod parçasında, farklı bir servis mimarisinde bulundu ve bir araya getirilerek en yüksek etkiye ulaşıldı.
Genişletilmiş Desen: Uzaktan Erişim + Yetki Yükseltme
İstismar zincirleri sadece web uygulamalarına özgü değildir. Mobil ve işletim sistemi güvenliğinde de en yaygın saldırı deseni, birden fazla zafiyeti zincirlemektir. Genellikle bu zincir, "uzaktan kod çalıştırma" (remote code execution - RCE) ve "yerel yetki yükseltme" (local privilege escalation - LPE) olmak üzere iki ana halkadan oluşur.
Sezgin Baran Korkmaz ve Pegasus Üzerine: NSO Pegasus Nasıl Çalışıyor ? Teknik-taktik Analiz.
Bu videoda Mehmet İnce, NSO Pegasus gibi gelişmiş casus yazılımların çalışma prensibini açıklarken, aslında modern istismar zincirlerinin temel mantığını özetliyor.
Lütfen videoyu izlerken şu zincirleme desenlerine dikkat edin: Zero-Click RCE Zinciri: Bu bölümde, Android'deki Stagefright zafiyeti anlatılıyor. Saldırganın sadece bir MMS mesajı göndererek (kullanıcı hiçbir şeye tıklamadan) hedef cihazda kod çalıştırması mümkün oluyordu. Burada primitive, MMS mesajlarını işleyen kütüphanedeki bir bellek bozulması zafiyetidir. Bu, doğrudan root yetkileriyle RCE sağladığı için tek başına yeterliydi. One-Click RCE + LPE Zinciri: Bu kısımda, daha yaygın olan bir senaryo ele alınıyor: Halka 1 (RCE): Kullanıcı bir linke tıklar ve web tarayıcısı (örn. Safari) zararlı bir siteyi açar. Tarayıcının JavaScript motorundaki (örn. WebKit) bir zafiyet, saldırganın tarayıcının sandbox'ı içinde kod çalıştırmasını sağlar. Bu, kısıtlı bir RCE'dir. Halka 2 (LPE/Sandbox Escape): Saldırgan, bu ilk erişimi kullanarak işletim sisteminin çekirdeğinde (kernel) veya başka bir ayrıcalıklı servisinde bulunan ikinci bir zafiyeti tetikler. Bu bölümde bahsedilen "local privilege escalation", bu ikinci adımdır. Bu zafiyet, sandbox'tan kaçmayı ve cihazda tam yetki (root) elde etmeyi sağlar.
Bu desen, bir kod denetçisi için şu anlama gelir: Düşük yetkili bir bağlamda (örneğin bir web sunucusunun www-data kullanıcısı) bir RCE bulduğunuzda, araştırmanız bitmemiştir. Asıl soru şudur: "Bu sunucuda, bu ilk erişimi kullanarak yetki yükseltebileceğim başka bir zafiyet var mı?" Bu, yerel servislerin yanlış yapılandırılması, SUID bitine sahip programlardaki hatalar veya güncellenmemiş bir kernel olabilir.
Sonuç
Bu derste, tekil kod bulgularını alıp onları mantıksal bir istismar yoluna dönüştürme ve bu yolu ikna edici bir PoC anlatısıyla belgeleme becerisini kazandık. Artık bir kod tabanını incelerken sadece "Bu kod bozuk mu?" diye değil, "Bu kod başka bir bozuk kodla birleşerek ne kadar tehlikeli olabilir?" diye de soracaksınız.
Anahtar Çıkarımlar:
- Zincirleme Düşünme: Güvenli kod denetiminin ileri seviyesi, bulguları izole bir şekilde değil, birbiriyle potansiyel etkileşimleri içinde değerlendirmektir.
- PoC Anlatısının Gücü: İyi yazılmış bir PoC anlatısı, bir zafiyetin soyut riskini somut bir felaket senaryosuna dönüştürür. Bu, teknik olmayan paydaşları bile ikna etmenin en etkili yoludur.
- Bağlamlar Arası Köprüler: En güçlü zincirler genellikle farklı teknolojileri, protokolleri ve mantıksal katmanları (SSRF -> SQLi, RCE -> LPE) birbirine bağlar. Bir denetçi olarak bu farklı bağlamlar arasında akıcı bir şekilde hareket edebilmelisiniz.
Bu modülün ve aynı zamanda kursumuzun son dersinde, bugün öğrendiğimiz bu etki analizi ve zincirleme yeteneğini bir adım daha ileri taşıyacağız. Tespit ettiğimiz bu karmaşık zafiyet desenlerinin temel nedenlerini soyutlayarak, gelecekteki kod denetimleri için nasıl hedefli ve proaktif kontrol listeleri geliştirebileceğimizi ele alacağız. Böylece, reaktif olarak zafiyet bulmaktan, proaktif olarak zafiyetleri önlemeye doğru bir adım atmış olacağız.