Önbellek taşmalarıVon-Neuman 1 mimarisin başlangıcından itibaren geçerlidir.1988 yılında Morris Internet Solucanıile kötü bir şöhrete kavuştu. Ne yazık ki halen bazi basit saldırıyöntemleri etkili olabilmektedir.1999 güvenlik raporunda önbellek taşırmada en çok kullanılan saldırıyöntemi yığınıbozmak olarak bildirilmişti.
Modern bilgisayar sistemleri yığın bölümünü (stack segment) fonksiyon çağrılarısırasında parametreleri ve yerel değişkenleri kaydetmek için kullanıyor. Yığın (stack) önce giren sonra çıkar (LIFO) prensibi ile çalışıyor ve sürecin hafızadaki görüntüsünda üst hafıza alanında yer alıyor.Eğer program bir fonksiyon çağırırsa yeni bir "stack frame" oluşturulur. Burada fonksiyon içinde kullanılan yerel değişkenler ve parametreler saklanır.Yığın işaretçisi yığının şu anda geçerli olan adresini tutan bir yazmaçtır.Ayrıca bir çok uygulama çerçeve işaretçisi (frame pointer) kullanır ki bu işaretçinin(pointer) görevi yerel değişkenler daha kolay bir şekilde adreslenmesini sağlamaktır. Fonksiyonun geri dönüşadresi de ayrıca burada saklanmıştır.İşte tam bu noktada kötü niyetli bazıkimseler istedikleri takdirde yerel değişkeni taşırıp fonksiyonun döneceği adresi değiştirerek kendi yaptıkları programın çalışmasınısağlayabilirler.
Bu tip saldırıçok sık karşılaşılan bir durum olsada bunu dışında heap tipi (malloc/realloc fonksiyonlarıile) saldırıile de yığını(stack) taşırmak mümkündür.
C programlarısınırlarıkontrol etmediğinden bazıkütüphane fonksiyonlarıbile tehlikeli fonksiyonlar içermektedir.
| strcpy(char *dest, const char
          *src) | Burada dest buffer taşması yapabilir | 
| strcat(char *dest, const char
          *src) | dest deÄŸiÅŸkeni taÅŸma yapabilir | 
| getwd(char *buf) | buf deÄŸeri taÅŸma yapabilir | 
| gets(char *s) | s deÄŸeri taÅŸma yapabilir | 
| [vf]scanf(const char *format,
          ...) | argümanlar taşma yapabilir | 
| realpath(char *path, char
          resolved_path[]) | path buffer taşması yapabilir | 
| [v]sprintf(char *str, const char
          *format, ...) | str deÄŸeri taÅŸma yapabilir | 
Aşağıdaki kod fonksiyonun dönüşadresi üzerine taşma yapması için dizayn edilmiştir.
#include <stdio.h>
void manipulate(char *buffer) {
  char newbuffer[80];
  strcpy(newbuffer,buffer);
}
int main() {
  char ch,buffer[4096];
  int i=0;
  while ((buffer[i++] = getchar()) != '\n') {};
  i=1;
  manipulate(buffer);
  i=2;
  printf("The value of i is : %d\n",i);
  return 0;
}Burada eğer biz 160 karakterlik bir girişyaparsak ne olur acaba. Çok tehlikeli sonuçlar doğurabilir. Mesela exec(/bin/sh) şeklinde bir programın derlenmişhali gönderilirse kötü niyetli kimselere bütün kapılarıaralamışolur.
Yığın taşmalarından kurtulmanın yolu boyutu sınırlandırılmışbir hafıza erişimi sağlamaktır.Bir de standart string kütüphanesindeki strcpy,strcat fonksiyonlarıyerine strncpy strncat fonksiyonları tercih edilebilir. Bu fonksiyonlar dizinin boyutunu parametre olarak alır daha fazlasınıkopyalamaz. Ama bu fonksiyonlar Null ile bitirmedikleri için dizi dolana kadar yazım işlemini NULL ile devam ettirirler. Böyle olunca diğer fonksiyonlara göre zaman kaybı olacaktır.
OpenBSD altında bu problemi çözmek için bazıyeni hafıza kopyalama fonksiyonlarıgeliştirilmiştir. strlcpy ve strlcat fonksiyonlarıNULL karakteri gördüğünde sonlanır. Daha fazla bilgi için OpenBSD'nin bu fonksiyonlarla ilgili man page'lerine bakabilirsiniz.
Ne yazık ki toplum tarafından kullanılan onlaraca kod içinde yukarıda bahsettiğimiz açıklardan bolca bulunuyor. Allah'tan bunun için farklıçözümlerimiz de var. Bazıderleyiceler çalışma zamanında programınızın sınırlarınıkontrol etmesini sağlayan araçlar bulunduruyor.
Stack guard bu eklentilerden bir tanesi ;gcc kod üreticisi altında küçük bir güncelleme işlemi sonucunda eklenebiliyor. StackGuard web sitesinden bu eklentiyi elde edebilirsiniz. (http://immunix.org/stackguard.html)
StackGuard eklentisi yığın bölümüne (stack segment) yönelik saldırılarıönlemek için fonksiyonların dönüşadreslerini koruma altına alıyor. StackGuard fonksiyonun dönüşadresine bir "canary" (kanarya) kelimesi ekliyor. Eğer "canary" kelimesi değişmişise burada saldırıgerçekleştiğine hükmediliyor ve syslog dosyasına davetsiz misafir uyarısıgönderilerek program sonlandırılıyor.
StackGuard gcc kod üreticisi üzerinde küçük bir yama yapar , özel olarak function_prolog() ve fuction_epilog() fonksiyonları üzerinde. function_prolog() "canary" kelimelerini gerekli yerlere yerleştirir , function_epilog() ise kanaryaların yerinde durup durmadığınıkontrol eder. Eğer herhangi bir değişiklik oluşmuşise fonksiyon bitirilmeden önce gerekli işlem gerçekleştirilir.
Bu şekilde programınızıderlemek çoğu buffer taşırma saldırılarınıönleyecektir. Fakat yinede tam manasıile güvenilir değildir. Mesela ben canary yi değiştirmem ama sonrasını değiştiririm.
Tekrar derleyemeyeceğiniz programlar için derleyici tabanlı programlar işe yaramayacaktır. Bu gibi programlarda eğer strcpy strcat gibi fonksiyonlarıyığın işaretçisinden (stack pointerdan) önce kullanmadıysanız belirli kütüphaneler yardımıile güvenli hale getirebilirsiniz. Bu kütüphanelerden bir kaçı:
- libsafe
- libverify
- libparanoia
Ne yazık ki bu kütüphane tabanlısavunma sistemi bazıkısıtlar içeriyor. Bu kütüphaneler sadece küçük güvenlik tabanlıproblemleri çözüyor ve asıl problemi ihmal ediyor. Eğer derleme sırasında fomit-frame-pointer kullanıldıise bu güvenlik eklentileri çalışmayacaktır.Ayrıca LD_PRELOAD ve LD_LIBRARY_PATH çevre değişkenleri kullanıcıtarafından değiştirilebilir ve bozulabilir.