Bash betiği ile Tüm Mysql veritabanlarında arama yapma
Bu aralar hack saldırılarında ve ataklarında inanılmaz bir yoğunluk var. Yönettiğim sunucularda karşılaştığım bazı saldırılar yanında bana gelen yardım taleplerinde ki artışlarda bana hack ataklarının sayılarının oldukça arttığını gösteriyor. Bu ataklardan en çok uygulanan tekniklerden birisi de SQL injection yani SQL enjeksiyonu atakları. Peki nedir bu SQL injection saldırısı?

SQL injection (SQL enjeksiyonu) Saldırıları
SQL Injection (SQL Enjeksiyonu), kötü niyetli kullanıcıların veri tabanıyla etkileşime giren uygulamaların güvenlik açığından yararlanarak sistem üzerinde yetkisiz işlemler yapmasına olanak tanıyan bir saldırı tekniğidir. Bu saldırı türü, uygulamaların kullanıcıdan aldığı verileri doğrudan SQL sorgusuna eklemesi ve gerekli kontrolleri ya da filtrelemeyi yapmaması sonucunda ortaya çıkar. SQL Injection, web uygulamaları için en kritik güvenlik açıklarından biridir; çünkü saldırgan, veri tabanını manipüle edebilir, hassas bilgileri ele geçirebilir veya sistemin bütünlüğüne zarar verebilir.
1. SQL Injection Nasıl Gerçekleşir?
Bir web uygulaması, kullanıcıdan gelen veriyi doğrudan veya dolaylı olarak bir SQL sorgusuna eklediğinde, bu girdi üzerinde herhangi bir filtreleme veya doğrulama yapmıyorsa saldırganın eklediği kod parçacığı veri tabanında istenmeyen işlemlerin yürütülmesine neden olabilir. Örneğin, basit bir kullanıcı giriş formunu ele alalım:
SELECT * FROM kullanıcılar
WHERE kullanıcı_adı = ‘KULLANICI_GİRDİSİ’
AND parola = ‘KULLANICI_GİRDİSİ’
Burada KULLANICI_GİRDİSİ
doğrudan sorguya eklenmiştir. Eğer bir saldırgan kullanıcı_adı
alanına ' OR '1'='1
gibi bir ifade girerse sorgu:
SELECT * FROM kullanıcılar
WHERE kullanıcı_adı = ” OR ‘1’=’1′
AND parola = ‘KULLANICI_GİRDİSİ’
şeklini alır. Bu durumda '1'='1'
her zaman doğru olduğu için, ek bir kontrol mekanizması yoksa uygulama tüm kullanıcı kayıtlarını döndürebilir.
Benzer şekilde parola alanına da enjeksiyon ifadeleri eklenerek daha gelişmiş saldırılar gerçekleştirilebilir. Bu örneği SQL Injection’ın temel mantığını anlamanız açısından yazıyorum.

