SQL Injection

Zinnur Yeşilyurt —  2 Eylül 2014 — 2 Comments

Merhabalar,

Bu benim bu blogdaki ilk yazım. Bu blogla Linux Yaz Kampı 2104’ü anlatan bir yazının altına attığım bir yorumla tanıştığım için Linux Yaz Kampı 2014’te Web Uygulama Güvenliği ve Güvenli Kod Geliştirme kursunda öğrendiğim bir konuyla başlamak istedim. Konunun çok ilerisini anlatan bir yazı değil de biraz özet maiyetinde. Zira bu konu için kitaplar var. o_O

Yazılımcı için iyi yazılım, uygulama geliştirmek önemlidir. Ancak geliştirdiğimiz işin güvenli olması da çok çok çok önemli bir konu. Zira çok fazla kişi internet bankacılığı, mobil ödeme, kredi kartı vs… kullanmakta.

Linux yaz kampı bünyesinde gittiğim kurs sonrası kursa dair bir doküman hazırlığındayım. Yakın zamanda bitecek ve yayınlayacağım. Kursun toparlama özeti gibi bir şey olacak sanırım. Ama şimdiden 25 sayfa olan bir özet görmedim. Neyse konumuza gelelim.

OWASP Top 10 sıralamasında 1. sırada yer alan Injections zafiyetinin bir çeşidi de Sql injection. Sql injection kullanıcıdan alınan input alanına arka tarafta çalışan Sql sorgusunu manipüle edip amacımıza hizmet edecek çıktılar vermesini sağlayacak Sql query’ler sokuşturmaktır.

SQLI (Sql Injections) ÇEŞİTLERİ

  • Union Based Sqli: Kolon sayısının “union” ile bulunmasıyla başlanıp sorgunun derinleştirilmesidir. 2 farklı select sorgusunun “union” ile birleştirildiğinde çıktı verebilmesi için eşit sayıda kolon sayısına sahip olmalı. Durumun kod üzerinde nasıl geliştiğini görmek için basit bir kod bloğunu inceleyelim:

Input’umuz POST methoduyla kullanıcıdan alınan catid değeridir. catid değeri kodun aşağısına inilince sql sorgusunun içine gittiği görülmektedir. O halde catid değişkenin değerine yazdığımız ifade ile SQL sorgusunu manipüle edebiliriz. Örnek olarak da catid içerisine şunu yazabiliriz:
(Tabii denemeler ile kaç kolon olduğunu bulduktan sonra)

Burada temel durum arka taraftaki select ile işlev gören sorgunun yapısının neyi ekrana döktüğünü, nasıl döktüğünü izleyerek manipüle edecek query’i buna göre oluşturmaktır.

  • Blind Based Sqli (Adam Asmaca gibi 🙂 ): Deneme – yanılma methoduyla veritabanından gelen cevaba göre şekillenen SQLi çeşididir. Örneğin “substring” kullanılarak yapılabilir. Sql injection’da önemli olan kullanıcıdan alınan verinin sorgunun neresine gittiğidir.

Burada topicid’nin karşısındaki id değişkenin değerini union ile manipüle edemeyiz. Çünkü group by ifadesi sql syntax’ından dolayı hata verecektir! Önemli olan burada araya girerek yazdığımız yeni sorgunun çalışmasıdır. Buradaki örnekte şöyle bir yol izleyebiliriz:

Buraya önce 2 yazıyoruz ki sonuç dönmediği haliyle burada sqli olduğunu anlıyoruz. Sonrasında topicid=’3′ and ‘1’=’1‘ ile çatır çutur sqli zafiyetini sömürebiliriz. Burada farkedildiği gibi sqli incelemesinde başta union sqli gibi belirli bir durum yok her şey tamamen tahmini ve körlemesine işliyor.
Peki burada 1 yazdık, 2 yazdık da ne oldu? Şimdilik sadece zafiyet tespiti yaptık. Şimdi o zafiyeti sömüreceğiz. Peki bu kadar körlemesine giderken bunu nasıl yapacağız? Tabii ki en başta da söylediğimiz gibi substring kullanacağız. Örneğin yukarıda and kelimesinden sonra ‘1’=’2′ gibi ifadelerle devam ettik burada devam edebildiğimiz nokta and kelimesinden sonrası olduğu için buraya substring ile devam edeceğiz.

