Categories
OWASP PortSwigger Vulnerability

SQL Injection – Lab #12 Blind SQL Injection with Conditional Errors

Koşullu Sorgularda Hataları Yorumlayarak Blind SQLi Sömürme

Bir önceki çalışmamızda uygulama üzerindeki cookie değerine koşullu SQL sorguları yazdık ve normal durumda olması gereken davranış oluyor mu kontrol ettik ve Blind SQLi olduğunu tespit edip istediğimiz sorguları göndererek kullanıcı adı ve parolaya ulaştık.

Fakat her zaman bu kadar rahat olmayabilir. Requestte giden cookie değerini bozmadan çalışabilecek basit bir SQL satırını koşullu halde yazdığımızda sorgumuz çalışmayabilir. Bu durumda daha önceki örneklerde olduğu gibi farklı bir veritabanıyla karşı karşıya olabileceğimizi düşünmeliyiz.

Bu lab bizlere Oracle veritabanlarında CASE WHEN, THEN TO_CHAR ve ROWNUM komutları ile sorgu nasıl yazılır onu gösterecek. Bunların hepsini bilmek zorunda değilsiniz. Ben de test esnasında bilemem fakat arama motorlarında neyi search edeceğinizi bilmek testi başarı ile yapmanızı sağlayacaktır.

Uygulamamızı açıyoruz ve ilk giden paketimizi Burp Suite ile araya girerek durduruyoruz. Denemeler gerçekleştireceğimiz için Repeater’a atıyoruz. Teste “TrackingId” değişkenine tek tırnak ( ‘ ) atarak başlıyoruz.

TrackingId değişkenine tek tırnak ( ‘ ) atınca bozulan sorgu ekran görüntüsü

Açtığımız ve değeri bozan tek tırnağı ( ‘ ) kapadığımızda ise sorgu sorunsuz çalışıyor. Bu durum Blind SQLi açığının olduğu bilgisini kuvvetlendiriyor.

2 tane tek tırnak ( ‘ ) gönderilen sorgu sonuç ekran görüntüsü

Bu durumda 2 tane tek tırnak ( ‘ ) arasına yazacağım bir SQL komutunun çalışmasını beklemekteyim. SELECT komutu ile boş bir sütun getirmesini istedik. 

' (select ' ') '

Yukarıdaki komut basit ve çalışabilir bir komuttur. Fakat uygulama üzerinde çalışmamıştır.

SQL sorgunun hata ekran görüntüsü

Bu durumda daha önceki pratiklerde öğrendiğimiz gibi veritabanının farklı olma ihtimalini göz önünde bulundurarak denemeler yapıyoruz ve Oracle veritabanları için kullanılan DUAL tablosunu çekmek istiyoruz. Eğer olumlu bir sonuç alamazsak diğer veritabanlarının sorgularını deneyeceğiz.

' UNION SELECT ' ' from dual-- '
Oracle veritabanı kullanıldığının tespit edildiği sorgu ekran görüntüsü

Veritabanımızın Oracle olduğunu tespit ettik. Gönderdiğimiz sorguların çalıştığını da gördük. Bizim için kullanıcı tablosu ve içerisindeki kullanıcı bilgileri oldukça önemli. Kullanıcı tablolarının genelde ismi “users” olduğundan şimdi böyle bir tablo olup olmadığını tespit edebilecek sorgular göndereceğiz.

' UNION SELECT ' ' from users-- '
Users tablosu için gönderilen sorgunun 200 OK ekran görüntüsü

“Users” tablosunun varlığını tespit edebildik. Şimdi ise içerisinde Administrator diye bir kullanıcı var mı buna bakmalıyız. Daha önceki çalışmalarımızda olduğu gibi hemen “users” tablosunun “username” değerinde “administrator” kullanıcısı çağırma sorgusu yapacağız.

' UNION SELECT ' ' from users where username='administrator'-- '
Administrator kullanıcısı için 200 OK ekran görüntüsü

Sorguyu gönderdiğimizde 200 OK ekran görüntüsü aldık. Bir de olmayan bir kullanıcı deneyelim bakalım nasıl davranacak.

bilisimcikiz kullanıcısı için 200 OK ekran görüntüsü

“Administrator” kullanıcısının var olup olmadığından emin değiliz ama “bilisimcikiz” kullanıcısının olmadığından eminiz 😄 Bir terslik var. Burada labdan kopya çekebiliriz ya da arama motorlarında Oracle veritabanlarında koşullu sorgular nasıl oluyor araştırarak bulabiliriz. Burada biraz matematik zekası iyi olacaktır. Öyleyse, değilse, eşitse, veya ya da ve gibi komut ve operatörlere hakim olmak gerekir. Yine tekrar ediyoruz bunları ezberlemek zorunda değilsiniz. Çünkü test ettiğiniz sistemler sürekli olarak çeşitlilik gösterecektir. Önemli olan analitik düşünebilmek. Oracle veritabanında bir şeyin durumunu öğrenmek için CASE WHEN kullanılmaktadır. Bu if-else gibidir. CASE WHEN 1=1’e THEN yani şu işlevi yap XXX END gibi yazım türleri bulunmaktadır. Bu bilgidir. Bunu yorumlayamayız. Bilmemiz gerekir. Bkz.

' UNION SELECT CASE WHEN (username='administrator') THEN to_char(1/0) ELSE NULL END FROM users--

Eğer “users” tablosundaki “username” sütunu “administrator” değerine eşitse 1’i 0’a böl değilse boş bırak dedik aşağıdaki sunucu hatası ekran görüntüsünü aldık. Bu da “administrator” kullanıcısı var demek. 

username sütunun administratore eşit olması durumunda bölme işlemi yapıldı ve sunucu hatası alındı ekran görüntüsü

Koşulu değiştirdiğimizde çıktıya bakalım.

' UNION SELECT CASE WHEN (username='administrator') THEN to_char(1/1) ELSE NULL END FROM users--
username sütunun administratore eşit olması durumunda bölme işlemi yapıldı 1, 1e bölünebildiği için 200 OK ekran görüntüsü

Kullanıcımızı tespit ettiğimize göre artık parolası için sorgu gönderebiliriz. Burada daha önce kullandığımız Substring() yöntemi kullanacağız ama Oracle veritabanlarında değişiklik gösterdiğini unutmamak gerekir. Bkz.

Aşağıdaki sorgu ile parolamızın uzunluğunu öğreniyoruz. 20 değerine kadar hep hata aldık. 20’de 200 OK aldık. Eğer parola 20den büyükse 1’i 0’a böl, değilse NULL yani boş döndür. Parola 20’den büyük olmadığı için bölme işlemini yapmadı ve else kısmına atladı NULL 200 OK döndü.

Rakamın 19 olması durumunda parola 19’dan büyük ise 1’i O’a böl, değilse NULL yani boş döndür. Parola zaten 20 karakter ve 19’dan büyük olduğu için bölme işlemini yapıyor ve 1, 0’a bölünmediği için hata ekran görüntüsü alıyoruz. Bu da bize parolamızın 19’dan büyük olduğunu doğruluyor. 

' UNION SELECT CASE WHEN LENGTH (password)>20 THEN+to_char(1/0) ELSE NULL END FROM users WHERE username='administrator'--'
' UNION SELECT CASE WHEN SUBSTR (password,1,1)='a' THEN to_char(1/0) ELSE NULL END FROM users WHERE username='administrator'--'
İ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ü
0edvsl74sv0z3h51cxqk // Parola

Leave a Reply

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