Tek Bir Giriş Formu Nasıl Bütün Veritabanını Ele Verdi? — Anonim SQL Injection Senaryosu
Bu, yetkili bir güvenlik testinde karşılaştığımız gerçek bir durumun isim verilmeden, anonimleştirilmiş anlatımıdır. Amaç suçlamak değil; aynı hatanın binlerce sistemde nasıl tekrarlandığını ve nasıl kapatıldığını göstermek.
Elimizde sıradan bir kurumsal panel vardı: kullanıcı adı, şifre, "Giriş" butonu. Dışarıdan bakınca hiçbir şey ilginç değildi. Ta ki kullanıcı adı alanına tek bir karakter — bir tırnak işareti — yazana kadar.
İlk Kıvılcım: Bir Tırnak
Kullanıcı adına sadece ' yazıp giriş denediğimizde ekrana bir veritabanı hatası düştü:
You have an error in your SQL syntax near '''
Bu tek satır her şeyi anlatır: girdiğimiz metin, hiçbir kontrolden geçmeden doğrudan SQL sorgusunun içine yapıştırılıyor. Muhtemel sorgu şuna benziyordu:
SELECT * FROM kullanicilar WHERE ad = '<girdi>' AND sifre = '<girdi>';
Kimlik Doğrulamayı Atlamak
Klasik ama hâlâ işe yarayan yük (payload), kullanıcı adı alanına şu:
' OR '1'='1' --
Sorgu şuna dönüşür ve '1'='1' her zaman doğru olduğu için ilk kullanıcıyla (çoğunlukla yönetici) şifre bilmeden giriş yapılır:
SELECT * FROM kullanicilar WHERE ad = '' OR '1'='1' -- ' AND sifre = '...';
Otomatikleştirmek: sqlmap
Zafiyetin boyutunu ölçmek için — yetki kapsamında — sqlmap kullanırız. İsteği tarayıcıdan yakalayıp dosyaya kaydeder ve şu komutu çalıştırırız:
sqlmap -r istek.txt --batch --dbs
Araç, enjeksiyonu doğrular ve veritabanlarını listeler. Ardından tek bir tablonun tamamı çekilebilir:
sqlmap -r istek.txt --batch -D uygulama -T kullanicilar --dump
Sonuç: tüm kullanıcı adları, e-postalar ve parola özetleri (hash) ekranımızda. Eğer parolalar zayıf algoritmayla saklanıyorsa, birkaç saat içinde büyük kısmı çözülür.
Etki: Neden "Kritik"?
- Tam veri sızıntısı: Müşteri kayıtları, e-postalar, parolalar.
- Yetki yükseltme: Yönetici hesabıyla sisteme tam hakimiyet.
- Yasal ve itibari yıkım: KVKK kapsamında bildirim yükümlülüğü, para cezası ve güven kaybı.
Tek bir kontrol edilmeyen giriş alanı, koca bir kurumu bu noktaya taşır.
Çözüm: Aslında Çok Basit
SQL Injection'ın panzehiri onlarca yıldır bellidir: parametreli sorgular (prepared statements). Girdiyi asla sorgu metnine yapıştırmayın; parametre olarak geçin.
# YANLIŞ — girdi doğrudan sorguya giriyor
cur.execute("SELECT * FROM kullanicilar WHERE ad = '" + ad + "'")
# DOĞRU — parametre olarak geçiliyor, enjeksiyon imkânsız
cur.execute("SELECT * FROM kullanicilar WHERE ad = %s", (ad,))Ek katmanlar: en az yetkili veritabanı kullanıcısı, hata mesajlarını kullanıcıya göstermemek (try/except ile genel mesaj) ve bir web uygulama güvenlik duvarı (WAF).
Etik ve yasal not: Bu tekniklerin tamamı yalnızca sahibi olduğunuz veya yazılı yetki aldığınız sistemlerde denenmelidir. İzinsiz erişim Türkiye'de TCK 243-244 kapsamında suçtur. REDCELL tüm çalışmalarını sözleşme ve yetki kapsamında yürütür.
Sonuç
SQL Injection "eski" bir açıktır ama OWASP listelerinin hâlâ zirvesindedir — çünkü hızlı yazılan her yeni kod onu geri getirir. Bir giriş formunuz varsa, tek bir tırnak testi bugün yapılmalıdır. Emin değilseniz, biz bakalım.
Sisteminizin güvenliğinden emin misiniz?
Ücretsiz Ön Değerlendirme →