Burada kast edilen sayfa sonuç dönerse arkadaki veritabanı mysql’in versiyon 5’ini kullanıyor demektir. Dönmezse 6 diyerek yolumuza devam ediyoruz.
Veritabanının sayıyla olan versiyon kısmını bu yöntemle çok rahat edinebiliriz. Ancak harfli olan kısımlar için küçük bir fonksiyon ekleyeceğiz: ASCII

Not!: Versiyon isimleri küçük harfle yazıldığından küçük harf kontrolleri yazpınız. Yani ASCII tabloda küçük harfler bölümünden başlayınız. Yoksa çok işiniz var.

Burada zafiyeti sömürmek için versiyon isminden ziyade tablo isimleri, kullanıcı parolaları vs.. gibi şeyleri kontrol ederek alabilirsiniz.

  • Time Based Sqli : Eğer output yoksa, sleep fonksiyonunu kullanarak elimizdeki query sokuşturmalarının çalışıp çalışmadıklarını veritabanının sleep ile versiğimiz zaman değeri kadar geç cevapla dönmesinden anlarız. Dönen işe yarar bir şey yoktur ancak bizim sqli olduğunu anlayabilmemizin sebebi sorguda sleep gönderdiğimizde veritabanının mışıl mışıl uyumasıdır.
  • Error Based  Sqli:Veritabanına “ veya ‘ vs.. gibi hata vermesini sağlayacak girdiler yollayarak Syntax Errror verdirtip değişkenleri kullanılışları, verdiği hataya göre veritabanını anlayarak zafiyeti sömürme biçimidir.

Not!:Google’da “Sql Injection Wiki” aratılırsa injection için tüm veritabanlarında hangi yöntemler kullanıldığı görebiliriz.

Sqli var mı yok mu için basit test:
www.sky.com/index.php?xxx=6
www.sky.com/index.php?xxx=7-1
veya
www.sky.com/index.php?xxx=6 and 1=1
www.sky.com/index.php?xxx=6 and 1=2
Eğer URL’de bu gibi ifadeler yazdığımızda ekrana sonuç alabiliyorsak bu, SQL açığının varlığını gösterir.

SQL INJECTION’DAN KORUNMA YÖNTEMLERİ

Kodlama sırasında veritabanıyla olacak iletişim kullanılan dil üzerindeki “Prepared Statement” yapılarıyla yapılmalıdır. Veya basitçe ORM kullanımıyla da çözülebilir. Zaten ORM de taban olarak Prepared Statement kullanır.
Örneğin PHP dilinde PDO ile Prepared Statement oluşturabilirsiniz. Eğer bilmiyorsanız kullandığınız dildeki Prepared Statement kodlamayı öğrenmelisiniz.
Bu biçimdeki kodlama uygulamanızı Sqli saldırılarına karşı kesinlikle koruyacaktır.

Umarım bu yazdıklarım birilerine faydalı olur.
Şimdi ise ilk yazıların adeti olan

Zinnur Yeşilyurt

Zinnur Yeşilyurt

Posts Twitter

Hayalindeki mesleği ve işi icra etmekte olan, mutlu ve huysuz bir penguen. Güvenlik hakkındaki her şeyi tutkuyla öğrenmek istiyor. Şu an Junior Security Consultant olarak Symturk'de çalışıyor.

2 responses to SQL Injection

  1. Zinnur öğrendiklerimizi pekiştirdim sabah sabah 🙂 Eline sağlık…

  2. Zinnur Yeşilyurt
    Zinnur Yeşilyurt 2 Eylül 2014 at 11:47

    😀 Teşekkür ederim Elif’cim 🙂

Yorum yapmak için