S.A Arkadaslar.
Buffer Overflow
hazirlayan: Bug Researchers
Buffer Overflow (Arabellek Tasimi)
Buffer Overflow’larin ilk ortaya çikma tarihi 1970’lere dayaniyor.Bu isle ugrasan bir çok kisi (hepsi yurt disindan) bu konuda dökümanlar yazmistir fakat bu dökümanlarin Türkçesi anca 2000’li yillarda Türkiye’ye gelmistir.
Buffer Overflow dedigimiz sey hatali kodlanmis bir programin disaridan bir etkiyle belleginin tasmasina neden olmaktir.Daha açarsak sinir kontrolü yapilmamis bir degiskenine alabileceginden daha fazla veri atanirsa program bellek hatasi verir ve bu hatayi kullanarak özel olarak hazirlanmis bazi kodlar sayesinde programin akisi degistirilebilir.Bunun en güzel örneklerinden biri daha 1.5 seneyi doldurmamis Sasser Solucanidir.Bu solucan Windows isletim sisteminde sürekli çalisan LSASS.EXE adli dosyada bulunan bir Buffer Overflow hatasi sayesinde milyonlarca makinaya bulasabildi.
Bu LSASS.exe nin asil görevi (Local Security Authentication Server) Windows un kulanici islemlerinin güvenligini saglamak ve kullanici izinlerini düzenlemekti.Fakat Windows 2000 ve XP yüklü makinelerde bu dosyanin kullandigi bir DLL dosyasinda Buffer Overflow tesbit edildi.( (LSASRV.DLL).Bu sayede virüs 445 inci porta baglanip, programa istedigi islemleri yaptiriyordu.Daha sonra da LSASS.EXE kapatiliyordu ve 1 dakika içinde de server a reset atiliyordu.
Kisacasi Buffer Overflow Exploiting bir programdaki programlama hatalarini kullanarak o programin degiskenlerine ve program akisina disaridan erismeye denir.
Bu tür bir saldiri yöntemini engellemenin iki çesit yolu oldugunu söleyebiliriz:Birincisi eger programi gelistiren firma yada kisi bizsek Buffer Overflow hatalarini engellemek için alt seviye bellek fonksiyonlarindan ve sinir kontrolü yapmayan degisken islemlerinden olabildigince kaçinmaliyiz.Örnegin C dilinde, iki string tipinde degiskeni birbirine kopyalamak için kullanilan strcpy() fonksiyonu bu tür buffer overflow hatalarina gebedir.Çünkü birinci string i ikinci string e kopyalar fakat sinir kontrolü yapmaz.Yani eger biz degiskenlerden herhangi birinin büyüklügünü statik olarak girmissek bu programda bellek tasmasina yol açacaktir.
Örnegin asagidaki C programinda çok basit bir buffer overflow görülmektedir:
int main(int argc, char *argv[])
{
char Buffer1[4];
char * Buffer2;
Buffer2 = AAAAOverFlow ;
strcpy(Buffer2,Buffer1); // iste tam burada Buffer Overflow mevcuttur.
return 0;
}
Kodda görüldügü gibi ilk 4 byte tan sonra yazilan OverFlow kelimesi tam anlamini yansitmaktadir.Bu pogram çalistiginda Buffer Overrun hatasi verecektir.Ama OverFlow sözcügü program stack inin kritik kisimlarini etkileyecektir.
Peki bu exploitleri nasil kullaniriz dediginizi duyar gibiyim. Bu exploitler yazildigi dile göre ilk derlenir sonrada yorumlanir.En çok C Dili kullanilarak yazilmaktadir.
Bu tür exploitleri derlemek için ilk önce gcc komutlarini kullanmayi bilmeniz gerekmektedir.
Gcc komutlari Windows sistemlerde kullanilamiyor isletim sisteminizin Linux tabanli olmasi gerekmektedir.Bunun için bilgisayariniza sanal sistem kurup Back | Track 2 ile rahatlikla derleyebilirsiniz.
Özet olarak gcc komut kullanimi su sekildedir;
Linux Console;
Gcc exploit.c –o exploit = buradaki ilk exploit.c = exploitin ismi ve uzantisi –o’dan sonraki exploit derlendikten sonraki adi bunu ne isterseniz onu yapabilirsiniz.
Çalistirmak için
./exploit = bu komuttan sonra sizden ip path vs… isteyecektir gerekli olanlari dogru verdiginizde exploit uygulanmis olacaktir
Ayrica Arabellek Tasmalarini, Saldiriya Açik Olup Olmadiginiz ve Korunma Yollarini Su Sekilde Siralayabiliriz;
Yigit (Stack) Tasmasi
-Yigit tasmalari, “arabellek” tasmalarinin en iyi anlasilan ve en yaygin formudur. Yigit tasmalarinin esaslari basittir:
Iki arabellek vardir; keyfi saldiri girdisini barindiran kaynak arabellek ve saldiri girdisini içine alamayacak kadar küçük olan hedef arabellek. Ikinci arabellek yigit üzerinde olmali ve yigit üzerindeki fonksiyon geri dönüs (return) adresine yakin denebilecek bir yerde olmalidir.
-Kusurlu kod, ilk arabellegin, ikinci arabellek için çok büyük oldugunu kontrol etmez. Düsman veriyi, ikinci arabellegi ve fonksiyon dönüs adresini yok edecek sekilde ikinci arabellege kopyalar,
-Fonksiyon geri döndügünde, CPU yigit çerçevesini (stack frame) açar ve geri dönüs adresini yigittan alir. Geri dönüs adresi simdi kirlenmistir (degistirilmistir) ve saldiri kodunu göstermektedir.
-Uygulamada daha önce çagiran tarafa (previous caller) geri dönmek yerine saldiri kodu çalistirilir.
Saldiriya açik olup olmadiginizi anlama (yollari)
Eger programiniz:
-Arabellek tasmasindan mustarip olan bir dille yazilmis veya bu diller ile yazilmis baska bir programa bagli ise ve
-Kullanicidan girdi aliyorsa VE
-Girdiyi aritmiyorsa VE
-Kanarya degerleri (canary values) kullanmadan yigit üzerinde ayrilmis degiskenler kullaniyorsa
Uygulama büyük ihtimalle saldiriya açiktir.
Kendinizi koruma (yollari)
-Çalistirilmayan yigitlar kullanabilen sistemler üzerinde programinizi kurun ve isletin (AMD ve Intel x86-64 çipleri ile ilgili 64 bitlik isletim sistemleri (XP SP2 - hem 32 hem 64 bitlik-, Windows 2003 SP1 - hem 32 hem 64 bitlik-, AMD ve
x86-64 islemciler üzerinde 32 ve 64 bit modalarinda Linux 2.6.8 sonrasi,
OpenBSD - w^x özellikli Intel, AMD, Sparc, Alpha ve PowerPC-,
noexec_user_stack özelligi çalisir durumda olmayan Solaris 2.6 ve sonrasi) ???)
-C ve C++ disindaki programlama dillerini kullanin
-Çok uzun girdileri önlemek için kullanici girdilerinin geçerliliklerini denetleyin ve önceden anlasilmis sartlara (mesela A-Z, a-z, 0-9, v.b.) uyduklarina emin olmak için degerleri kontrol edin.
-Eger C ve C++ dillerinde yazilmis isletim sistemi ve yardimci programlar kullaniliyorsa, en düsük erisim hakki prensibini (the principle of least privilege) kullandiklarindan emin olun, yigit ve yigin (heap) tasmalarina karsi koruyucu derleyiciler kullanin ve sistemi yamalari ile güncel tutun.
Yigin Tasmasi
Yigin tasmalari problemlidirler ve “çalistirilmayan yigitlari” (no executable stacks) ayarlayabilen CPUlar tarafindan tam olarak korunmazlar. Yigin, uygulama yürütme süresi (application run time) tarafindan lokal olarak tanimlanmis degiskenler için ayrilmis bir bellek alanidir.
function foo(char *bar) {
char thingy[128];
…
}
bar yigit üzerinden geçirilmisken (passed) thingy için yer, yigin üzerinde ayrilmistir.
Tasma yollari yigit tasmalarindakiler ile tamamen ayni sekildedir.
Saldiriya açik olup olmadiginizi anlama (yollari)
Eger programiniz:
-Yigin arabellek tasmalarindan mustarip olan bir dille yazilmis veya bu diller ile
yazilmis baska bir programa bagli ise VE
-Kullanicidan girdi aliyorsa VE
-Girdiyi aritmiyorsa VE
-Kanarya degerleri kullanmadan yigin üzerinde ayrilmis degiskenler kullaniyorsa
uygulama büyük ihtimalle saldiriya açiktir.
Format Dizgisi
Format dizgi arabellek tasmalari, kullanicinin asagidakine benzer girdileri girmesinden kaynaklanir:
%08x.%08x.%08x.%08x.%08x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n
Üstteki saldiri dizgisi yigit üzerindeki bes kaydi basacaktir. Format dizgileri son derece özellesmis arabellek tasmalaridir ve buna ragmen, uzaktan tamamen ele geçirme dahil ayni saldirilari uygulamak için kullanilabilirler.
Evrensel kod istismarlarinin uygulanmalari Anley’in 2002 yilindaki makalesinde gösterildigi gibi, tipik arabellek tasmalarina Gore biraz daha zordur, ama evrensel kod kullanarak arabellek tasmalarindan korundugunuzu varsaymak yanlistir. Evrensel kod tasmalarina örneklerden bir tanesi yikici bir Truva ati olan Code Red’dir.
Saldiriya açik olup olmadiginizi anlama (yollari)
Eger programiniz:
-Arabellek tasmalarindan mustarip olan bir dille yazilmis veya bu diller ile yazilmis baska bir programa bagli ise VE
-Kullanicidan Unicode girdisi aliyorsa VE
-Girdiyi aritmiyorsa VE
-Kanarya degerleri kullanmadan yigit ve yigin üzerinde ayrilmis degiskenler kullaniyorsa
-printf(), snprintf() ve bunlara benzer veya es deger diger fonksiyonlari, veya bunlari kullanan syslog gibi system servislerini kullaniyorsa uygulama büyük ihtimalle saldiriya açiktir.
Özel yapim (custom) uygulama kodunuz için, güvenilmeyen her kaynaktan gelen girdileri kabul eden bütün kodlari incelemeniz ve kodun bu sekildeki bütün girdiler üzerinde büyüklük kontrollerini uyguladigindan emin olmaniz gerekir.
Bu kontroller, aslinda bu tür saldirilara karsi etkilenmeyen yerlerde de yapilmalidir
çünkü yakalanmayan çok uzun girdiler, hizmet disi birakma ve diger operasyon el problemlere de neden olabilirler.
Tamsayi Tasmasi
Bir uygulama, iki belirlenmis büyüklükte sayi aldiginda ve bunlar ile bir isler yaptiginda, sonuç ayni büyüklükte çikmayabilir. Mesela, iki 8 bitlik numara olan 192 ve
208 birbirine eklendiginde ve diger bir 8 bitlik bir baytta saklanirsa, islem sonrasi meydana çikan sayi 8 bitlik sonuca sigmayacaktir:
% 1100 0000
+ % 1101 0000
= % 0001 1001 0000
En üstteki yarim sözcük (4 bit) atilacaktir ve geriye kalan geçerli bir sonuç degildir.
Bu durum bütün diller için bir problem olabilir. Mesela, bir çok hexadecimal çeviriler (conversion) %M0’i 192’ye “basarili bir sekilde” çevirecektir. Endiselenilmesi gereken diger alanlar, dizilim indisleri (array indices) ve örtülü (implicit) kisa matematik islemleridir.
Saldiriya açik olup olmadiginizi anlama (yollari)
-Web, uygulama sunucu ve Internet altyapinizdaki diger ürünlerinize ait en son hata raporlarini takip edin. Bu ürünlere ait en son yamalari uygulayin.
-Sunucu ürünlerinizde ve özel yapim web uygulamalarinizda arabellek tasma hatalarini bulacak yaygin olarak kullanilan tarayicilar ile web sitenizi periyodik olarak tarayin
-Kodunuzu Unicode istismarlarina karsi inceleyin.
-C ve C++ disindaki programlama dillerini kullanin
-Çok uzun girdileri önlemek için kullanici girdilerinin geçerliliklerini denetleyin ve sartlara (mesela A-Z, a-z, 0-9, v.b.) uyduklarina emin olmak için degerleri kontrol edin.
-Eger C ve C++ dillerinde yazilmis isletim sistemi ve yardimci programlar kullaniliyorsa, en düsük erisim hakki prensibini kullandiklarindan emin olun, yigit ve yigin (heap) tasmalarina karsi koruyucu derleyiciler kullanin ve sistemi yamalari ile güncel tutun.-Özellikle bayt ve short olan isaretli (signed) tamsayilari inceleyin
-Bu degerlerin, + - * / veya % gibi aritmetik islemler uygulandiktan sonra dizilir indisleri olarak kullanildigi yerler var mi?
-Kod, negatife veya sifir indisleri ile basa çikiyor mu
Kendinizi koruma (yollari)
-.NET: David LeBlanc’in SafeInt<> C++ sinifini veya diger yapilarini kullanin
- .Derleyiciniz destekliyorsa ve tam aksi söylenmemisse, tamsayilar için varsayili degeri isaretsiz (unsigned) olarak degistirin. Ne zaman kullanmaniz gerekiyorsa isaretsiz (unsigned) tamsayilari kullanin.
-.Eger diliniz ve çatiniz (framework) destekliyorsa deger kümesi kontrolleri kullanin
Küçük degerlerle ugrasirken aritmetik islemlerde dikkatli olun, özellikle tasma isaret degisiklikleri veya diger hatalar olusabilecekken..
Bug Researchers