SQL Injection' a Giriş ve SQL Injection Nedir?

SQL Injection

For successful operations, surprise must be achieved by guerrillas.
Intelligence is extremely important, and detailed knowledge of the target's dispositions, weaponry and morale is gathered before any attack.


SQL Injection web uygulamalarında ki en ciddi açıkların başında gelir. Özellikle frameworkler ve ORM (Object Relational Mapping) gibi ekstra veritabanı katmanlarının popülerleşmesi ile eskisine göre bugünlerde biraz daha az görülmektedir ama emin olun hala heryerdeler!

Web uygulaması geliştiricilercileri SQL Injection’ ı tam anlamadıklarından dolayı bazı ölümcül hatalar yaparlar. Bu yüzden bugün bilinen basit SQL Injection metodları o kadar çok görünmese de ileri de anlatacağımız ileri seviye SQL Injection açıklarını çok büyük firmalardan, hazır sistemlere kadar bir çok yerde görebilirsiniz.

Güvenlik Günahı !

Ben hackleyemediysem kimse hackleyemez.

Güvenlikteki büyük günahlardan biri kişilerin bazı açıklar hakkında “ben hackleyemediysem güvenlidir.” diye düşünmeleri. Yazı dizisi boyunca bu şekilde bir dizi SQL Injection şehir efsanelerine de yer vereceğiz.

Son olarak SQL Injection hakkında önemli bir not,
SQL Injection veritabanından ve dilden bağımsız olarak her türlü uygulama-veritabanı ilişkisine sahip sistemde bulunabilir ve bu veritabanlarının bir açığı değildir. SQL Injection’ dan korunmak web geliştiricisinin görevidir.

SQL Nedir?

SQL (Structured Query Language) veritabanlarında data çekme, silme ve değiştirme gibi işlemler için kullanılan basit yapılı bir dildir. Bugün hemen hemen tüm web uygulamalarının altyapısında veritabanı desteği vardır ve bu web uygulamaları veritabanı ile SQL aracılığıyla anlaşırlar.

Bir siteye mesaj bıraktığınızda bu mesaj veritabanına kaydedilir. O mesaj onaylandığında veritabanındaki bir alan güncellenmiş olur. Yönetici veritabanındaki kaydı silerek o mesajın siteden silinmesini sağlar.

Örnek bir kayıt silme SQL cümlesi şu şekilde olabilir;
DELETE FROM members WHERE id=17

Yukarıdaki kod veritabanı tarafından çalıştırıldığında members tablosunda id alanı 17 olan kayıt silinecektir.

Bu makale SQL dilinin basit detaylarını ele almayacaktır. Eğer SQL konusunda zayıf iseniz makaleyi anlamanız güç olacaktır. Makaleye devam etmeden önce SQL in temel komutlarını öğrenmenizi ve veritabanı mantığınız anlamanızı tavsiye ederim.

SQL Injection Nedir?

Web uygulamalarında bir çok işlem için kullanıcıdan alınan veri ile dinamik SQL cümlecikleri oluşturulur. Mesela “SELECT * FROM Products” örnek SQL cümleciği basit şekilde veritabanından web uygulamasına tüm ürünleri döndürecektir. Bu SQL cümlecikleri oluşturulurken araya sıkıştırılan herhangi bir meta-karakter SQL Injection’ a neden olabilir.

Meta-Karakter Nedir?

Meta-karakter bir program için özel anlamı olan karakterlere verilen isimdir. Örnek olarak C temelli C#, Javascript, PHP gibi dillerde (\) backslash karakteri bir meta-karakterdir. Compiler (derleyici) ya da Interpreter (yorumlayıcı) bu karakteri görünce ondan sonraki karakteri ona göre işler.

SQL’ için kritik metakarakter (‘) tek tırnak’ tır. Çünkü iki tek tırnağın arası string olarak algılanır. Diğer bir önemli meta-karakter ise (;) noktalı virgüldür, satırın bittiğini ve yeni satır başladığını bildirir.

