SQL Enjeksiyonu Teknik Detaylar ve Uygulama | Teknik Arşiv

TURAN

Administrator
Yönetici
Katılım
16 Eylül 2025
Mesajlar
12
Tepkime puanı
9
Puan
3
Web sitesi
ebubekirbayat.com.tr

Pratik İstismar Dinamikleri​

Modern production ortamlarında SQL Enjeksiyonu (SQLi), basit bir tırnak işareti (`'`) testinden çok daha karmaşık bir keşif sürecini kapsar. Bir saldırganın ilk aşamada odaklandığı nokta, Application Logic ile Database Engine arasındaki senkronizasyonu bozmaktır. Discovery fazında, girdi alanlarına gönderilen polimorfik yükler (payloads), uygulamanın HTTP yanıtındaki milisaniyelik gecikmeleri (Time-based Inference) veya içerik boyutundaki byte bazlı değişimleri (Boolean-based Inference) hedefler.

Sahada tetiklenme mekanizması genellikle ORDER BY, GROUP BY veya LIMIT gibi dinamik yapılandırılan query segmentlerinde yoğunlaşır. Statik analiz araçlarının (SAST) gözden kaçırdığı "Second-order SQLi" durumlarında, veri ilk aşamada veritabanına güvenli görünerek kaydedilir ancak daha sonra başka bir fonksiyon tarafından (örneğin bir raporlama motoru) ham (raw) olarak çağrılıp işlendiğinde tetiklenir. Discovery aşaması, Out-of-Band (OOB) teknikleri (DNS/HTTP exfiltration) kullanılarak otomatize edilebilir; bu, kör (blind) senaryolarda veri çekme hızını dramatik şekilde artırır.

Teknik Mekanizma Analizi (Data Flow)​

SQLi'nin temelindeki mekanik arıza, Control Plane (SQL komutları) ile Data Plane (kullanıcı girdisi) arasındaki sınırın ortadan kalkmasıdır. Veri akışı şu aşamalarda manipüle edilir:

