2 Mart 2012 Cuma

SQL Injection


SQL Injection web uygulamalarinda ki en ciddi açiklarin basinda gelir. Özellikle frameworkler ve ORM (Object Relational Mapping) gibi ekstra veritabani katmanlarinin popülerlesmesi ile eskisine göre bugünlerde biraz daha az görülmektedir ama emin olun hala heryerdeler!

Web uygulamasi gelistiricilercileri SQL Injection’ i tam anlamadiklarindan dolayi bazi ölümcül hatalar yaparlar. Bu yüzden bugün bilinen basit SQL Injection metodlari o kadar çok görünmese de ileri de anlatacagimiz ileri seviye SQL Injection açiklarini çok büyük firmalardan, hazir sistemlere kadar bir çok yerde görebilirsiniz.

Güvenlikteki büyük günahlardan biri kisilerin bazi açiklar hakkinda “ben hackleyemediysem güvenlidir.” diye düsünmeleri. Yazi dizisi boyunca bu sekilde bir dizi SQL Injection sehir efsanelerine de yer verecegiz.
Son olarak SQL Injection hakkinda önemli bir not,
SQL Injection veritabanindan ve dilden bagimsiz olarak her türlü uygulama-veritabani iliskisine sahip sistemde bulunabilir ve bu veritabanlarinin bir açigi degildir. SQL Injection’ dan korunmak web gelistiricisinin görevidir.


SQL Nedir?


SQL (Structured Query Language) veritabanlarinda data çekme, silme ve degistirme gibi islemler için kullanilan basit yapili bir dildir. Bugün hemen hemen tüm web uygulamalarinin altyapisinda veritabani destegi vardir ve bu web uygulamalari veritabani ile SQL araciligiyla anlasirlar.
Bir siteye mesaj biraktiginizda bu mesaj veritabanina kaydedilir. O mesaj onaylandiginda veritabanindaki bir alan güncellenmis olur. Yönetici veritabanindaki kaydi silerek o mesajin siteden silinmesini saglar.
Örnek bir kayit silme SQL cümlesi su sekilde olabilir;

DELETE FROM members WHERE id=17

Yukaridaki kod veritabani tarafindan çalistirildiginda members tablosunda id alani 17 olan kayit silinecektir.
Bu makale SQL dilinin basit detaylarini ele almayacaktir. Eger SQL konusunda zayif iseniz makaleyi anlamaniz güç olacaktir. Makaleye devam etmeden önce SQL in temel komutlarini ögrenmenizi ve veritabani mantiginiz anlamanizi tavsiye ederim.

SQL Injection Nedir?


Web uygulamalarinda bir çok islem için kullanicidan alinan veri ile dinamik SQL cümlecikleri olusturulur.
Mesela “SELECT * FROM Products” örnek SQL cümlecigi basit sekilde veritabanindan web uygulamasina tüm ürünleri döndürecektir. Bu SQL cümlecikleri olusturulurken araya sikistirilan herhangi bir meta-karakterSQL Injection’ a neden olabilir.

Meta-Karakter Nedir?
Meta-karakter bir program için özel anlami olan karakterlere verilen isimdir. Örnek olarak C temelli C#, Javascript, PHP gibi dillerde (\) backslash karakteri bir meta-karakterdir. Compiler (derleyici) ya da Interpreter (yorumlayici) bu karakteri görünce ondan sonraki karakteri ona göre isler.
SQL’ için kritik metakarakter (‘) tek tirnak’ tir. Çünkü iki tek tirnagin arasi string olarak algilanir. Diger bir önemli meta-karakter ise (;) noktali virgüldür, satirin bittigini ve yeni satir basladigini bildirir.
Genel bir web uygulamasinda olasi bir üye girisi islemi su sekildedir;

• Formdan gelen kullanici adi ve sifre bilgisi ile ilgili SQL cümlecigi olusturulur (SELECT * FROM members WHERE user=’admin’ AND password=’sifre’ gibi)
• SQL cümlecigi kayit döndürüyorsa böyle bir kullanicinin var oldugu anlamina gelir ve session(oturum) açilir ve ilgili kullanici üye girisi yapmis olur.
• Eger veritabanindan kayit dönmediyse "kullanici bulunamadi" veya "sifre yanlis" gibi bir hata ile ziyaretçi tekrar üye girisi formuna gönderilir.

Örnek bir üye girisi kodu
ASP ile yazilmis örnek bir üye girisi kodu;

1. FUsername = Request.Form("username")
2. FPassword = Request.Form("password")
3.
4. Set RsLogin = SQLConn.Execute("SELECT * FROM Members WHERE username = '" & FUsername & "' AND Password = '" & FPassword & "'")
5.
6. If RsLogin.EOF AND RsLogin.BOF Then
7. Response.Redirect "/error.asp"
8.
9. Else
10. Session("login") = RsLogin("user_id")
11. Response.Redirect "../"
12.
13. End If

Kod gayet basit. 1. ve 2. satirda “username” ve “password” form degiskenlerinin degerlerini aliyor. 4. satirda SQL cümleciginin içerisine yerlestirip kullanici kontrolü yapiyor.

Bu islemden sonra 6. satirda sonucun bos olup olmadigina bakiyor. Eger bos ise yani kullanici veritabaninda bulunmadiysa 7. satirda görüldügü gibi kullaniciyi hata sayfasina gönderiyor.
Eger bulunduysa 10 ve 11. satirdaki islemleri yapiyor. Yani kullaniciya id’ si ile birlikte bir session açiyor. Bu sayede kullanici sisteme giris yapmis oluyor.

Bu klasik bir login prosedürü. Tabii ki daha farkli ya da karisik olabilir.
Kullanici adi ve sifreye bir injection denemesi yapip neler olacagini inceleyelim. Eger kullanici adi ve sifre yerine “' OR ''='” ve “' OR ''='” girersek basarili bir sekilde üye giris yapmis oluyoruz ama nasil ve niye?

Simdi çalisan örnek kodu tekrar hatirlayalim 1 ve 2. satir form degerini aliyordu 4. satirda bu gelen degerleri SQL’ in içerisine yerlestirip veritabaninda sorgu yaptirtiyordu.

Form degerlerini yerlerine yerlestirelim ve az önceki çalisan SQL’ e bakalim;

SELECT * FROM Members WHERE username = '' OR ''='' AND Password = '' OR ''=''

Farkettiginiz üzere bu SQL sorgusu her zaman dogru dönecek ve “Members” tablosundaki tüm üyeleri getirecektir. Bu SQL cümlecigini tercüme edersek su sekilde olacaktir. Members tablosundan username bos olanlari ve password ü bos olanlari getir ya da bos esittir bos!
Birinci ve ikinci mantiksal kontrolün kayit döndürüp döndürmesi önemli degil çünkü üçüncü kontrol her zaman dogru olarak döneceginden (bos her zamana bosa esit degil mi?) bu SQL cümlecigi her zaman tüm kayitlari döndürecektir. Yani kayit bos mu dolu mu diye kontrol ettigimizde kayit dolu olarak gözükecektir. Farkettiyseniz OR kullandik dolayiyla mantiksal sorgularin herhangi bir dogru (true) olarak dönerse tüm kayitlar dönmüs oluyor.
Dolayisiyla bu SQL Injection' i yaptigimizda dönen kayitlardaki ilk kullanici olarak giris yapilmis olacaktir.

Gördügünüz gibi SQL Injection; SQL cümleciklerinin arasina disaridan girdi yaparak SQL’ i istediginiz sekilde manipüle etmenize izin veriyor.

Hiç yorum yok:

Yorum Gönder