Genel bir web uygulamasında olası bir üye girişi işlemi şu şekildedir;

  • Formdan gelen kullanıcı adı ve şifre bilgisi ile ilgili SQL cümleciği oluşturulur (SELECT * FROM members WHERE user=’admin’ AND password=’sifre’ gibi)
  • SQL cümleciği kayıt döndürüyorsa böyle bir kullanıcının var olduğu anlamına gelir ve session(oturum) açılır ve ilgili kullanıcı üye girişi yapmış olur.
  • Eğer veritabanından kayıt dönmediyse "kullanıcı bulunamadı" veya "şifre yanlış" gibi bir hata ile ziyaretçi tekrar üye girişi formuna gönderilir.

 

Örnek bir üye girişi kodu

ASP ile yazılmış örnek bir üye girişi 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. satırda “username ve “passwordform değişkenlerinin değerlerini alıyor. 4. satırda SQL cümleciğinin içerisine yerleştirip kullanıcı kontrolü yapıyor. 

Bu işlemden sonra 6. satırda sonucun boş olup olmadığına bakıyor. Eğer boş ise yani kullanıcı veritabanında bulunmadıysa 7. satırda görüldüğü gibi kullanıcıyı hata sayfasına gönderiyor.

Eğer bulunduysa 10 ve 11. satırdaki işlemleri yapıyor. Yani kullanıcıya id’ si ile birlikte bir session açıyor. Bu sayede kullanıcı sisteme giriş yapmış oluyor.

Bu klasik bir login prosedürü. Tabii ki daha farklı ya da karışık olabilir.

Kullanıcı adı ve şifreye bir injection denemesi yapıp neler olacağını inceleyelim. Eğer kullanıcı adı ve şifre yerine “' OR ''='” ve “' OR ''='” girersek başarılı bir şekilde üye giriş yapmış oluyoruz ama nasıl ve niye?

Şimdi çalışan örnek kodu tekrar hatırlayalım 1 ve 2. satır form değerini alıyordu 4. satırda bu gelen değerleri SQL’ in içerisine yerleştirip veritabanında sorgu yaptırtıyordu.

Form değerlerini yerlerine yerleştirelim ve az önceki çalışan SQL’ e bakalım;

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

Farkettiğiniz üzere bu SQL sorgusu her zaman doğru dönecek ve “Members” tablosundaki tüm üyeleri getirecektir. Bu SQL cümleciğini tercüme edersek şu şekilde olacaktır. Members tablosundan username boş olanları ve password ü boş olanları getir ya da boş eşittir boş!

Birinci ve ikinci mantıksal kontrolün kayıt döndürüp döndürmesi önemli değil çünkü üçüncü kontrol her zaman doğru olarak döneceğinden (boş her zamana boşa eşit değil mi?) bu SQL cümleciği her zaman tüm kayıtları döndürecektir. Yani kayıt boş mu dolu mu diye kontrol ettiğimizde kayıt dolu olarak gözükecektir. Farkettiyseniz OR kullandık dolayıyla mantıksal sorguların herhangi bir doğru (true) olarak dönerse tüm kayıtlar dönmüş oluyor.

Dolayısıyla bu SQL Injection' ı yaptığımızda dönen kayıtlardaki ilk kullanıcı olarak giriş yapılmış olacaktır.

Gördüğünüz gibi SQL Injection; SQL cümleciklerinin arasına dışarıdan girdi yaparak SQL’ i istediğiniz şekilde manipüle etmenize izin veriyor.
 
Şimdi SQL Injection videoyu izleyip SQL Injection’ ın en bilinen şeklini görmüş olalım.

answer - 26.01.2007

sitenize yeni bakiyorum ve acayip merak lisiyim bana yardimci olursaniz sevi nirim bunlari daha kolay ve acik nasil ogrenebilirim bana ce vap verirseniz sevinirim simdiden tesekkurler yazilarinizi takip edicem

C4N_P0L4T - 23.01.2007