1. Untrusted Input Entry: Veri, HTTP parametreleri, header bilgileri (User-Agent, X-Forwarded-For) veya JSON payload içinden alınır.
2. Query Construction (Vulnerable Path): Uygulama katmanı, gelen veriyi bir string birleştirme (concatenation) veya sprintf benzeri formatlayıcılar ile SQL cümlesine dahil eder.
3. AST (Abstract Syntax Tree) Manipulation: Veritabanı motoru SQL sorgusunu parse ederken, kullanıcıdan gelen meta-karakterler (;, --, ', /*) sorgunun sözdizimsel ağacını yeniden yapılandırır.
4. Execution Context Shift: Veri olarak değerlendirilmesi gereken girdi, artık komutun bir parçasıdır. Örneğin, bir WHERE koşulu, saldırganın enjekte ettiği OR 1=1 ile mantıksal bir totolojiye dönüşerek yetkilendirme kontrollerini bypass eder.

Bu süreçte bellek yönetimi hatalarından ziyade Mantıksal Ayrıştırma Hatası söz konusudur. Veritabanı sürücüsü (driver), kendisine gelen tekil string'in hangi kısmının geliştiriciye, hangi kısmının kullanıcıya ait olduğunu ayırt edemez.

Gerçekçi Saldırı Senaryosu (Case Study)​

Senaryo: Bir kurumsal CRM sisteminin dashboard ekranında çalışan, istatistikleri filtrelemek için kullanılan bir API endpoint'i.

Hedef Endpoint: GET /api/v1/stats?field=revenue&order=ASC

Saldırgan, order parametresinin doğrudan SQL sorgusuna ORDER BY yan tümcesi olarak eklendiğini fark eder. Klasik ? placeholder'ları genellikle ORDER BY ifadelerinde kullanılamaz, bu da geliştiricileri string concatenation yapmaya iter.

Saldırı İsteği:
GET /api/v1/stats?field=revenue&order=(CASE+WHEN+(SELECT+ASCII(SUBSTRING(password,1,1))+FROM+users+WHERE+username='admin')=97+THEN+revenue+ELSE+date+END)

Yanıt Analizi:
Eğer admin şifresinin ilk harfi 'a' (ASCII 97) ise, tablo revenue sütununa göre sıralanır. Değilse date sütununa göre sıralanır. Saldırgan, JSON yanıtındaki nesne sıralamasını kontrol ederek veritabanındaki tüm veriyi karakter karakter sızdırır.

Derinlemesine Kod Analizi​

Aşağıda, tipik bir PHP/PDO ortamında yapılan hatalı bir uygulama örneği bulunmaktadır:

PHP:
// VULNERABLE CODE
public function getInvoices($userId, $sortBy) {
    // $sortBy doğrudan kullanıcıdan geliyor: "amount", "date", vb.
    $sql = "SELECT id, amount, date FROM invoices WHERE user_id = " . $userId . " ORDER BY " . $sortBy;
    
    // Geliştirici userId için prepare kullanmış ancak sortBy için concatenation yapmış
    $stmt = $this->db->prepare($sql); 
    $stmt->execute();
    return $stmt->fetchAll();
}

Teknik Analiz:
- Satır 4: $userId değişkeni bir integer dökümü (cast) yapılmadan eklenmiş. Eğer bu değer dışarıdan manipüle edilebiliyorsa (örneğin bir session poisoning ile), Union-based SQLi için zemin hazırlar.
- Satır 4 (Kritik Hata): $sortBy değişkeni doğrudan SQL cümlesine eklenmiş. PDO Prepared Statements, sütun veya tablo isimlerini parametre olarak bağlamayı (binding) desteklemez.
- Risk: Bir saldırgan sortBy değerine id; DROP TABLE invoices; -- gibi bir payload gönderdiğinde, veritabanı motoru Stacked Queries destekliyorsa (PostgreSQL veya MSSQL gibi), tablo tamamen silinecektir.

Hatalı Varsayımlar ve Yaygın Yanılgılar​

1. "WAF Kullanıyoruz, Güvendeyiz": WAF'lar imza tabanlıdır. 0x (hex) kodlama, /*!50000select*/ gibi veritabanına özgü yorum satırı hileleri veya HTTP Parameter Pollution (HPP) teknikleri ile WAF kuralları kolaylıkla bypass edilebilir.
2. "Stored Procedure'lar SQLi'yi Önler": Eğer procedure içerisinde dinamik SQL (EXEC veya sp_executesql) kurgulanmışsa, zafiyet uygulama katmanından veritabanı katmanına taşınmış olur. Güvenliği sağlayan procedure değil, içindeki parametrik yapıdır.
3. "Framework Kullanıyorum, SQLi Olmaz": ORM (Object-Relational Mapping) araçları, rawQuery() gibi metodlar sunar. Geliştirici performans veya karmaşıklık nedeniyle bu metodlara başvurduğu anda koruma kalkanı devre dışı kalır.

Modern Savunma ve Remediye Stratejileri​

Savunma, Defense in Depth prensibiyle çok katmanlı olmalıdır:

- Parameterized Queries (Primary Defense): Veri ve komut setini protokol seviyesinde ayırın. Binary protokol kullanan sürücüler, veriyi "data" paketinde, komutu "header" paketinde göndererek karışıklığı önler.
- Allow-listing (Sıralama ve Dinamik Tablolar İçin): ORDER BY gibi alanlarda parametre bağlama yapılamadığı için, kullanıcıdan gelen girdi önceden tanımlanmış bir liste (array) ile kontrol edilmelidir.
- Principle of Least Privilege (PoLP): Uygulamanın kullandığı DB kullanıcısı, sadece ihtiyaç duyduğu tablolara SELECT/INSERT/UPDATE yetkisine sahip olmalıdır. DROP, ALTER veya xp_cmdshell gibi sistem seviyesi yetkiler kesinlikle kısıtlanmalıdır.
- Database Firewalling: Sorgu paternlerini analiz eden ve beklenmedik bir UNION veya SLEEP gördüğünde bağlantıyı kesen veritabanı seviyesinde güvenlik duvarları kullanılmalıdır.

Güvenlik Profesyoneli Perspektifi​

Bir siber güvenlik uzmanı olarak, log analizinde Anomali Tespiti yaparken şu örüntülere odaklanılmalıdır:
- Sözdizimi Hataları: DB Error: 1064 (42000) near... gibi hataların loglarda yoğunlaşması, bir fuzzing işleminin işaretidir.
- Response Size Variance: Normalde 500 byte dönen bir endpoint'in aniden 10kb veya 0 byte dönmesi.
- Latency Spikes: Özellikle kör (blind) saldırılarda kullanılan pg_sleep() veya dbms_lock.sleep() fonksiyonları, uygulama yanıt süresinde belirgin (ve genellikle tam sayı saniyelerle ifade edilen) gecikmelere neden olur.

Teknik Çıkarım​

SQL Enjeksiyonu, basit bir girdi filtreleme sorunu değil, bir mimari tasarım hatasıdır. Verinin kontrol akışını (control flow) değiştirebildiği her nokta potansiyel bir risk taşıdır. Seviye 3'te, bu zafiyetin Cloud-Native ortamlarda, NoSQL enjeksiyonları ve GraphQL Injection vektörleri ile nasıl evrildiğini, servisler arası güven (trust) ilişkilerinin nasıl sömürüldüğünü inceleyeceğiz.
 
Üst