Categories
OWASP PortSwigger Vulnerability

SQL Injection – Lab #11 Blind SQL Injection with Conditional Responses

Koşullu Yanıtlar İle Blind SQLi Zafiyeti

Blind SQLi zafiyetinde gönderilen sorgularda hata ekranı göremeyiz. Uygulamanın davranışlarını göz önünde bulundurup ona göre SQL sorguları göndererek deneme yanılma yöntemi ile veritabanına erişim olup olmadığını kontrol ederiz. Yukarıdaki örneklerde olduğu gibi satır ve sütunları öylece sıralama mümkün değildir. Bu nedenle Blind yani kör atış, okunaksız gibi isimlendirilir.

Lab bize uygulamayı ziyaret ettiğimizde “Welcome back!” mesajı aldığımızı söylüyor. Lab’ın açıklamasından cookiede bir zafiyet olduğunu biliyoruz. “Users” diye bir tablo olduğunu ve burada “username”, “password” sütunlarının olduğundan bahsediyor. Bizde Blind SQLi zafiyeti istismar ederek bu tablodaki bilgilere erişim sağlayacağız.

Lab uygulama ekran görüntüsü

Uygulamayı ziyaret ettiğimizde daha önceki lablarda olan uygulamalara benzer alanları olduğunu görüyoruz. Cookie de zafiyet olduğunu biliyoruz bu nedenle nasıl göründüğüne tarayıcımıza eklediğimiz bir eklenti yardımı ile bakıyoruz. Buna Burp Suite’den de bakabilirdik. Kullandığımız eklentiye buradan ulaşabilirsiniz.

Çerezlerin (cookie) görüntülendiği eklenti ekran görüntüsü

İki tane cookie olduğunu görüyoruz. Bir tanesi “session” diğeri ise “TrackingId”. “TrackingId” isminden anlaşılacağı gibi izleme kimliği oluyor. Yani biz uygulamayı ilk ziyaret ettiğimizde alıyoruz. Henüz sayfada “Welcome back!” diye bir ifade yok fakat sayfalar arasında gezdiğimizde örneğin “My Account” butonuna tıkladığımda “TrackingId’mi” uygulama tanıyacağı için geri geldimi düşünecek ve “Welcome back!” diyecek. Eğer biz cookiede zafiyet olduğunu bilmeseydik veritabanı ile iletişim kurduğunu düşündüğümüz tüm değişkenleri incelemek durumunda kalacaktık.

Lab uygulama sayfaları arası gezinme “Welcome back!” ifadesinin çıktığı ekran görüntüsü

Uygulamayı ziyaret ettik ve bir izleme kimliği oluştu. Bu izleme kimliği artık veritabanına kayıtlı ve ürün kategorilerinde ya da diğer menülerde gezerken uygulama tarafından eşleştirilip sağ üst köşede “Welcome back!” yazısı olarak gelecek. Güzel! Şimdi biz burada başka neler çağırabiliriz? Ya da bu veritabanına yazıldığını bildiğimiz izleme kimliği ile neleri çağırabiliriz ona bakacağız. Başlangıçta istek gittiğinde aldığımız sonuç ile değiştirdiğimizde giden sonucu inceleyeceğiz.

İzleme kimliğinin çalıştığı sorgu ekran görüntüsü

“TrackingId’nin” veritabanından nasıl sorgu çektiğini hayal etmeliyiz. Etmeliyiz ki benzer sorgular gönderebilelim. Daha önceki lablarda SELECT ile birçok sorgu çağırdık.

select tracking_no from tracking_tabloismi where trackingId = 'X4e2dFXO8H7goMtn' // buradaki tracking_no, tracking_tabloismi tamamen uydurma muhtemelen uygulama üzerinde farklı isimlerle tutuluyordur. Buradaki amacımız nasıl sorgulandığını şekillendirmek.

İzleme kimliğinin sonuna farklı bir harf ekledik ve yeniden istek yaptığımızda bu sefer “Welcome back!” yazısının gelmediğini gördük. Bu da “TrackingId” değişkenindeki zafiyeti doğrulamamızı sağladı.

Veritabanında olmayan “TrackingId” gönderilmesi sonucu alınan çıktı ekran görüntüsü

“TrackingId” değişkenine bazı SQL sorguları yazarak uygulamanın nasıl davrandığını gözlemliyoruz.

'+and+1%3d1-- // trackingId devamına ekliyoruz.

1=1 doğru bir ifade olduğu için ve izleme kimliğide daha önce veritabanında olan bir bilgi olduğu için yeniden geldiğimizi düşündü ve “Welcome back!” yazısını gömüş olduk.

Koşullu sorgu gönderilip veritabanı ile eşleştirme yapılan sorgu ekran görüntüsü

1=0–‘ yazsaydık 1, 0’a eşit olmadığı için veritabanında izleme kimliği olsa bile dönmeyecektir. Çünkü arada “and” ifadesi bulunmaktadır.

Koşullardan birinin sağlanmaması durumunda alınan ekran görüntüsü