Bende Yeni Basladim Okuyorum Yazdiklarinizi Anlamadan Cok Begendim Bana Biraz Yardim Edip Yonlendirirseniz Sevinirim.Yani Nasil Baslicam Gibi Tesekkürler.

kuen - 23.01.2007

sql injection dan korunuyoruzda, xss den tam güvenli bir sekilde nasil korunuruzu bende uzun zamandir düsünüyorum, makaleni merakla bekliyorum ferruh.

Varol - 21.01.2007

evet zaten replace ederek kullaniyorum query stringleri fakat bu yöntemde en azindan adami ugrastirir diye aklima geldi:) yani madem girdin hemencecik müdürün odasina dalma ilk önce giris katta dur demek:D

Ferruh Mavituna - 21.01.2007

Benim xss den kastim sonuçta yine bu yolla, stringler ile verinin aktarilmasiydi. Yani önemli olan o stringlerin, formlarin içerisi tarafindan tanimsiz kalmasini saglamak, bunu söylemek istedim:)

Hicbir koruma olmamasindan kat kat iyidir:)

B.A.D. - 21.01.2007

Benim xss den kastim sonuçta yine bu yolla, stringler ile verinin aktarilmasiydi. Yani önemli olan o stringlerin, formlarin içerisi tarafindan tanimsiz kalmasini saglamak, bunu söylemek istedim:)

Ferruh Mavituna - 21.01.2007

Unutmayin ki XSS ataklarda var..

Su anki konu ile tamamen alakasiz olmasinin yaninda kullandiginiz korunma koduna guvenmeniz buyuk bir hata lakin XSS ten korunmak icin en kotu yollardan biri o sekilde basir bir blacklisting yapmak. Sadece olurda birileri buradan alip kullanir diye yazayim dedim.

Ileride XSS konusuna da gelecegiz orada insallah detaylarina ineriz.

Simdilik `Server.HTMLEncode()` u kulanmaniz yukaridakine gore daha saglikli.

B.A.D. - 20.01.2007

okadar da basite almayin bunu... Unutmayin ki XSS ataklarda var.. Bunun için ben asp girislerimde bunu gibi bir fonksiyon kullaniyorum. Bunun ile sizde korunaiblirsiniz..

Function PostKontrol(yazi)

