Semih Yavuz tarafından yazılmıştır.
Buffer Overflow , muhtemelen en bilinen yazılım güvenlik açıklarından biridir. Çoğu yazılım geliştirici, Buffer Overflow açığının ne olduğunu bilir, ancak hem eski hem de yeni geliştirilmiş uygulamalara yönelik Buffer Overflow saldırıları hala oldukça yaygın bir saldırı türüdür.Sorunun bir kısmı, Buffer Overflow saldırılarının meydana gelebileceği çok çeşitli yollardan ve kısmen bunları önlemek için sıklıkla kullanılan hataya açık tekniklerden kaynaklanmaktadır.
Buffer ya da Türkçe çevirisiyle arabellek , bir program içinde işlenmekte olan verileri tutmak için kullanılan ayrılmış bir bellek bölümüdür. Örnek olarak, bir program daha sonra çalışmak üzere kullanıcı girdisini kabul ettiğinde, bu kullanıcı girdisini depolamak için bir bellek parçasının ayrılması gerekir ve her programda gelen ve giden verileri tutmak için arabellekler kurulur.Bu arabellekler tipik olarak RAM belleğinde çalışır ve bilgisayarlar, performansı artırmaya yardımcı olmak için sık sık arabellek kullanır; çoğu modern sabit sürücü, verilere verimli bir şekilde erişmek için arabelleğe alma işleminden yararlanır ve birçok çevrimiçi hizmet de arabellek kullanır. Bir video akışı uygulamasında program, anlık gecikmeleri telafi etmek için önceden bir video verisi kaynağı depolamak için arabellekleri kullanır.
Arabellek taşması gerçekleşmeden önce bellek ayırma aşağıdaki gibi görünür:
<---------------------------> <------------------------------------>
Buffer(Arabellek) Diğer program verileri
Boyutu arabelleği aşmayan normal bir input aşağıdaki gibi görünür:
1111111111111 22222222222222222222222222222222222
<--------------------------->EIP<---------------------------------->
Buffer(Arabellek) Diğer program verileri
Ancak kullanıcı input boyutu arabellek boyutunu aştığında, kullanıcı girdisi diğer potansiyel olarak önemli program verilerinin üzerine yazabilir:
111111111111111111111111111111111111111222222222222222222222222222
<--------------------------->EIP<---------------------------------->
Buffer(Arabellek) Diğer program verileri
Veri hacmi, arabelleğin depolama kapasitesini aştığında bir Buffer Overflow (arabellek taşması) meydana gelir.Bu nedenle fazladan veriyi ara belleğe yazmaya çalışan program, bitişik bellek konumlarının üzerine yazar veya bu konumlardaki verileri bozar.Klasik bir Buffer Overflow istismarında, saldırgan bir programa veri gönderir ve bu veri, küçük boyutlu bir yığın arabelleğinde depolanır. Sonuç olarak, işlevin dönüş işaretçisi de dahil olmak üzere çağrı yığınındaki bilgilerin üzerine yazılır. Veri, dönüş işaretçisinin değerini ayarlar, böylece işlev döndüğünde, kontrolü saldırganın verilerinde bulunan kötü amaçlı koda aktarır.Nihayetinde Buffer Overflow saldırılarının keşfi kolay değildir ve bir tanesi keşfedilse bile, genellikle istismar edilmesi son derece zordur. Bununla birlikte, saldırganlar, bir çok ürün ve bileşende Buffer Overflow zaafiyetlerini tanımlamayı başardılar.
Örnek olarak bir Buffer Overflow kod parçası aşağıda verilmiştir,
Farklı stratejiler kullanan ve farklı kod parçalarını hedefleyen farklı Buffer Overflow saldırıları vardır. Aşağıda en bilinenlerden birkaçı bulunmaktadır.
Buffer Overflow saldırısının günümzde en yaygın ve en eski türüdür ve call stack’te bir arabelleğin taşmasına neden olur.
Bu saldırı türü, stack olarak bilinen açık bellek havuzundaki verileri hedefler.Heap overflow, stack-based taşmalardan farklı bir şekilde sömürülür.Heap üzerindeki bellek, uygulama tarafından çalışma zamanında dinamik olarak ayrılır ve tipik olarak program verilerini içerir.
Unicode Overflow, kullanıcıdan ASCII karakterleri bekleyen bir girişe Unicode karakterler ekleyerek bir Buffer Overflow’a neden olur.
Bir integer (tamsayı) değişkeni içinde, değişkenin tutabileceği maksimum değerden daha büyük bir değeri saklamaya çalıştığınızda bir Integer Overflow meydana gelir. C dili bu durumu undefined behavior olarak tanımlar. Pratikte, bu genellikle işaretsiz bir tamsayı kullanılmışsa değerin kaydırılması ve işaretli bir tamsayı kullanılmışsa işaret ve değerin değişmesi anlamına gelir.
Modern işletim sistemleri, Buffer Overflow saldırılarını azaltmaya yardımcı olan runtime korumalarına sahiptir. Ancak bu güvenlik açığını önlemenin en kolay yolu, buna izin vermeyen bir dil kullanmaktır. C ve C++ programlama dilleri, belleğe doğrudan erişime sahip oldukları için belleklerdeki verilerin üzerine yazmaya veya verilere erişmeye karşı yerleşik korumaları olmadığı için arabellek taşması saldırılarına karşı oldukça hassas olan iki programlama dilidir.Ne yazık ki Windows, Mac OS ve Linux’un tümü C ve C++ ile yazılmış kodları kullandıkları için bu zaafiyetin boyutunu ciddi manada çoğaltmaktadır.
Sömürü riskini azaltmaya yardımcı olan 2 yaygın korumayı inceleyelim:
Adres Alanı Rastgeleleştirme (Address Space Randomization):Bir işlemin önemli veri alanlarının adres alanı konumlarını rastgele yeniden düzenler. Buffer Overflow saldırıları genellikle önemli çalıştırılabilir kodun tam yerinin bilinmesine dayanır, adres alanlarının rastgele hale getirilmesi bunu neredeyse imkansız hale getirir.
Veri Yürütme Engellemesi(Data Execution Prevention): Yürütülebilir (executable) veya yürütülemez(non-executable) belleğin belirli alanlarını işaretleyerek, bir istismarın yürütülemez bir alanda bulunan kodu çalıştırmasını önler.
Structured Exception Handling Overwrite Protection (Yapılandırılmış Özel Durum İşleme Koruması): Structured Exception Handling Overwrite Protection kısa adıyla SEHOP günümüzde yaygın kullanılan bir Buffer Overflow saldırısı olan Structural Exceptions üzerine yazma(Override) tekniğini kullanan istismarları engeller.
[TR] Buffer Overflow’a Giriş
Buffer Overflow , muhtemelen en bilinen yazılım güvenlik açıklarından biridir. Çoğu yazılım geliştirici, Buffer Overflow açığının ne olduğunu bilir, ancak hem eski hem de yeni geliştirilmiş uygulamalara yönelik Buffer Overflow saldırıları hala oldukça yaygın bir saldırı türüdür.Sorunun bir kısmı, Buffer Overflow saldırılarının meydana gelebileceği çok çeşitli yollardan ve kısmen bunları önlemek için sıklıkla kullanılan hataya açık tekniklerden kaynaklanmaktadır.
Buffer Overflow (Arabellek Aşımı) Nedir?
Buffer ya da Türkçe çevirisiyle arabellek , bir program içinde işlenmekte olan verileri tutmak için kullanılan ayrılmış bir bellek bölümüdür. Örnek olarak, bir program daha sonra çalışmak üzere kullanıcı girdisini kabul ettiğinde, bu kullanıcı girdisini depolamak için bir bellek parçasının ayrılması gerekir ve her programda gelen ve giden verileri tutmak için arabellekler kurulur.Bu arabellekler tipik olarak RAM belleğinde çalışır ve bilgisayarlar, performansı artırmaya yardımcı olmak için sık sık arabellek kullanır; çoğu modern sabit sürücü, verilere verimli bir şekilde erişmek için arabelleğe alma işleminden yararlanır ve birçok çevrimiçi hizmet de arabellek kullanır. Bir video akışı uygulamasında program, anlık gecikmeleri telafi etmek için önceden bir video verisi kaynağı depolamak için arabellekleri kullanır.
Arabellek taşması gerçekleşmeden önce bellek ayırma aşağıdaki gibi görünür:
<---------------------------> <------------------------------------>
Buffer(Arabellek) Diğer program verileri
Boyutu arabelleği aşmayan normal bir input aşağıdaki gibi görünür:
1111111111111 22222222222222222222222222222222222
<--------------------------->EIP<---------------------------------->
Buffer(Arabellek) Diğer program verileri
Ancak kullanıcı input boyutu arabellek boyutunu aştığında, kullanıcı girdisi diğer potansiyel olarak önemli program verilerinin üzerine yazabilir:
111111111111111111111111111111111111111222222222222222222222222222
<--------------------------->EIP<---------------------------------->
Buffer(Arabellek) Diğer program verileri
Veri hacmi, arabelleğin depolama kapasitesini aştığında bir Buffer Overflow (arabellek taşması) meydana gelir.Bu nedenle fazladan veriyi ara belleğe yazmaya çalışan program, bitişik bellek konumlarının üzerine yazar veya bu konumlardaki verileri bozar.Klasik bir Buffer Overflow istismarında, saldırgan bir programa veri gönderir ve bu veri, küçük boyutlu bir yığın arabelleğinde depolanır. Sonuç olarak, işlevin dönüş işaretçisi de dahil olmak üzere çağrı yığınındaki bilgilerin üzerine yazılır. Veri, dönüş işaretçisinin değerini ayarlar, böylece işlev döndüğünde, kontrolü saldırganın verilerinde bulunan kötü amaçlı koda aktarır.Nihayetinde Buffer Overflow saldırılarının keşfi kolay değildir ve bir tanesi keşfedilse bile, genellikle istismar edilmesi son derece zordur. Bununla birlikte, saldırganlar, bir çok ürün ve bileşende Buffer Overflow zaafiyetlerini tanımlamayı başardılar.
Örnek olarak bir Buffer Overflow kod parçası aşağıda verilmiştir,
Kod:#include "stdafx.h" #include <math.h> volatile double test; double function3() { test++; return exp(test); } double function2() { return log(test); } double function1() { int a[5] = {0}; a[7] = (int)&function3; return exp(function2()); } int _tmain(int argc, _TCHAR* argv[]) { double a = function1(); test = a; return a; }
Buffer Overflow Türleri
Farklı stratejiler kullanan ve farklı kod parçalarını hedefleyen farklı Buffer Overflow saldırıları vardır. Aşağıda en bilinenlerden birkaçı bulunmaktadır.
Stack Overflow Attack
Buffer Overflow saldırısının günümzde en yaygın ve en eski türüdür ve call stack’te bir arabelleğin taşmasına neden olur.
Heap Overflow Attack
Bu saldırı türü, stack olarak bilinen açık bellek havuzundaki verileri hedefler.Heap overflow, stack-based taşmalardan farklı bir şekilde sömürülür.Heap üzerindeki bellek, uygulama tarafından çalışma zamanında dinamik olarak ayrılır ve tipik olarak program verilerini içerir.
Unicode Overflow Attack
Unicode Overflow, kullanıcıdan ASCII karakterleri bekleyen bir girişe Unicode karakterler ekleyerek bir Buffer Overflow’a neden olur.
Integer Overflow Attack
Bir integer (tamsayı) değişkeni içinde, değişkenin tutabileceği maksimum değerden daha büyük bir değeri saklamaya çalıştığınızda bir Integer Overflow meydana gelir. C dili bu durumu undefined behavior olarak tanımlar. Pratikte, bu genellikle işaretsiz bir tamsayı kullanılmışsa değerin kaydırılması ve işaretli bir tamsayı kullanılmışsa işaret ve değerin değişmesi anlamına gelir.
Buffer Overflow Saldırılarına Karşı Nasıl Korunulur?
Modern işletim sistemleri, Buffer Overflow saldırılarını azaltmaya yardımcı olan runtime korumalarına sahiptir. Ancak bu güvenlik açığını önlemenin en kolay yolu, buna izin vermeyen bir dil kullanmaktır. C ve C++ programlama dilleri, belleğe doğrudan erişime sahip oldukları için belleklerdeki verilerin üzerine yazmaya veya verilere erişmeye karşı yerleşik korumaları olmadığı için arabellek taşması saldırılarına karşı oldukça hassas olan iki programlama dilidir.Ne yazık ki Windows, Mac OS ve Linux’un tümü C ve C++ ile yazılmış kodları kullandıkları için bu zaafiyetin boyutunu ciddi manada çoğaltmaktadır.
Sömürü riskini azaltmaya yardımcı olan 2 yaygın korumayı inceleyelim:
Adres Alanı Rastgeleleştirme (Address Space Randomization):Bir işlemin önemli veri alanlarının adres alanı konumlarını rastgele yeniden düzenler. Buffer Overflow saldırıları genellikle önemli çalıştırılabilir kodun tam yerinin bilinmesine dayanır, adres alanlarının rastgele hale getirilmesi bunu neredeyse imkansız hale getirir.
Veri Yürütme Engellemesi(Data Execution Prevention): Yürütülebilir (executable) veya yürütülemez(non-executable) belleğin belirli alanlarını işaretleyerek, bir istismarın yürütülemez bir alanda bulunan kodu çalıştırmasını önler.
Structured Exception Handling Overwrite Protection (Yapılandırılmış Özel Durum İşleme Koruması): Structured Exception Handling Overwrite Protection kısa adıyla SEHOP günümüzde yaygın kullanılan bir Buffer Overflow saldırısı olan Structural Exceptions üzerine yazma(Override) tekniğini kullanan istismarları engeller.
Moderatör tarafında düzenlendi: