Web Uygulama Güvenliği: SQL Injection - Blind

Bu döküman önceki SQL Injection dökümanın devamı niteliğindedir. https://spyhackerz.org/forum/threads/web-uygulama-güvenliği-sql-injection.55122/ Blind SQL Injection Nedir...

Bu döküman önceki SQL Injection dökümanın devamı niteliğindedir.

Blind SQL Injection Nedir?
Zararlı SQL sorgularımızda hata çıktısı alamadığımız ama aynı zamanda SQL sorgularının çalıştığı SQL Injection türüdür.

Tespiti:
Verdiğimiz veriye göre değişkenlik gösteren bir sayfa bulalım ve bu sayfada SQL injection açığını arayalım.
1 verdik çalıştı 2 verdik çalıştı ve farklı veri getirdi demek ki bu veri girişinden gelen veriler dinamik bir şekilde işlenip bize çıktısı veriliyor.

sqli1.pngsqli1.png

1' attık veri gelmedi. Peki neden gelmedi? Çünkü sayfanın statik kodlarında eğer hata varsa çıktısını gösterme manasındaki @ işareti kullanılmış gördüğünüz gibi.

sqli10.pngsqli10.png

Ama 1 ile veri geliyor 1' ile veri gelmiyor demek ki arkada bir sıkıntı var.
Hemen SQL injection için mantıksal işlemler gerçekleştirelim.
Geçen derste anlattığım gibi 1=1 true döneceğinden where seçicisine true gelir.
Ve dolayısıyla her veri true değerine sahip olduğundan bütün çıktıları görebiliyoruz.
Select deyimi kullanıldığından bütün verileri görebildiğimizi hatırlatmak isterim.
# işareti ile de sonra gelen tek tırnağı yorum satırı içine alıyoruz çünkü sayfadaki kolon sayısını tespit etmek için integer değer vermemiz gerekiyor ve buradaki sondaki tek tırnak işi zorlaştırıyor MySQL o sondaki php kodlarında yazılmış olan tek tırnak işaretini görmezden gelsin diye yorum satırı içine alıyoruz # işaretiyle.

sqli2.pngsqli2.png

Evet bütün çıktıları görebildik. Güzel demekki buradaki verileri istismar edebiliriz.

Hemen sayfada kullanılan SQL sorgusundaki tablonun kolon sayısını bulmak için işlem gerçekleştirelim.
Normalde order by sıralama işlemi yaparken yanına alacağı integer değer ile kolon ismi olmadan o integer değeri kolon sırasına göre bulur ve o kolonmuş gibi çağırır.
Yani "order by 1" dersek "order by ilk_kolon" şeklinde sorguyu çalıştırır.
Biz de bu sayede sayfada kullanılan kolon sayısına ulaşabiliriz.
Ve eğer kolon sayısına ulaşırsak o kolonlardan sayfa içerisinde bize gösterilen kolonları tespit edip tespit edilen kolona veritabanından istediğimiz veriyi yerleştirebiliriz.
Bu sayede veritabanı içerisindeki kritik veriye erişebiliriz. Örneğin yetkili kullanıcı için oluşturulan kullanıcı adı ve parola bilgisi gibi.

Burada kolon sayısını birer birer artırıp bulabileceğimiz gibi büyükten küçülte küçülte de gidebiliriz.
Mantık şu şekil: Hata verince küçült, hata vermezse arttır. Ve en son hata verenin bir altındaki değerde kolon kullanılmaktadır demek o içinde bulunduğumuz tabloda.

Örnek:
order by 5 --> hata verdi demekki 5'in altında bir değerde kolon taşıyor
order by 1 --> çalıştı demekki 1 veya 1'in üstünde bir değerde kolon taşıyor.
order by 3 --> hata verdi demekki 3'ün altındaki bir değerde kolon
order by 2 --> çalıştı demek 2'nin üstü ama 2'nin en küçük üstü olan 3 hata vermişti demekki içinde bulunduğumuz sorguda 2 kolon kullanılmaktadır.

sqli3.pngsqli3.png

Sıra geldi bu kolonların sayfada kullanılan kısımlarından kullancıya çıktısı verilen kısımları bulmaya.
Bu çıktıyı bulabilirsek içine istediğimiz veriyi yerleştirebiliriz.