yazi = Replace(yazi, "<", "&lt;")
yazi = Replace(yazi, ">", "&gt;")
yazi = Replace(yazi, "script", "&#115;cript", 1, -1, 0)
yazi = Replace(yazi, "SCRIPT", "&#083;CRIPT", 1, -1, 0)
yazi = Replace(yazi, "Script", "&#083;cript", 1, -1, 0)
yazi = Replace(yazi, "script", "&#083;cript", 1, -1, 1)
yazi = Replace(yazi, "object", "&#111;bject", 1, -1, 0)
yazi = Replace(yazi, "OBJECT", "&#079;BJECT", 1, -1, 0)
yazi = Replace(yazi, "Object", "&#079;bject", 1, -1, 0)
yazi = Replace(yazi, "object", "&#079;bject", 1, -1, 1)
yazi = Replace(yazi, "applet", "&#097;pplet", 1, -1, 0)
yazi = Replace(yazi, "APPLET", "&#065;PPLET", 1, -1, 0)
yazi = Replace(yazi, "Applet", "&#065;pplet", 1, -1, 0)
yazi = Replace(yazi, "applet", "&#065;pplet", 1, -1, 1)
yazi = Replace(yazi, "embed", "&#101;mbed", 1, -1, 0)
yazi = Replace(yazi, "EMBED", "&#069;MBED", 1, -1, 0)
yazi = Replace(yazi, "Embed", "&#069;mbed", 1, -1, 0)
yazi = Replace(yazi, "embed", "&#069;mbed", 1, -1, 1)
yazi = Replace(yazi, "event", "&#101;vent", 1, -1, 0)
yazi = Replace(yazi, "EVENT", "&#069;VENT", 1, -1, 0)
yazi = Replace(yazi, "Event", "&#069;vent", 1, -1, 0)
yazi = Replace(yazi, "event", "&#069;vent", 1, -1, 1)
yazi = Replace(yazi, "document", "&#100;ocument", 1, -1, 0)
yazi = Replace(yazi, "DOCUMENT", "&#068;OCUMENT", 1, -1, 0)
yazi = Replace(yazi, "Document", "&#068;ocument", 1, -1, 0)
yazi = Replace(yazi, "document", "&#068;ocument", 1, -1, 1)
yazi = Replace(yazi, "cookie", "&#099;ookie", 1, -1, 0)
yazi = Replace(yazi, "COOKIE", "&#067;OOKIE", 1, -1, 0)
yazi = Replace(yazi, "Cookie", "&#067;ookie", 1, -1, 0)
yazi = Replace(yazi, "cookie", "&#067;ookie", 1, -1, 1)
yazi = Replace(yazi, "form", "&#102;orm", 1, -1, 0)
yazi = Replace(yazi, "FORM", "&#070;ORM", 1, -1, 0)
yazi = Replace(yazi, "Form", "&#070;orm", 1, -1, 0)
yazi = Replace(yazi, "form", "&#070;orm", 1, -1, 1)
yazi = Replace(yazi, "on", "&#111;n", 1, -1, 0)
yazi = Replace(yazi, "ON", "&#079;N", 1, -1, 0)
yazi = Replace(yazi, "On", "&#079;n", 1, -1, 0)
yazi = Replace(yazi, "on", "&#111;n", 1, -1, 1)
yazi = Replace(yazi, "document.cookie", "&#068;ocument.cookie", 1, -1, 1)
yazi = Replace(yazi, "javascript:", "javascript ", 1, -1, 1)
yazi = Replace(yazi, "vbscript:", "vbscript ", 1, -1, 1)
yazi = Replace(yazi, "'", "")
yazi = Replace(yazi, vbCrLf, "
")

PostKontrol = yazi

End Function


kullanmak için ise requestin basina PostKontrol yapin yeter.

Örnegin;

kadi = PostKontrol(Reques.Form("UserName"))

gibi. Sifre içinde herzaman kripto yapin. MD5 en iyisi. Takilan arkadaslkar olursa mail atabilirler microsoft.turkey[at]gmail.com
-FIXED
-FIXED

Ferruh Mavituna - 20.01.2007

zaman db yapimizda ilk üyeyi herzaman en az yetkiyi vermeliyiz. Veya aklima simdi geldi. Bir if daha ekleyip


Aslinda hayir bu bir korunma degil hala SQL Injection a tamamen acikcisiniz, bir cok acidan. SQL Injection dan korunmak temel olarak cok basit ASP icin konusursak tek tirnagi iki cirft tirnak ile replace etmek yeterli olacaktir. Ancak biraz daha detayli korunma makalesi de yoldaki makalelerden.

Varol - 20.01.2007

o zaman db yapimizda ilk üyeyi herzaman en az yetkiyi vermeliyiz. Veya aklima simdi geldi. Bir if daha ekleyip

if memberID=1 then
Response.Redirect "/error.asp"
end if

dersek en azindan adami biraz daha ugrastirmis olabiliriz. Pekala saldirgan db den sorgu yaptiramadigi sürece ilk kullanici disinda herhangi biriyle login olamaz degilmi ?

Bu da az da olsa bir önlem olabilir. ' or 1=1 -- gibi bir sistem kullanarak test ederdim ben login panelini yazdigimda pekde basarili olmazdim tabi.:)

Yazi çok güzel devamini bekliyoruz bloglarda tanitima basliyoruz.

yLmZ - 20.01.2007

Benm yaptigim saftirik bir sitemde bu sql i kullanmistim,, anlasildi nasil girdikleri =)

«« - « Geri 1 - 2

Yorum Yazın


Tüm yorumlar onaydan geçmektedir, bu işlem en uzun 30 dk. sürecektir. E-mail adresleri yeni yorumları bildirme harici hiç bir başka amaçla kullanılmamaktadır ve sitede gözükmemektedir.



Captcha Kodu