2. Saldırı Yöntemleri ve Amaçları
SQL Injection saldırganın hedeflerine göre farklı yöntemlerle uygulanabilir. Temel amaçlar şunlardır:
-
Veri Sızdırma (Data Extraction):
Saldırgan, veri tabanında yer alan kullanıcı bilgileri, e-posta adresleri, parolalar gibi hassas verileri elde etmek isteyebilir. -
Veri Manipülasyonu (Data Manipulation):
Saldırgan verileri değiştirmek, eklemek veya silmek isteyebilir. Bu, veri bütünlüğünü ciddi şekilde tehdit eder. -
Yetki Yükseltme (Privilege Escalation):
Bazı durumlarda saldırgan, veri tabanında sistem yönetici haklarını (örneğinroot
veyadb_owner
) ele geçirmek isteyebilir. Böylece sunucu üzerinde daha kapsamlı işlemler yürütebilir. -
Sistem Keşfi ve Yan Saldırılar (Lateral Movement):
Eğer veritabanı sunucusu üzerinde farklı servisler ve dosya sistemine erişim mümkünse, saldırgan bu yolla ağa daha derin sızmalar yapabilir.
3. SQL Injection Türleri
3.1 Klasik (Basit) SQL Injection
Kullanıcının girdiği verinin sorguya doğrudan enjekte edilmesi ile ortaya çıkan en temel saldırı türüdür. Filtreleme yapılmayan basit formlar veya URL parametreleri üzerinden kolayca gerçekleştirilebilir.
3.2 Blind (Kör) SQL Injection
Uygulamanın hata mesajlarını veya sorgunun sonuçlarını doğrudan göstermediği durumlarda saldırı “körlemesine” gerçekleştirilir. Saldırgan, örneğin sayfa yanıt süresi veya dönen hata kodları aracılığıyla sorgu hakkında bilgi edinmeye çalışır. Blind SQL Injection, uygulamanın sınırlı geri bildirim vermesine rağmen saldırganın yine de veri tabanı hakkında bilgi edinmesini sağlayabilir.
3.2.1 Boolean Based
Sorgunun doğru veya yanlış olmasına göre farklı çıktılar döndüren bir yönteme dayanır. Saldırgan, “OR 1=1
” gibi ifadelerle sorgunun nasıl değiştiğini küçük ipuçlarından anlar.
3.2.2 Time Based
Sunucunun yanıt verme süresine dayalı bir yöntemdir. Saldırgan, örneğin SQL fonksiyonlarıyla (SLEEP
, WAITFOR
gibi) sunucuyu bekleterek sorgunun doğru mu yanlış mı olduğunu ölçmeye çalışır.
3.3 Error Based SQL Injection
Uygulama veya veri tabanı, saldırganın girdiği hatalı sorgulara dair detaylı hata mesajları veriyorsa, saldırgan bu mesajlardaki bilgilere dayanarak veri tabanı yapısı hakkında fikir sahibi olabilir. Hata mesajlarında tablo veya sütun adları görünebilir.
3.4 Union Based SQL Injection
UNION
ifadesi kullanılarak birden fazla sorgu sonucu birleştirilebilir. Saldırgan, kendi hazırladığı ek sorguları birleştirerek veri tabanından farklı tabloların bilgilerini de elde edebilir.
4. SQL Injection Korunma Yöntemleri
SQL Injection’a karşı en etkili yöntem, kullanıcı girdilerini güvenli şekilde sorguya işlemek ve uygulamaların mimarisini güvenlik odaklı tasarlamaktır. Başlıca korunma yöntemleri şunlardır:
-
Parametreli Sorgular (Prepared Statements) ve ORM Kullanımı:
Geliştirme ortamında ve veritabanına erişim katmanlarında parametreli sorgular (örneğin,PreparedStatement
veya benzeri yapı) kullanmak SQL enjeksiyon riskini büyük ölçüde azaltır. ORM (Object Relational Mapping) araçları da çoğu zaman parametreli sorgular kullanarak kodu daha güvenli hale getirir. -
Doğrulama ve Filtreleme (Validation & Sanitization):
Uygulama katmanında kullanıcıdan gelen veriler mutlaka doğrulanmalı, geçersiz karakterler (örneğin'
,;
,--
gibi) filtrelenmeli veya uygun biçimde kaçırılmalıdır. Ayrıca, beklenen veri tipleri (sayı, e-posta, tarih vb.) net olarak belirlenmeli ve aksi durumda işlenmeden reddedilmelidir. -
Minimum Yetkilendirme (Least Privilege) Prensibi:
Uygulamanın veri tabanı kullanıcısına sadece gerekli yetkiler tanınmalıdır. Örneğin, yalnızca okuma işlemi yapması gereken bir servis için “sadece SELECT yetkisi” verilmesi yeterlidir. Bu sayede SQL Injection gerçekleşse bile yetkinin kısıtlı olması hasarı sınırlar. -
Hazır Güvenlik Kütüphaneleri ve Çatılar (Framework):
Geliştirme yaptığınız dilin veya kullandığınız web çatısının (framework) sunduğu güvenlik kütüphanelerini kullanmak, manuel hata riskini azaltır. Pek çok modern çatı, form doğrulama, veritabanı sorgu yönetimi gibi kritik işleri daha güvenli bir şekilde yönetir. -
Hata Mesajlarını Sınırlama (Custom Error Pages):
Canlı ortamda veri tabanı veya sistem hatalarını kullanıcıya (ve dolayısıyla potansiyel saldırgana) doğrudan yansıtmamaya özen gösterin. Aksi takdirde, saldırgan uygulamanın ve veri tabanının iç yapısı hakkında faydalı ipuçları elde edebilir. -
Güncelleme ve Yama Yönetimi:
Veri tabanı motorunun, işletim sisteminin ve kullanılan diğer kütüphanelerin güncel tutulması gereklidir. Bilinen bir güvenlik açığı, yamalanmamış sistemlerde kolayca kullanılabilir. -
Güvenlik Duvarı ve WAF (Web Application Firewall) Kullanımı:
WAF gibi araçlar, bilinen zararlı sorgu desenlerini filtreleyerek SQL Injection saldırılarını engellemeye yardımcı olabilir. Ancak tek başına WAF çözümü yeterli değildir; uygulama katmanında da güvenli kodlama şarttır.
5. Test ve Tespit Yöntemleri
-
Sızma Testi (Penetration Testing):
Uygulamanın güvenliğini test etmek için profesyonel güvenlik uzmanları, “beyaz şapkalı hacker” teknikleriyle saldırgan bakış açısından uygulamayı denetler. Bu testlerde otomatik araçlar ve manuel teknikler kullanılarak SQL Injection dahil pek çok zafiyet aranır. -
Otomatik Zafiyet Tarayıcıları (Vulnerability Scanners):
Nikto, OWASP ZAP, Burp Suite, Acunetix gibi araçlar, hedef uygulamada yaygın açıklıkları tarayabilir ve SQL Injection için temel testler uygulayabilir. -
Kod İncelemesi (Code Review):
Geliştiriciler ve güvenlik uzmanları, uygulama kodunu gözden geçirerek dışarıdan alınan verilerin nasıl işlendiğini inceleyebilir. Parametreli sorguların doğru kullanımı, gerekli filtreleme ve doğrulama adımlarının varlığı kontrol edilir. -
Log Analizi ve İzleme (Monitoring):
Saldırganlar genellikle sistem dışı kalıplar veya hatalar yaratır. Loglar düzenli olarak incelenirse şüpheli sorgular veya anormal trafik tespit edilebilir.
SQL Injection, veri tabanı ile etkileşime giren tüm uygulamalar için potansiyel olarak yıkıcı bir güvenlik açığıdır. Güvenli bir uygulama geliştirmek için kullanıcı girdilerinin doğrulanması, parametrik sorguların kullanılması, en az yetki prensibinin uygulanması ve düzenli güvenlik testlerinin yapılması kritik önem taşır. Modern web uygulamalarının karmaşıklığı, birden çok katmanda güvenlik mekanizmalarını zorunlu kılar. Sadece bir ya da iki tedbir almak genellikle yeterli değildir; güvenli kodlama alışkanlıkları, sürekli eğitim ve güncel güvenlik yamaları ile desteklenmelidir.
Kısacası, SQL Injection saldırılarını önlemenin yolu, sıkı güvenlik prosedürlerine bağlı kalmaktan geçer. Geliştiricilerin, sistem yöneticilerinin ve güvenlik uzmanlarının koordineli çalışması sayesinde bu saldırı türü büyük ölçüde engellenebilir veya en azından hasarı minimal düzeye indirilebilir.
Konumuzun başına dönersek buna benzer bir olaydan dolayı sunucuda ki tüm veritabanlarında bazı anahtar kelimeleri aratmak zorunda kaldığım için bir bash betiği yazmak zorunda kaldım. Sunucu da bulunan 38 farklı MySQL veritabanında bu anahtar kelimeleri tek tek aratmaya çalışmak çok zahmetli olacağı ve zaman alacağı için doğrudan terminal üzerinden bash betiği ile tüm veritabanlarında kelime aratmak ya da sorgu çalıştırmak en kolayı.
Basit Bash Betiği ile Arama
Aşağıdaki örneği, root
kullanıcısı ve "password"
parolası üzerinden bağlandığınızı varsayarak yazdım. Kendi mysql kullanıcı/parola bilgilerinize göre güncellemelisiniz.
#!/bin/bash
# MySQL bağlantı bilgileri
USER=”root”
PASS=”password”
# Aranacak kelime
SEARCH_TERM=”anahtar_kelime”
# MySQL içerisindeki tüm veritabanlarını listeleyelim
databases=$(mysql -u”$USER” -p”$PASS” -Bse “SHOW DATABASES”)
# Sistem veritabanlarını (mysql, information_schema vs.) atlayabilmek için bir fonksiyon:
is_system_db() {
case “$1” in
“information_schema”|”performance_schema”|”mysql”|”sys”)
return 0
;;
*)
return 1
;;
esac
}
# Elde edilen veritabanları üzerinde gezinme
for db in $databases; do
# Sistem veritabanı ise devam et
if is_system_db “$db”; then
continue
fi
echo “Veritabanı inceleniyor: $db”
# Veritabanındaki tabloların listesini al
tables=$(mysql -u”$USER” -p”$PASS” -Bse “SHOW TABLES IN $db”)
# Her tabloyu kontrol edelim
for table in $tables; do
# Bu tabloda hangi kolonlar var?
columns=$(mysql -u”$USER” -p”$PASS” -Bse “SHOW COLUMNS FROM $db.$table”)
# Kolonları satır satır ele alabilmek için while/read kullanalım
while IFS= read -r col; do
colName=$(echo “$col” | awk ‘{print $1}’) # Kolon adı
colType=$(echo “$col” | awk ‘{print $2}’) # Kolonun veri tipi
# Eğer kolon text veya char türündeyse arama yapmak daha mantıklı
if [[ “$colType” == *”char”* ]] || [[ “$colType” == *”text”* ]] || [[ “$colType” == *”varchar”* ]]; then
# Bu kolonda “anahtar_kelime” geçen satır sayısını bulalım:
resultCount=$(mysql -u”$USER” -p”$PASS” -N -Bse \
“SELECT COUNT(*) FROM \`$db\`.\`$table\` WHERE \`$colName\` LIKE ‘%$SEARCH_TERM%’;” 2>/dev/null)
if [ “$resultCount” -gt 0 ]; then
echo ” -> $db.$table.$colName kolonunda $resultCount kayıt bulundu.”
fi
fi
done <<< “$columns”
done
done
Betik içerisinde bulunan SEARCH_TERM=”anahtar_kelime”
anahtar_kelime yazan kısma tüm veritabanlarında aratmak istediğiniz kelimeyi yazabilirsiniz. Betiği ana dizinde bulunan “root” klasörü içerisine anahtar_arama.sh ismi ile oluşturunuz.
Oluşturduğumuz betiğe chmod +x anahtar_arama.sh komutu ile çalışma izni verelim.
./anahtar_arama.sh
komutu ile betiğimizi çalıştıralım.
Eğer betiği sadece tek veritabanında kullanmak istersek şu şekilde güncelleyebiliriz.
#!/bin/bash
USER=”root”
PASS=”password”
DB=”veritabani_ismi”
SEARCH_TERM=”anahtar_kelime”
tables=$(mysql -u”$USER” -p”$PASS” -Bse “SHOW TABLES IN $DB”)
for table in $tables; do
columns=$(mysql -u”$USER” -p”$PASS” -Bse “SHOW COLUMNS FROM $DB.$table”)
while IFS= read -r col; do
colName=$(echo “$col” | awk ‘{print $1}’)
colType=$(echo “$col” | awk ‘{print $2}’)
if [[ “$colType” == *”char”* ]] || [[ “$colType” == *”text”* ]] || [[ “$colType” == *”varchar”* ]]; then
resultCount=$(mysql -u”$USER” -p”$PASS” -N -Bse \
“SELECT COUNT(*) FROM \`$DB\`.\`$table\` WHERE \`$colName\` LIKE ‘%$SEARCH_TERM%'”)
if [ “$resultCount” -gt 0 ]; then
echo “$DB.$table.$colName -> $resultCount satır”
fi
fi
done <<< “$columns”
done
Betikte bulunan DB=”veritabani_ismi”
SEARCH_TERM=”anahtar_kelime”
satırlarını kendi veritabanı isminizi ve anahtar kelimeniz ile değiştirmelisiniz.
Betiği Özelleştirme ve Sonuçların Detaylandırılması
-
Sadece kaç kayıt olduğunu değil, içeriklerini de görmek isterseniz
COUNT(*)
yerine*
seçip veriyi direkt çekebilirsiniz. Ancak çok büyük tablolar ve çok fazla eşleşme varsa, çıktı çok büyük olacak ve tarama zaman alacaktır.
SELECT * FROM `$DB`.`$table` WHERE `$colName` LIKE ‘%$SEARCH_TERM%’;Sistem veritabanlarını atlamak çoğu zaman gereklidir, çünkü
information_schema
,performance_schema
,mysql
gibi veritabanlarının içindeki tablolar genellikle yapı bilgilerini barındırır, gerçek uygulama verisi içermez.
Performans İpuçları
-
Tüm tablolar ve tüm kolonlarda
%anahtar_kelime%
şeklinde bir LIKE ifadesi kullanmak, indeksleri kullanmayı zorlaştıracağından büyük bir veritabanında oldukça yavaş olabilir. -
Çok sayıda veritabanı veya çok büyük tablolarınız varsa, komutu ekran yerine bir dosyaya (
>> results.txt
) yönlendirip uzun vadede incelemek mantıklı olabilir. -
Eğer metin aramanızı hızlandırmak istiyorsanız, FULLTEXT indeks kullanılan kolonları hedefleyebilir veya aramayı daraltabilirsiniz; fakat bu, LIKE sorgularına göre ek yapılandırma gerektirir.
Bu şekilde bir betik veya basit bir döngü yardımıyla “anahtar_kelime” kelimesini tüm veritabanlarında, tüm tablolar ve text tabanlı kolonlarda arayabilirsiniz.
Umarım bana yardımı olduğu gibi sizlere de yardımı olmuştur.
Başka bir yazı da görüşmek üzere kendinize iyi bakın.