Hemen union ile önceki sorguya ek yeni bir sorgu oluşturup bu iki sorguyu birleştiriyoruz.
select ile seçme işlemi gerçekleştiriyoruz 1,2 diyerekte önceki sorguda kullanılan 2 kolona erişiyoruz. -Buradaki mantık kolon sayısına kadar birer birer artırmak değil kolon sayısı kadar seçim yapmak. Tabi birer birer artırmak seçtiğimiz verinin nerede olduğunu görmemizi kolaylaştırıyor-
Ve bu kolonların normalde çıktısını görebileceğimiz yerde 1 ve 2 değerini görüyoruz
Demekki bu 1 ve 2 değeri arkaplanda sorgudaki select ile seçilen kolonları temsil ediyor ve 2 kolonun çıktısı bize sunuluyor.
Şimdi bunun içine istediğimiz veriyi yerleştirelim.
Ben deneme amaçlı içinde bulunduğum veritabanını gösteren database() fonksiyonunu kullandım ve başarıyla çıktısını gördüm.

sqli4.pngsqli4.png

Hatırlayalım MySQL veritabanı yazılımında information_schema adlı bir veritabanı varsayılan olarak vardı.
Ve bu information_schema veritabanı diğer veritabanlarının tablo isimlerini kolon isimlerini de saklıyordu.
Hemen information_schema veritabanından şuan kullanmakta olduğumuz veritabanının tablo isimlerine erişelim.
Burada dikkat edin önceden görmediğimiz bir fonksiyon olan group_concat fonksiyonunu gördük.
Bazı yerlerde select deyimi ile seçim yapılır ve çıktısı bir döngü içerisine alınmadığından tek bir adet olarak görürüz yani ilk tablo ismini tek görürüz. İlerleyen makalelerde bunlara örnek vereceğim. Mesela oralarda group_concat fonksiyonu ile birden fazla tablo, kolon ismini bir araya getirebiliriz. Yani bir nevi birleştirici işlevine yarıyor.
group_concat "," ile ayırır ve gördüğünüz gibi gerekli tablo isimlerini elde ettik.

sqli5.pngsql5.png

users Tablosu ilgimi çekti sistemdeki yetkili kullanıcın bilgilerine erişebiliriz diye düşünüp o tablonun kolonlarını çekelim.

sqli6.pngsqli6.png

sonra o tablonun içerisindeki verileri seçiyorum ama yalnız user_id user password kolonlarında bulunan verilerini seçiyorum.
Ve seçtiğimiz bu kolonları ":" ile ayırıyorum.
Bu sayede ilgili tablonun içindeki verileri gerekli kolonlarındaki bilgilerine sql injection açığıyla ulaşmış olduk.

Bonus: Eğer içinde bulunduğumuz MySQL kullanıcısının dosya okuma yetkisi varsa load_file() fonksiyonu ile sistemde bulunan dosyaları okuyabiliriz.

sqli8.pngsqli8.png

Gerekli bilgi:
İllaki or ile mantıksal işlemler yaptırmayabiliriz. Burada and anahtar kelimesi kullanabiliriz.
Örneğin 1' and 1=1# ile sorgu elde ederiz ve 1=1 true olacağından and true dediğimden ilk değeri 1 olan ve true değerine sahip olan içerikleri görebileceğimiz
Eğer 1' and 1=2# verisini sorgumuza eklersek 1 integer değeri 2 integer değerine eşit olmadğından false dönecektir ve and false olacağından iki taraftan biri sağlanmadığından false dönecektir ve çıktı göremeyeceğiz.

1' and 1=1# -> 1' and true# -> 1 değerine sahip olanları seç
1' and 1=2# -> 1' and false -> iki değerden ikiside sağlanmadığından (and iki değerden ikisini sağlanıp sağlanmadığını kontrol eder) çıktıyı göremeyeceğiz.

sqli9.pngsqli9.png

Teşekkürler.
 

Ekli dosyalar

  • sqli10.png
    sqli10.png
    17.1 KB · Görüntüleme: 2
131,877Konular
3,272,205Mesajlar
316,453Kullanıcılar
gorkemeurrrSon Üye
Üst Alt