SQL Injection With WebShell Upload
- SQL 101
- SQL Injection Zafiyetinin Keşfi
- SQL Injection Zafiyetinin Sömürülmesi
- SQL Injection Zafiyetinin Otomatize Araçlarla Sömürülmesi
- SQL Injection Zafiyetinin Kapatılması
SQL 101
show databases = Veritabanı dosyalarını göstermek için kullanılır.
use veritabanİsmi = Kullanılacak olan veritabanı ismini belirlemek için kullanılır.
show tables = Veritabanında bulunan tabloları görüntülemek için kullanılır.
select = Tablo da bulunan kayıtları görüntülemek için kullanılır. (* ile tablonun tüm sütunlarının gösterilmesi sağlandı. from ile tablo ismi belirtildi.)
insert into = Veritabanına kayıt eklemek için kullanılır. (Tablo adı belirtildikten sonra eklenecek olan sütunlar belirlenir. Values kısmında ise sütunlara denk gelecek olan değerler atanır.)
information_schema = Veritabanı ile ilgili veritabanlarına ulaştığımız tablo diyebiliriz.
concat = Select ile gelen birden fazla alanı tek bir alana birleştirmemizi sağlar. Örnek olarak bir where deyimiyle belirli bir id değeri olan verilerin getirilmesini istiyorsunuz. Farklı bir id değerini de sorguya eklemek için kullanılır. Bir where deyiminde 2 adet id değeri sorgulayınca syntax hatası alınıyor.
concat kullanarak 2 id değeri için sonuç döndürülecek.
SQL Injection Zafiyetinin Keşfi
Web uygulamamızda sayfalara tıkladıkça sayfaların id numarasına göre getirildiği gözlemlenmiştir.
id değerinin yanına syntax ı bozması amacıyla tırnak işareti attığımızda veritabanı hatasıyla karşılaşmaktayız.
Matematiksel işlem yapılarak id değeriyle oynamaya devam ediyoruz.
2–1 payload’unu yolladıktan sonra yine 1. sayfanın gelmesinden matematiksel işlemin MYSQL tarafından yapıldığı gözlemlenmiştir.
Şimdi ise sahneyi UNION komutuna bırakıyoruz. İlk olarak sütun sayısını tespit etmeye çalışacağız. Çünkü birleştirilmeye çalışılan 2 veritabanının sütun değerlerinin eşleşmesi gerekmektedir.
Sütun sayısı eşleşmediği zaman hata mesajı gelmektedir.
Sütun sayısı doğru olarak verildiği zaman verileri getirdiği gözlemlenmiştir.
4 adet sütunumuz olduğunu tespit ettiğimize göre bu sütunları kullanarak veritabanından bilgiler elde etmeye çalışalım.
Yukarıda bahsettiğimiz information_schema üzerinden veritabanı ile ilgili verileri elde edip admin paneline erişim sağlayamaya çalışacağım.
picture veritabanı içerisinde users tablosunda kritik bilgiler olabileceğinden içerisinde ki concat kullanarak verileri okuyacağım. Burada veritabanı ismi users hemen bitişiğinde bulunan ise tablo adı olarak gelmektedir. Arasına noktalama işareti konularak okunması kolaylaştırılabilinir.
Sütun adlarını öğrendikten sonra sütunlarda bulunan değerleri çağırarak kullanıcı adı ve parola değerlerimizi elde edeceğiz.
Parola değerinin hash li olarak tutulmuştur. Fakat parolanın cleartext halini bulabiliriz. Bunun için john, hashcat gibi programlar kullanılabilinir. Ya da https://crackstation.net/ adresinden kontrol edilebilinir.
Parola bilgisini elde ettik. P4ssw0rd şimdi bunu SQLMap yardımıyla bulalım.
SQLMap ile Veritabanına Erişim
- — dbms = Veritabanından verileri çekmek için kullanılır.
- — level = Saldırının gücünü belirlemede kullanılır. (1–5) Varsayılan : 1
- — risk = Saldırının gücünü belirlemede kullanılır. (1–3) Varsayılan : 1
- -d = Doğrudan veritabanı bağlantısı için kullanılır.
- -u , — url = Hedef adres verilmek için kullanılır.
sqlmap -u “http://192.168.2.133/cat.php?id=1" — risk=3 — level=3 — dbs
komutu ile veritabanı isimleri getirilmesi sağlanmıştır.
sqlmap -u “http://192.168.2.133/cat.php?id=1" — risk=3 — level=3 -D photoblog — tables
Çıktıdan photoblog veritabanı seçilerek içerisinde bulunan tablolar çağrılmıştır.
Tablolardan kullanıcılar çekilerek parola bilgisi elde edilmeye çalışılmıştır. Veritabanında parolalar MD5 formatında tutulduğundan dolayı çıkan hash değeri john, hashcat gibi programlar yardımıyla ya da crackstation gibi ortamlarda karşılığı araştırılabilinir.
Basit parola kullanıldığından dolayı sqlmap ile verilen wordlist ile eşleşen değer var mı ? diye kontrol edilmiştir.
Elimizde admin panelinin kullanıcı adı parolası bulunmaktadır. Saldırı yüzeyimizi genişlettiğimizden dolayı admin panelini keşfederek saldırının etki alanını genişletmeye çalışacağız.
Yönetim Paneline Erişim WebShell
Kullanıcı adı ve parola bilgisiyle yönetim paneline erişildi. New picture kısmı hemen gözüme çarptı. Yeni bir fotoğraf eklenirken bir Webshell atarak sistem tamamen ele geçirilebilinir mi? Bunu deneyeceğim.
Ayarları yaptıktan sonra webshell imizi yüklüyoruz.
Fakat PHP uzantılı içeriklere karşı bir önlem alındığını görüyoruz.
Burada en basit yöntem olarak blacklist olarak bir önlem alınmışsa yanına versiyon bilgisi yazılarak atlatılabilinir.
Şimdi yeni dosyamızı yüklemeyi deneyelim.
Başarılı şekilde dosyamız yüklendi. Şimdi dosyamız üzerinden sunucu üzerinde komut çalıştırmayı deneyelim.
cmd parametresi ile ls komutunu gönderdiğimiz komut satırında gibi komut çalıştırabiliyoruz. Sunucu içerisinde kritik bilgilere erişilerek saldırı yüzeyi arttırılabilinir. Yetki yükseltilebilir.
Web uygulamasında bulunan kodlara erişilebildiğinden farklı zafiyetlerde ortaya çıkarılabilinir.
SQL Injection Zafiyetinin Kapatılması
1-) Uygulamamızda zafiyetin oluşmasının temel nedeni kullanıcıdan alınan id değerinin değiştirilmesidir. id değeri manipüle edilerek sunucuya kadar ele geçirildi. Kullanıcıdan alınan değerler uygulamalarımızın olmazsa olmazıdır. Fakat kullanıcıdan alınan değerlere güvenilmemelidir.
$id =
$_GET[‘id’];
$query = "SELECT * FROM users where id=$id";
Bu şekilde kullanıcıdan değer alınırsa kullanıcıdan gelen 1; DROP TABLE users; payload ı ile sistem de bulunan kullanıcı tablosu silinebilir.
Burada query yerine bir yer tutucu da kullanılacak olan SQL cümlesi tanımlanırsa id değişkeni de belli değişken türüne atandıktan sonra sorgumuza eklenirse güvenli bir yapı elde edilmiş olunur.
db->prepare(“SELECT * FROM users where id=?”);
$db->execute($data);
2-)r. SQL ifadesindeki her parametre değişkene atanmalıdır. Atama işlemi sonrası yordam çalıştırılıp sonrasında kapanır.
$stmt = $mysqli->prepare(“INSERT INTO urun VALUES (?, ?, ?)”);
$stmt->bind_param(‘123’, $kullanici_no, $urun_ad, $urun_yol);$kullanici_no = ‘admin’;
$urun_ad = ‘test’;
$urun_yol = “administrator”;$stmt->execute();
$stmt->close();
3-) Sunucu tarafında dışarıya açık bir veritabanı uygulamasında kullanılmayan SQL komutlarının yasaklanmasıyla sıkılaştırma yapılabilir. Sadece sıkılaştırma yapmak yetersiz olacaktır. Saldırgan veritabanın da bulunan verilere erişebilir. Fakat veritabanını silemez gibi bir durum ortaya çıkmaktadır.
Kaynakça
https://docs.microsoft.com/
https://www.php.net/
https://pentesterlab.com/