Eğer “and” değil de “or” deseydik. Şartlardan birini sağladığımız için yine “Welcome back!” yazısını görecektik. Bu testlerde uygulama üzerinde SQLi çalıştırabildiğimizi desteklemektedir.

“Or” ile sorgu denemesi ekran görüntüsü

SQL sorgusu çalıştabildiğimizi ve eğer veritabanında istediğimiz veri varsa “Welcome back!” yoksa bir şey yazmadığını biliyoruz. Şimdi ise “users” tablosunun olup olmadığını sorgulamalıyız. SQL sorgularda LIMIT kullanma için bakınız.

'+and (select 'a' from users LIMIT 1)='a'-- // Burada users tablosunda içinde a harfi olanları seç ve bir tane döndür gerisini yorumla (--) diyoruz. a yerine tahmini herhangi bir şey yazabilirdiniz. LIMIT kullanmamızın nedeni ise içinde a harfi geçen 100lerce kayıt olabilir. Hepsini okumasına gerek yok. 
“Users” tablosunun tespiti için kullanılan sorgu ekran görüntüsü

Buradan çıkaracağımız sonuç “users” diye bir tablonun var oluşudur. Çünkü veritabanı eğer tanıdık bir “TrackingId” gönderirsek ekrana “Welcome back!” yazıyordu.

 and (select username from users where username='administrator')='administrator'--
“Administrator” kullanıcısının “Users” tablosunda olup olmadığının sorgulandığı ekran görüntüsü

Bu sorgudan “administrator” kullanıcısının veritabanında olduğunu tespit etmiş oluyoruz. Biraz daha anlaşılması için sorguyu yorumlayacağız. “TrackingId’den” sonra yazılı olan pgF1fkWgzjwWPM1D çerezi zaten var olduğunu bildiğimiz çerezimiz “and” ile diğer bilgiye koşulluyoruz. Parantez içinde yazılan olan mavi çerçeveli  kısmı 1 sayısı gibi hayal edelim. kırmızı çerçeveli olan = ifadesi yeşil çerçeveli olanı da yine 1 ifadesi olarak hayal edelim. Günün sonunda “TrackingId=gerçek_cerez ve 1=1” doğru bir ifade olduğu için ekranda “Welcome back!” yazdığını göreceğiz.  Administrator kullanıcısı veritababında “users” tablosunun “username” sütununda yer aldığı için yazdı.

Bir sonraki aşamada parolanın değerini bulmalıyız. Parolayı direkt olarak kullanıcı ismi gibi tahmin etmemiz oldukça zor. Göndereceğiniz sorguda 1. harfi a ise, b ise , c ise diyerek bütün alfabeyi sıra ile şartlı sorgu olarak gönderip parolayı bulabiliriz. Fakat bu eziyet parolanın uzunluğuna göre değişecektir. Bunun yerine önce parolanın uzunluğu bulmak daha mantıklı olacaktır. SQL sorgularda bir şeyin uzunluğu için LENGTH kullanılıyor. Bkz.

' and (select username from users where username='administrator' and LENGTH(password)>19)='administrator'--
LENGTH ile parola karakter sayısının öğrenildiği sorgu ekran görüntüsü

Parolanın karakter sayısını öğrenmek için Burp Suitein nimetlerinden yararlanıyoruz.

İsteğin Intruder ekran görüntüsü

Reguestimizi sağ click yapıp Intruder’a attık. Önce tüm seçili olanları Clear ettik. Daha sonra sadece sayının döndüğü kısmı seçip Add yaptık ve Payloads sekmesine geçtik. 1’de 50’e kadar 1er 1er değiştir yazdık ve sonra “Start Attack” dedik.

Burp Suite Intruder Payloads sekmesi ekran görüntüsü
Start Attack sonrası gelen Burp Suite ekran görüntüsü

Çıktıyı incelediğimizde LENGTH değerinin değiştiği yer kadar karakter olduğunu gördük. Şimdi karakter sayısını bildiğimiz için brute force yöntemi ile parolayı tespit edeceğiz. Substring() yöntemi kullanacağız ve aşağıdaki sorgu olan Request değerini Intruder’a göndereceğiz.

' and (select substring(password,1,1) from users where username='administrator')='a'--
İsteğin Intruder ekran görüntüsü
Burp Suite Intruder Payloads Set 1 sekmesi ekran görüntüsü
Burp Suite Intruder Payloads Set 2 sekmesi ekran görüntüsü
Filtreleme yaparak sadece “Welcome back!” çıktısı basan isteklerin ekran görüntüsü
Parola karakterlerinin göründüğü ve Response sekmesinde “Welcome back!” yazısı ekran görüntüsü
Burp Suite ile tespit edilen Administartor kullanıcısı parola ekran görüntüsü
zr5s12bbjgslg9fa4aj8 //Parola
Lab tamamlama ekran görüntüsü

Kullanıcı adımızı zaten biliyorduk. Elde ettiğimiz parola ile girip yapıp labı tamamlıyoruz.

Leave a Reply

Your email address will not be published. Required fields are marked *