Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 26

İkinci Derece Enjeksiyonları Tespit Etme

Recommended resources

Harika bir başlangıç yapıyoruz. Bu ders, "İleri Seviye Enjeksiyon ve Veri Sınırı İhlalleri" modülümüzün ilk konusu olan ve genellikle otomatik tarayıcıların gözünden kaçabilen sofistike bir zafiyet sınıfını ele alıyor: ikinci derece enjeksiyonlar (second-order injections).

Bu derste, bir saldırganın kötü amaçlı girdiyi sisteme nasıl "ektiğini" ve bu girdinin daha sonra farklı bir bağlamda "hasat edilerek" nasıl bir zafiyete dönüştüğünü derinlemesine inceleyeceğiz. Amacımız, bu tür dolaylı ve zamana yayılmış veri akışlarını manuel kod analiziyle tespit etme yeteneğinizi keskinleştirmektir. Birinci derece enjeksiyonların aksine (girdi -> anında etki), ikinci derece enjeksiyonlar, verinin yaşam döngüsünü ve geçtiği güven sınırlarını bütüncül bir bakış açısıyla analiz etmeyi gerektirir. Bu, tam da sizin gibi "uzman gözüyle" kod analizi yapmayı hedefleyen bir profesyonel için kritik bir yetkinliktir.

İkinci Derece Enjeksiyonun Anatomisi

En temel tanımıyla ikinci derece enjeksiyon, kullanıcıdan alınan ve ilk aşamada güvenli bir şekilde depolanan bir verinin, daha sonra farklı bir işlem sırasında veritabanından veya başka bir kalıcı depolama alanından okunup güvensiz bir şekilde kullanılmasıyla ortaya çıkar.

Saldırı iki ana aşamada gerçekleşir:

  1. Ekim (Planting): Saldırgan, kötü amaçlı bir yük (payload) içeren bir veriyi uygulamaya gönderir. Uygulama, bu veriyi giriş anında doğrular veya "kaçış" (escaping) işleminden geçirir, bu nedenle INSERT veya UPDATE gibi ilk sorgu için zararsızdır. Veri, bu "temizlenmiş" haliyle veritabanına kaydedilir. Ancak, "temizleme" işlemi genellikle payload'u silmek yerine onu etkisizleştirmeye yöneliktir (örneğin, " karakterini \" yapmak gibi).
  2. Hasat (Harvesting): Uygulamanın farklı bir bölümü, daha sonra bu depolanmış veriyi okur. Ancak bu ikinci işlem, veriyi okuduğu kaynağa (veritabanına) güvendiği için, okunan veriyi herhangi bir doğrulama veya kaçış işlemine tabi tutmadan doğrudan hassas bir fonksiyona (SQL sorgusu, HTML çıktısı, komut satırı vb.) dahil eder. İşte bu noktada, depolanmış olan payload aktif hale gelir ve zafiyet tetiklenir.

Bu zafiyetin temel mantığını ve akışını daha iyi anlamak için lütfen aşağıdaki teknik makalenin ilgili bölümünü inceleyin.

Second Order Sql Injection

Bu doküman, ikinci derece SQL enjeksiyonunun ne olduğunu ve saldırının adımlarını net bir şekilde açıklamaktadır.

Lütfen bu bölümü okuyarak zafiyetin tanımını ve saldırı akışının adımlarını dikkatlice inceleyin. Özellikle, verinin "gidişinin güvenli" ama "gelişinin güvensiz" olması arasındaki farka odaklanın.

Okuduğunuz gibi, buradaki kilit nokta, güvenin yanlış bir varsayıma dayanmasıdır: "Veritabanından gelen veri güvenlidir." Kod analizi yaparken bu varsayım ölümcül olabilir. Veritabanı, dosya sistemi veya herhangi bir paylaşılan kaynak, kullanıcı girdisinin dolaylı yollardan geçtiği bir ara istasyon olabilir ve bu kaynaklardan okunan her veri, sanki doğrudan kullanıcıdan geliyormuş gibi şüpheyle ele alınmalıdır.


Klasik Bir Örnek: Depolanmış SQL Enjeksiyonu

Teoriyi pratiğe dökmek için, bu zafiyetin en yaygın görülen formlarından biri olan ikinci derece SQL enjeksiyonunu inceleyelim. Aşağıdaki kod parçacıkları, bir kullanıcının profil bilgilerini kaydettiği ve daha sonra bu bilgileri görüntülediği basit bir senaryoyu göstermektedir.

Aynı makalede yer alan PHP kod örneklerini inceleyerek zafiyetin kod seviyesinde nasıl oluştuğunu görelim.

Second Order Sql Injection

