October 1, 2026
PortSwigger SQL Injection: 18 Lab, 5 Blind Teknik ve Bir Geliştirici Gözü
Siber güvenlik tarafını öğrenmek isteyen bir yazılımcıyım. Amacım net değil aslında belki kariyer yolumu değiştirmek, belki de yazdığım…

By Enes Seven
3 min read
Siber güvenlik tarafını öğrenmek isteyen bir yazılımcıyım. Amacım net değil aslında belki kariyer yolumu değiştirmek, belki de yazdığım projelerin güvenlik tarafını kontrol edip daha iyi kod yazmak. Ama şunu fark ettim: bir geliştirici olarak güvenlik açıklarını anlamak, sadece saldırgan tarafını değil, savunma tarafını da güçlendiriyor.
Bu yazıda PortSwigger Web Security Academy'deki tüm SQL Injection lab'larını çözerken öğrendiklerimi paylaşacağım. 18 lab, 2 ana kategori, 5 blind teknik ve bir sürü aa bu yüzden prepared statement kullanıyormuşuz anı.
SQL Injection Nedir?
Aslında bunu geliştirici olarak en iyi biz biliyoruz. Kullanıcıdan gelen veriyi doğrudan SQL sorgusuna eklediğinizde olan şey.
query = "SELECT * FROM users WHERE username='" + userInput + "'"query = "SELECT * FROM users WHERE username='" + userInput + "'"Kullanıcı userInput'a admin'-- yazarsa ne olur? sonrasını yorum satırına çevirir, şifre kontrolü devre dışı kalır. Giriş yapıldı.
Bunu bilmek bir şey, ama lab ortamında 18 farklı senaryoda uygulamak bambaşka bir şey.
Bölüm 1: UNION Attack "Veri Ekranda"
İlk lab'larda sorgunun sonucu ekranda görünüyordu. Burada UNION attack ile kendi SELECT sorgumu ekliyordum.
Ama hemen UNION SELECT username, password FROM users yazamıyorsunuz. Önce bir zincir var:
- Sütun sayısını bul ORDER BY 1, ORDER BY 2… hata veren sayının bir eksiği = sütun sayısı
- String kabul eden sütunu bul UNION SELECT 'test', NULL
- Veriyi çek UNION SELECT username, password FROM users
ilk lablar bu şekilde bir döngüde gidiyorduk az çok, am oracle tarafında biraz başım ağrıdı.
Oracle Farkı Oracle'da her SELECT ifadesinde FROM şart. UNION SELECT NULL, NULL yazdığımda hata aldım FROM dual eklemem gerekiyordu. Tablo isimleri büyük harf, information_schema yerine all_tables kullanılıyor. Her veritabanının kendi kuralları var.
Bölüm 2: Blind SQLi "Veri Görünmüyor, Ama Var"
- lab'tan sonra işler zorlaştı. Artık sorgunun sonucu ekranda görünmüyordu. Veri orada, ama onu göremiyorsun. Nasıl çıkaracaksın? Cevap: evet/hayır soruları sorarak, karakter karakter.
5 farklı blind teknik öğrendim. Her birinin mantığı aynı: sunucuya bir soru soruyorsun ve cevabı farklı sinyallerden okuyorsun.
- Boolean-Based Sayfa Farkı
Sayfada "Welcome back" yazısı var. Doğru sorgu gönderdiğimde çıkıyor, yanlışta kayboluyor. Bunu sinyal olarak kullanarak SUBSTRING ile şifrenin her karakterini tek tek buldum. Mesela ilk harf 'a' mı? "Welcome back" geldiyse evet. Gelmediyse 'b' dene, 'c' dene… 20 karakterlik şifreyi harf harf çıkardım. Elle yapmak imkansız olduğu için Python ile otomatize ettim.
- Error-Based 500 vs 200
Sayfa hiç değişmiyor ama bir fark var: SQL hatası tetiklersem 500, tetiklemezsem 200 dönüyor. Oracle'da TO_CHAR(1/0) ile kasıtlı olarak sıfıra bölme hatası üretiyorum. Doğru karakter → 500, yanlış karakter → 200.
- Visible Error-Based Tek İstekte Tüm Veri
Bu en ilginç olanıydı. Hata mesajı detaylı gösteriliyorsa, CAST ile şifreyi integer'a çevirmeye çalışıyorsun. Veritabanı çeviremeyince hata mesajında şifrenin kendisini gösteriyor: "invalid input syntax for type integer: s3cr3tp4ssw0rd". Brute force yok, tek istek, tüm veri. Bir geliştirici olarak bu beni çok etkiledi production'da detaylı SQL hatası göstermek direkt veri sızıntısı demek.
- Time-Based Cevap Geç Gelirse Doğru
Bu sefer sayfa farkı da yok, hata kodu farkı da yok. Tek sinyal: response süresi. PostgreSQL'de pg_sleep(5) ile sunucuyu 5 saniye beklettim. Doğru karakter 5 saniye gecikme, yanlış karakter anında cevap. Burada bir trick vardı: cookie'de ; kullanmam gerekiyordu ama ; cookie'de ayırıcı karakter. %3B ile URL encode edip raw header olarak gönderdim. Bu tür detaylar lab ortamında öğrenilmezse gerçek testte çok zaman kaybettiriyor.
- Out-of-Band DNS ile Veri Sızdırma
En gelişmiş teknik. Sunucu hiçbir sinyal vermiyor sayfa aynı, hata yok, gecikme yok. Ne yaparsın? Sunucuyu senin kontrol ettiğin bir adrese DNS isteği yaptırırsın. Şifreyi subdomain olarak eklersin: s3cr3tp4ssw0rd.senin-sunucun.net. DNS logunda şifreyi görürsün. Bu teknik Burp Suite Professional gerektiriyor, ben henüz Community Edition kullanıyorum. Teoriyi öğrendim, pratiği Burp Pro aldığımda yapacağım.
Bölüm 3: WAF Bypass Güvenlik Duvarını Atlamak
Son lab en farklısıydı. Bir WAF (Web Application Firewall) vardı UNION SELECT yazdığımda "Attack detected" dedi ve isteği engelledi. Daha önce case değiştirme ile bypass yapmıştım (uNiOn SeLeCt). Ama bu WAF onu da yakalıyordu.
Çözüm: XML hex encoding. İstek XML formatında gidiyordu ve XML'de karakterleri hex formatıyla yazabiliyorsun. WAF UNION SELECT görmüyor ama veritabanı decode edip çalıştırıyor. WAF bypass edildi, veri geldi. Bu, güvenliğin tek katmanla sağlanamayacağını gösteriyor WAF var diye SQL injection'a karşı önlem almamak büyük hata.
Geliştirici Gözünden: Bunu Nasıl Engelleriz?
18 lab çözdükten sonra en çok şunu düşündüm: bunların hepsi tek bir satır kodla engellenebilir. Prepared statement kullandığınızda kullanıcının girdisi sorgunun yapısını değiştiremez. admin' yazsa bile bu bir string olarak değerlendirilir, SQL komutu olarak değil.
Ek önlemler: Hata mesajlarını gizle Visible error-based SQLi, detaylı hata mesajı gösterildiği için çalışıyordu. WAF tek başına yetmez XML encoding ile bypass edilebildiğini gördük. En az yetki prensibi veritabanı kullanıcısına sadece gerekli izinleri ver.
Sonuç: Saldırarak Savunmayı Öğrenmek
18 lab, yüzlerce istek, birkaç Python scripti ve çok fazla deneme-yanılma. SQL Injection'ı teorik olarak bilmekle, lab ortamında uygulamak arasında dağlar kadar fark var. Bir geliştirici olarak en büyük kazanımım şu oldu: artık kod yazarken "acaba bu sömürülebilir mi?" diye düşünüyorum. Bu düşünce şekli, güvenli kod yazmanın ilk adımı.
Sıradaki hedef: XSS (Cross-Site Scripting). Yine PortSwigger üzerinden, yine lab lab ilerleyerek.
Bu yazı, PortSwigger Web Security Academy'nin SQL Injection bölümündeki tüm lab'ları çözerken aldığım notlardan derlenmiştir. Eğer siz de güvenlik öğrenmek istiyorsanız, PortSwigger'ın ücretsiz lab'ları harika bir başlangıç noktası.