Birçok geliştirici SQL sorgularının nasıl bozulacağını bilmez bile. SWL komutunun güvenilir olduğunu düşünelim. Bunun anlamı erişim kontrolunu geçmesi (şifreleme denetiminden geçmesi) demektir. Bazen SQL sorguları işletim sistemi komutlarını da kullanabilir.
Doğrudan SQL komut enjeksiyonu, saldırganın sorguyu değiştirip gizli veriyi açma, üzerine yazma ya da tehlikeli sistem düzeyi komutları çalıştırma girişimidir. Bunun oluşma biçimi uygulamanın kullanıcı girişini SQL sorgusundaki değişmez parametrelerle birleştirmesi sırasında olur. Aşağıdaki örnek istenmese de gerçek öykülere dayanır.
Giriş kontrolu eksikliği ve veri tabanına süper kullanıcı ya da sahibi olarak bağlanmak (yeni kullanıcı yaratmasını sağlamak), saldırgana sizin veri tabanında süper kullanıcı yaratmanızı sağlar
sonuç kümesini sayfalara bölmek... ve süper kullanıcı yapmak (PosrgreSQL).
<?php
$offset = $argv[0]; // dikkat edin giriş kontrolu yok
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);
?>
Normal kullanıcılar "next" ve "prev" bağlarını tıklayarak $offset için kodlanmış URL adreslerini kullanırlar. Kodlama gelen $offset değerinin ondalık sayı olduğunu varsayar. Ama biri araya girip forma "urlencode()" eklenmesi yaparsa:
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
select 'crack', usesysid, 't','t','crack'
from pg_shadow where usename='postgres';
--
Eğer yaparsa, kodlama kendisine süper kullanıcı erişimi sağlar. Burada 0; asıl sorguya geçerli başlama noktası sunar ve onu sonlandırır.
Not: Bu SQL taramasına, sorgunun kalanını unutması (dikkate almaması) için yazılan genel bir kuraldır. SQL içinde açıklamanın başlangıcını tanımlar.
Şifreyi almak için en uygun yol, sorgulama sonucu sayfalarını tuzağa düşürmektir. Saldırganın bilmesi gereken tek şey, SQL satırında gönderilen değişkelerden hangisinin doğru ele alınmadığını bulmaktır. Bu engeller (filitreler) aşağıdaki form içinde kişiselleşirilecek SELECT deyimindeki WHERE, ORDER BY, LIMIT ve OFFSET koşullarıyla atanır. Eğer veri tabanınız UNION yapısını destekliyorsa, saldırgan şifreleri listelemek için tüm sorguyu asıl sorgunun peşine ekler. Bu durumda kriptolanmış şifre satırları kullanılması şiddetle önerilir.
Konuları listelemek... ve bazı şifreleri de (herhangi veri tabanı sunucusunda)
<?php
$query = "SELECT id, name, inserted, size FROM products
WHERE size = '$size'
ORDER BY $order LIMIT $limit, $offset;";
$result = odbc_exec($conn, $query);
?>
Sorgunun değişmez bölümü başka bir SELECT ile birleştirilir. O da tüm şifreleri açar.
'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
Eğer bu sorgu (' ve -- ile oynayarak) $query içindeki bir değişkene atanırsa, sorgunun canavarı uyandırılmış olur.
SQL güncellemeler de saldırmaya çok yatkın işlemlerdir. Bu sorgular da kesilerek ve sonuna yeni sorgular eklenerek yepyeni sorgulara dönüşür. Ama saldırgan daha çok SET koşulu üzerinde parmaklarını oynatır. Bu örnekte bazı şema bilgisi de sorguyu başarıyla değiştirmek için ayarlanmalıdır. Kullanılan form değişkenlerini inceleyerek, ya da yalnız kaba kuvvetle ele geçirilir. Şifre ve kullanıcı adı için çok fazla adlandırma kavramı da yoktur.
Şifreyi silmekten... daha çok yetki almaya kadar (her veri tabanı için)
<?php
$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>
Fakat kötü niyetli kullanıcı $uid içine ' or uid like '%admin%'; -- yazarak gönderir. Bu biçimiyle sorgulama "admin" şifresini değiştirir ya da $pwd değerini 'hehehe', admin='yes', trusted=100 " (en arkadaki boşluğuyla) daha çok yetki almayı sağlayabilir. Sonra sorgu yer değiştirebilir.
<?php
// $uid == ' or uid like'%admin%'; --
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --";
// $pwd == "hehehe', admin='yes', trusted=100 "
$query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE
...;";
?>
Bazı veri tabanı sunucularında işletim sistemi komutlarının nasıl erişildiğini gösteren örnekler
Veri tabanı işletim sistemine saldırı (MSSQL Sunucuda)
<?php
$query = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>
Eğer saldırgan $prod değerini a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- olarak gönderirse $query şöyle olur:
<?php
$query = "SELECT * FROM products
WHERE id LIKE '%a%'
exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);
?>
MSSQL Sunucu, toplu iş adımlarındaki SQL satırlarını peşindeki yerel veri tabanına yeni kullanıcı ekleme komutuyla çalıştırır. Eğer bu uygulama sistem yöneticisi (sa) olarak çalışıyorsa ve MSSQLSERVER servisleri yeterli yetkilerle çalışıyorsa, saldırganın bu bilgisayara erişim için artık bir kullanıcı hesabı vardır.
Not: Buradaki örneklerden bazıları özel veri tabanı sunucularına bağlanmıştır. Bu başka ürünlerde benzeri saldırıların başarılı olamayacağı anlamına gelmez. Sizin veri tabanınız da bir başka işlem için aynı biçimde savunmasız olabilir.