Bu bölüm, insertPage.php ve showPage.php dosyaları üzerinden ikinci derece SQL enjeksiyonunun nasıl gerçekleştiğini somut kod örnekleriyle göstermektedir.

Lütfen bu bölümdeki PHP kodlarını dikkatlice analiz edin. insertPage.php dosyasında mysql_real_escape_string fonksiyonunun kullanımına ve showPage.php dosyasındaki ikinci sorguda bu fonksiyonun neden kullanılmadığına odaklanın.

Bu örnekteki zafiyetin özeti şudur:

  • insertPage.php: Kullanıcıdan gelen nickname gibi alanlar, mysql_real_escape_string fonksiyonu ile işlenir. Bu fonksiyon, SQL sorgusunun sözdizimini bozabilecek özel karakterlerin (örn: tek tırnak ') önüne bir ters eğik çizgi (\) ekleyerek onları etkisiz hale getirir. Örneğin, admin' girdisi admin\' olarak veritabanına kaydedilir. Bu, INSERT sorgusunu güvende tutar. Ancak payload'un kendisi (örn: admin' OR 1=1 --) veritabanında saklanmaya devam eder.
  • showPage.php: İlk sorgu, yine güvenli bir şekilde nickname'e göre kullanıcı verisini çeker. Ancak sorun ikinci sorguda başlar. Veritabanından çekilen satırdaki firstName alanı ($row[2]), hiçbir kontrolden geçmeden doğrudan ikinci bir SQL sorgusuna birleştirilir. Eğer saldırgan, kayıt sırasında firstName alanına test' UNION SELECT 1,2,3,4 -- gibi bir payload girdiyse, bu payload veritabanından olduğu gibi okunur ve ikinci sorguyu manipüle eder.

Aşağıdaki görsel, tipik bir birinci derece SQL enjeksiyonunun veri akışını göstermektedir.

Bu görsel, kullanıcıdan gelen girdinin (`HTTP parameter`) doğrudan tehlikeli bir `executeQuery` fonksiyonuna ulaştığı birinci derece bir SQL enjeksiyonu akışını sergilemektedir. İkinci derece bir enjeksiyonda ise bu akışa bir ara adım eklenir: veri önce veritabanına yazılır, daha sonra farklı bir işlemle okunarak tehlikeli fonksiyona iletilir.

Modern Framework'lerde Durum: ORM'ler Her Zaman Güvenli mi?

Peki, günümüzde yaygın olarak kullanılan ORM (Object-Relational Mapping) katmanları ve modern framework'ler bizi bu tür zafiyetlerden tamamen korur mu? Cevap, ne yazık ki, hayır. ORM'ler, parametreli sorgular (prepared statements) kullanarak birinci derece enjeksiyonların büyük çoğunluğunu engellemede son derece etkilidir. Ancak, ORM'in kendisinde veya bir geliştiricinin ORM'i kullanma biçiminde hatalar olabilir.

Bir ORM'in, bazı karmaşık sorgu türlerini oluşturmak için arka planda dinamik olarak SQL string'leri birleştirdiği durumlar olabilir. Eğer bu birleştirme işlemine giren bir parametre, dolaylı yoldan (örneğin veritabanında saklanan bir konfigürasyon değeri üzerinden) kullanıcı tarafından kontrol edilebiliyorsa, ikinci derece bir enjeksiyon ortaya çıkabilir.

Bu konuyu daha somut bir şekilde anlamak için, Django framework'ünde bulunmuş gerçek bir SQL enjeksiyonu zafiyetini (CVE-2022-34265) analiz eden aşağıdaki videoyu izlemenizi rica ediyorum. Video, doğrudan bir ikinci derece enjeksiyonu göstermese de, bir ORM'in bile nasıl güvensiz string birleştirme yapabileceğini ve bunun bir kod analisti tarafından nasıl tespit edilebileceğini mükemmel bir şekilde ortaya koyuyor.

SQL Injection Gerçekte Nasıl Engelleniyor ? ORM kullanmak her zaman güvenli mi ?

Bu video, modern bir web framework'ü olan Django'da tespit edilen bir SQL enjeksiyon zafiyetinin kök neden analizini yapıyor. ORM'lerin güvenlik vaatlerine rağmen nasıl zafiyet barındırabileceğini anlamak için harika bir örnek.

Lütfen videonun bu bölümünü izleyin. Bu bölümde, Django'nun extract fonksiyonundaki bir SQL enjeksiyon zafiyeti, debugger kullanılarak adım adım analiz ediliyor. Özellikle, ORM'in arka planda nasıl bir SQL sorgusu oluşturduğuna, string birleştirmenin nerede yapıldığına ve saldırganın bu durumu nasıl istismar edebildiğine odaklanın.

İzlediğiniz videodaki zafiyet, kullanıcı girdisinin lookup_name olarak doğrudan extract fonksiyonuna verildiği bir birinci derece enjeksiyondur. Şimdi bu senaryoyu bir ikinci derece enjeksiyona dönüştürelim:

Farz edin ki uygulama, kullanıcıların raporlarında tarihleri hangi formatta (yıl, ay, hafta vb.) görmek istediklerini profillerine kaydetmelerine olanak tanıyor. Bir saldırgan, profil ayarlarında "tarih formatı" olarak şu değeri kaydedebilir: year) AS injected; SELECT pg_sleep(10); --. Uygulama bu girdiyi bir metin dizesi olarak gördüğü için, depolama sırasında bir sorun teşkil etmez.

Daha sonra, kullanıcı bir rapor oluşturduğunda, uygulama bu "tarih formatı" tercihini veritabanından okur ve videodaki zafiyetli extract fonksiyonuna parametre olarak geçirir:




# Kullanıcının profilinden okunan 'kötü' tercih
date_format_preference = "year) AS injected; SELECT pg_sleep(10); --" 




# Bu 'tercih' doğrudan ORM fonksiyonuna veriliyor
queryset.annotate(
    extracted_date=Extract('publication_date', lookup_name=date_format_preference)
)

Sonuç? Veritabanında masum bir şekilde duran bir metin dizesi, farklı bir bağlamda (ORM sorgusu oluşturma) tehlikeli bir SQL koduna dönüşür. Bu, ikinci derece enjeksiyon mantığının modern ve karmaşık bir uygulamasıdır.


Tespit ve Önleme Stratejileri

Güvenli kod analizi yaparken ikinci derece enjeksiyonları tespit etmek için şu adımları izlemelisiniz:

  1. Kaynakları Belirleyin: Kullanıcı tarafından kontrol edilebilen verilerin nereye yazıldığını tespit edin (Veritabanı tabloları, konfigürasyon dosyaları, cache vb.).
  2. Hedefleri Takip Edin: Bu depolanmış verilerin uygulama içinde nerelerde okunduğunu belirleyin. Kod tabanınızdaki SELECT sorgularını veya ORM'in okuma metotlarını (.get(), .filter() vb.) inceleyin.
  3. Bağlamı Analiz Edin: Okunan veri hangi bağlamda kullanılıyor?
    • Bir SQL sorgusuna mı dahil ediliyor? (İkinci Derece SQLi)
    • HTML sayfasına mı basılıyor? (Depolanmış XSS)
    • Bir dosya yolunu mu oluşturuyor? (Path Traversal)
    • Sistem komutuna mı parametre oluyor? (Komut Enjeksiyonu)
    • Bir XML ayrıştırıcısına mı veriliyor? (XXE)
  4. Doğrulamayı Kontrol Edin: Veri, okunduğu noktada, kullanılacağı bağlama uygun şekilde doğrulanıyor, temizleniyor veya kodlanıyor mu? Altın kural: Sadece girişte değil, kullanım anında da (çıkışta) veriyi doğrulayın.

Özet ve Sonraki Adım

Bu derste, ikinci derece enjeksiyonların temel mantığını, klasik ve modern örneklerini ve kod analizi sırasında bu zafiyetleri nasıl tespit edebileceğinizi öğrendik.

Anahtar Çıkarımlar:

  • İkinci derece enjeksiyonlar, verinin güvenli bir şekilde depolanıp daha sonra güvensiz bir şekilde kullanıldığı, zamana yayılmış zafiyetlerdir.
  • Bu zafiyetlerin temel nedeni, "veritabanı gibi dahili kaynaklardan gelen veriler güvenlidir" şeklindeki yanlış varsayımdır.
  • Manuel kod analizinde başarı, verinin tüm yaşam döngüsünü (depolama, okunma ve kullanılma) takip etme ve her kullanım noktasında bağlama özgü doğrulama yapılıp yapılmadığını kontrol etme becerisine dayanır.
  • Modern framework'ler ve ORM'ler güvenliği artırsa da, mutlak koruma sağlamazlar. Arka planda nasıl çalıştıklarını anlamak ve potansiyel zafiyet desenlerini bilmek kritik öneme sahiptir.

Bir sonraki dersimizde, yine bir veri akışı ve güven sınırı ihlali zafiyeti olan Sunucu Tarafı İstek Sahteciliği (Server-Side Request Forgery - SSRF) konusunu ele alacağız. Bir uygulamanın, saldırgan tarafından kontrol edilen hedeflere beklenmedik ağ istekleri yapmaya nasıl zorlanabileceğini ve bu durumu kodda nasıl tespit edeceğimizi inceleyeceğiz.