spacer.png, 0 kB
Bilgi için: bilgi at bilgiguvenligi gov tr   

 

spacer.png, 0 kB
spacer.png, 0 kB
Bellek Taşması (Stack Overflow) ve Korunma Yöntemleri Yazdır E-posta
Veysel Hataş, TÜBİTAK BİLGEM   
24.09.2013

Günümüzde network ve bilgisayar teknolojilerinin hızlı gelişimiyle beraber birçok güvenlik sorunlarını da beraberinde getiriyor. Hafıza bloğu taşması (buffer overflow) açığı, 1970’lerde ortaya çıkmış ve yaklaşık 20 yıl süre zarfında bilişim güvenliği açıklıkları arasında yerini almıştır. “Buffer overflow” güvenlik açığı saldırılarının büyük bir çoğunluğu, uzak network saldırılarında zararlı yazılımların kullanılması ile çok tehlikeli boyutlara ulaşılabiliyor.  National Vulnerability Database (https://nvd.nist.gov )’in istatistik verilerine göre, 2011 yılına 260 “Buffer overflow” güvenlik açığı arasından 211 tanesinin yüksek seviyeye sahip olduğu, 2013 yılında ise 35 “buffer overflow” güvenlik açığı arasından 32 tanesinin yüksek seviyeye sahip olduğu tespit edilmiştir. 2011’de SANS firmasının yaptığı en tehlikeli yazılım hataları listesinde de 3. sırada yer alıyor. Bu temel güvenlik açıklıkları işletim sistemlerinde çeşitli koruma mekanizmaları ile giderilmeye çalışılsa da günümüzde dahi çoğu uygulamalarda görülmektedir.

Hafıza Bloğu Taşması (Buffer Overflow)

Bellekte statik ve dinamik değişkenlerin tutulduğu sıralı hafıza blokları bulunmaktadır. “Buffer overflow”, genellikle sınır denetimi (bound checking) yapılmamış hafıza bloklarının taşıyabilecekleri veri miktarından daha fazlasını yükleyerek bu hafıza bloklarının sınırlarının aşılmasıdır. Genellikle bu alanlara fazla karakter kopyalama ile bir hafıza alanından diğerine erişim sağlanmaya çalışılır. Bu olay sistemde bellek taşmasına neden olur.

Hafıza Yapısı

Bir program çalıştırıldığında, işletim sistemi tarafından Şekil-1’deki gibi belleğe yerleştirilir. 0x00000000 – 0xffffffff adres aralığına sahip olan hafızanın ilk yarısı kullanıcı uygulamaları için, diğer yarısı ise çekirdek alanı için ayrılmıştır.  “Text segment” kısmına, o an çalıştırılacak programın kodu yani programın bir dizi çalıştırma talimatları yerleştirilir. İçerisinde komutların bulunduğu bu segment, non-linear olup read-only özelliğine sahiptir. “Data segment” kısmında başlatılmış (initialized) global ve statik değişkenler tutulurken, “BSS segment” alanında başlatılmamış (uninitialized) global ve statik değişkenler tutulur. Bu segmentler üzerine yazılabilir özellikte olup segmentlerin boyutları fix tutulmuştur. Son olarak Stack ve Heap segmentler ise hafızada hâlihazırda program çalışırken tahsis edilen ve karşılıklı büyüyen alanlardır. Stack alanı içerisinde register’lar ile erişilebilen önceden oluşturulmuş fonksiyonlara ait local değişkenler ve veriler yer almaktadır. Heap alanı da özel ayırıcılar (allocator) kullanarak erişilebilen (C dilinde malloc() fonksiyonu, C++ dilinde “new” anahtar öneki ile) ve dinamik değişkenlerin oluşturulup sonrasında yok edildiği yerdir. Bu alanın kontrolü programcıya verilmiştir.

sekil-1.png

Şekil-1 Hafıza bölümleri

Buffer overflow (hafıza bloğu taşması) güvenlik açığı bahsettiğimiz stack, heap hatta data alanlarında meydana gelebilmektedir. Bu açıklığı kullanan ataklar, stack overflow, heap overflow, integer overflow şeklinde isimlendirilmektedir. Bu yazımda buffer overflow atak türlerinden olan “stack overflow” yapısından kısaca bahsedip bazı bilinen korunma yöntemlerine değineceğim.

Stack (Yığın) Tabanlı Buffer Overflow

Stack, LIFO (son giren ilk çıkar) yapısına göre çalışmaktadır. x86 mimarisine göre bir program yığında oluşturulduğunda ESP (stack pointer) en üst yığın (top of the stack) adresini, EBP (base pointer) oluşturulan “stack frame” yapısının alt kısmını işaret eder. Yığın (stack) içerisinden bir fonksiyon çağırma işlemi yapıldığında, yığında ESP‘nin gösterdiği değer program çalıştığı sürede yığına yapılan PUSH ve POP işlemlerine göre değişiklik gösterir. EIP (Instruction pointer) ise text segment üzerindeki komut dizininde bulunan çalıştırılacak bir sonraki komutu işaret eder. Yığın oluşturulurken yüksek adresten düşük adrese doğru sırasıyla; fonksiyon argümanları, dönüş adres değeri (Return address), önceki fonksiyondaki kaydedilmiş EBP değeri (Saved EBP) ve fonksiyonda o an oluşturulan değişkenler kaydedilir. Fonksiyon sonlandığında local değişkenler ile beraber fonksiyon yığından kaldırılır ve yığın alanı bir sonraki fonksiyon için temizlenmiş olur.

sekil-2.png

Şekil-2 Fonksiyon çağırılma süresince yığın davranışı

Yığında belirlenmiş alanlara daha fazla veri yazılmaya çalışıldığında “Stack overflow” (yığın bellek taşması) meydana gelmesi, programın çakılmasına ya da yanlış çalışmasına neden olur. “Stack overflow” saldırıları, bu açıklığı kullanarak dönüş (return) adresi üzerine zararlı çalıştırılabilir kod (shellcode) adresi yazılarak kontrolün ele alınması ve yetkisiz erişim sağlanması şeklinde gerçekleşmektedir.

Saldırganlar tarafından kullanılan “Stack buffer overflow” atakları genelde iki yöntemle yapılır.

  1. Dönüş adresi üzerine istenilen adres değeri yazılarak,

  2. Bir fonksiyon göstericisi (function pointer) ya da SEH (exception handling) işaretcisi üzerine yazılarak yapılır.

Birinci yöntemin (overwriting the return address) en yaygın kullanımı,  Şekil-3'te görüldüğü gibi dönüş adresinin tutulduğu register üzerine “JMP ESP” komutu yazmaktır. Bu komutun olduğu herhangi bir adres değeri EIP’ye gösterilerek (bu adres değeri sistem ve uygulama dll dosyalarından da elde edilebilmekte), ESP ’nin gösterdiği önceden saldırgan tarafından oluşturulup belleğe yerleştirilmiş zararlı koda (shellcode) gidilmesi sağlanır. Bunun temel bir örnek yapısı aşağıda verilmiştir.

sekil-3.png

Şekil-3 Yığındaki “JMP ESP” konumu

resim-1.png

İkinci yöntem (Overwriting the Structured Exception Handling-SEH) ise windows işletim sistemi tarafından yazılımsal veya donanımsal problemlerden kaynaklanan ciddi program hatalarının üstesinden gelmek için kullanılan SEH metodunun farklı amaç doğrultusunda kullanılmasıdır. Program çalışma esnasında bir hata (exception) meydana geldiğinde, oluşturulmuş SEH liste bölümüne erişilir. Her SEH kaydı, hata işleyicisi (SE Handler)  adresinin ve bir sonraki SEH kaydı (Next SEH Record) adresinin tutulduğu alanlardan oluşur. Hata yakalama yapı göstericisi (SEH) kullanımını istismar etmek kısaca yukarıda bahsedilen SEH hafıza blokları üzerine “buffer overflow” saldırısı ve bazı temel adres hesaplamaları ile çalıştırılacak olan shellcode adresine ulaşılması sağlanır. Aşağıda bunun temel bir örnek yapısı verilmiştir.

sekil-4.png

Şekil-4 Yığında SEH overflow gösterimi

resim-2.png

Buffer Overflow Savunma ve Korunma Teknikleri

“Buffer overflow” saldırısını önlemek veya tespit etmek için çeşitli yöntemler bulunmaktadır. Bunlardan bazılarını aşağıda açıklayalım.

  • C ve C++ ile kod yazarken kütüphane fonksiyonları seçimine dikkat edilmelidir. Örneğin strcpy(), strcat(), sprint() ve vsprintf() gibi fonksiyonlar yerine strncpy () gibi daha güvenilir fonksiyon seçimi yapılabilir. Aynı zamanda bellek sınır kontrolleri yazılım bazında yapılmalıdır.

  • Yığında bellek taşmasını engellemek için bu bölgelerde çalıştırılabilir kodlara izin vermeme şeklinde bellek politikaları oluşturulabilir.  Böylece yığında zararlı kod çalıştırma girişimlerinde istisnai durum (exception) oluşturularak engellenmiş olunur.

  • İşletim sistemlerinde ve uygulamalarda kullanılmak üzere geliştirilmiş hafıza koruma mekanizmaları (SafeSEH, SEHOP, DEP, ASLR, EAP gibi) vardır. Windows üzerinde uygulama tabanlı bu ayarlamaları yapmak için Microsoft firmasının anti-exploit kiti olan EMET programı kullanılabilir.

  • Statik ve dinamik analiz yöntemleriyle program kaynak kodları analiz edilip “Buffer overflow” güvenlik açığı zafiyetine bakılıp önlemler alınabilir. Bu işte kullanılan değişik buffer overflow dedektörler ve konu ile alakalı onlarca makale bulunmaktadır.

  • İşletim sistemi ve sistemde kurulu uygulamaların güncelleştirmelerinin gerçekleştirilmesi ise bellek taşma ataklarından korunmanın en basit ve en etkili yöntemidir.

NOT: Yazıda verilen kod blokları sadece yöntemlerin örnek bir yapısını gösterme amaçlı olup, bu haliyle çalışmaması normaldir.

Kaynaklar

[1] http://cwe.mitre.org/top25/archive/2011/2011_cwe_sans_top25.pdf

[2] https://nvd.nist.gov

[3] http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=6405636&tag=1

[4] http://www.microsoft.com/en-us/download/details.aspx?id=38761

[5] http://beej.us/guide/bgc/output/html/multipage/strcpy.html

[6] http://www.rsa.com/rsalabs/node.asp?id=2011

[7] http://en.wikipedia.org/wiki/Buffer_overflow

[8] http://emergentchaos.com/archives/2008/10/buffer-overflows-and-history-a-request.html


Favori olarak ekle (0) | Görüntüleme sayısı: 10208

Bu yazıya ilk yorumu yazın

Sadece kayıtlı kullanıcılar yorum yazabilir.
Lütfen sisteme giriş yapın veya kayıt olun.

 
spacer.png, 0 kB
spacer.png, 0 kB
Copyright 2017 TÜBİTAK-BİLGEM. Sitenin teknik altyapısında Joomla kullanılmıştır. Yazar ve site referans gösterilmeden alıntı yapılamaz. Görüşleriniz
spacer.png, 0 kB