Ana içeriğe atla

Buffer Overflow Üretecek Programcı Nasıl Yetiştirilir


Yukarıdaki örnek "Bilgisayar Programlama I" dersinde "dizi" kavramının anlatıldığı kısımde yer alan örneklerden birisi. Ancak deneyimli programcılar bu kodun hatalı olduğunu ve istenmeyen sonuçlar ortaya çıkartacağını fark etmişlerdir.Bu durumu fark etmeyenler için bu eğlenceli hata hakkında bir şeyler yazmak istiyorum...



Şimdi yukarıdaki kodu yazalım ve derleyelim. Ben sizin yerinize yazdığım için siz aşağıdan kopyala yapıştır yaparak kullanabilirsiniz :)


#include <stdio.h>
int a[10],i,j;
main(){
    /* dizi elemanları giriliyor*/
    for(i=0;i<=10;i++){
        printf("\n%d. sayıyı giriniz:",i);
        scanf("%d",&a[i]);
        if(a[i]==0) break;
        j=i;
    }
    /*dizi elemanları yazdırılıyor*/
    for(i=0;i<=j;i++)
        printf("%d\n",a[i]);
}

Yukarıdaki kodları ornek2.c adıyla kaydettikten sonra, Linux ortamı için aşağıdaki gibi bir komutla derleyelim. Windows ortamında derlemek için Dev-C++ kullanabilirsiniz...


seker@seker-N53SN:~$ gcc -fno-stack-protector -o ornek2 ornek2.c 


Şimdi kodumuzu derlediğimize göre çalıştıralım ve neler olduğuna bir bakalım. ornek2 programımız, belirttiğimiz i sayacı 10 değerinden küçük yada eşit olduğu  sürece bizden sayı girmemizi isteyecektir.



Yukarıdaki ekran çıktısına bakarsanız döngünün 10 adımdan fazla sürdüğünü görebilirsiniz.

Sağ kenarda kocaman 1 rakamıyla gösterdiğim döngü adımında girilen değerden sonra bir terslik olduğunu ve döngünün uzadığını fark etmiş olmalısınız. Aynı durum 2, 3 ve 4 olarak işaretlediğim adımlarda da gerçekleşiyor...

Peki ne oluyor da böyle oluyor?

1, 2, 3 ve 4 ile gösterdiğim adımlarda girilen değerin, döngü sayacını değiştirdiğini ve böylece döngünün uzayıp gittiğini görebilirsiniz. Bu adımda ekranda "10. sayıyı giriniz" yazıyor olsa bile gerçekte okuduğumuz 11. sayı olur. Bu durumda int a[10] diyerek hafızda ayırdığımız 10 birimlik alana 11 birim veri yazmış oluruz. Yani bir tür bellek taşması durumu oluşur. Taşan kısım hafızada i değişkeninin bulunduğu alana yazılır ve i değişkeni değiştiği için for döngüsü olması gereken farklı bir yere atlar...

Bu durumu yanda görülen bellek şeması üzerinde daha kolay anlayabiliriz. Yeşil olarak gösterilen bellek alanları a[10] dizisi için ayrılan alanlardır. Hemen ardından ise kırmızı ile göstermekte olduğum i değişkeni için ayrılan alan yer alır. Bir sonraki mavi alan ise j değişkeni için bellekte ayrılan alanı temsil etmektedir...
For döngümüz normalde 10 sayı okumak zorundadır ancak küçük(!) bir programlama hatası sonucunda for döngüsü 11 kez çalışmakta ve 11 sayı okumatadır. Bu nedenle en son okunan değer hafızada i değişkeni için ayrılan kırmızı renkli hafıza alanına taşmaktadır...

For döngüsü döngünün hangi adımda olduğunu kırmızı renkli alana, yani i değişkeninin değerine bakarak takip ettiği için meydana gelen bu taşma i değişkeninin değerini, dolayısı ile for döngüsünün akışını değiştirmektedir...

Bu nedenle taşma olduğu anda 10 değerinden daha küçük bir değer girilmesi durumunda döngü başa sarmakta ve sayı okumaya devam etmektedir. Bu aşamada negatif değerler girmek suretiyle programın olması gerekenden çok farklı bellek adreslerine yazmaya çalışması ve "Segmentation Fault" vermesi sağlanabilir...

Bellek taşması durumu her zaman bu kadar masum sonuçlar ortaya çıkartmaz. Bazı durumlarda özel olarak hazırlanan ve shellcode olarak isimlendirilen özel kod parçacıkları taşan bellek alanına yazılır ve bilgisayarın bir şekilde bu kodu çalıştırması sağlanır. Sonuç olarak çalışmakta olan yazılım üzerine vazife olmayan bir iş yaparak sistemin kırılmasına neden olur. Ancak bu durum genellikle öğrencilere anlatılmaz yada bu durumu anlatabilecek yetkinlikte hoca bulunamaz. Bu nedenle okulda programlama öğrenen ve yalnızca okulda öğrendikleriyle yetinen kişilerin yazdıkları uygulamalar kırılıp dökülmeye başlar... :(

İyi de bu kadar laf salatasını neden yaptım? Öğrencilere temel programlama becerisini kazandırmayı amaçlayan bir C kitabında yer alması için şahane bir örnek. Ben 2005 yılında bu hatalı örneği keşfettiğimden beri hala orada durduğunu görünce yazasım geldi... Buraya yazdım.. :)

Yorumlar

  1. Harun Abi Çok Güzel Bir Yazı Paylaşmıssın :) Ve düşünüyorumda daha önce niye dikkat etmedik hadi biz yeni öğrendik diyelim, Öğretmenlerin belki çocukların kafası karışır diye mi söylemiyorlar yoksa, dikkat etmediklerinden(kitabı yazan kişi hata yapmaz düşüncesinde) mi ?, yoksa bilmediklerinden mi ? Bu en basit hataymış, ve dediğin gibi tehlikeli sonuçlar doğurabilir :)

    Bende hata olmaz diye düşünürdüm ama bundan sonra her komutun üzerinden belli testler yapacağım ne olur ne olmaz :)

    YanıtlaSil
  2. Gerçekten harika bilgilendirme için teşekkürler

    YanıtlaSil

Yorum Gönder

Bu blogdaki popüler yayınlar

Crunch ile Wordlist Oluşturmak

Crunch seçilen karakter kümesinden, istenilen uzunlukta parolalar üreten ve bu parolaları bir dosyaya yazarak wordlist oluşturan kullanışlı bir araçtır. Çalışmak için özel bir yetkiye ihtiyaç duymaz. Yalnızca derlenip çalıştırılması yeterlidir. Çalıştığında istenilen karakter kümesinden parolalar üretir ve bir dosyaya yazar.
Oldukça hızlı çalışır ve kolay kullanılır.



Crunch Kurulumu
Öncelikle crunch yazılımını indirelim.
harun@gondor:~$ wget http://garr.dl.sourceforge.net/project/crunch-wordlist/crunch-wordlist/crunch-3.0.1.tgz
İndirme işlemi bittikten sonra crunch-3.0.1.tgz arşivini açalım.

harun@gondor:~$ tar zxvf crunch-3.0.1.tgz crunch3.0/ crunch3.0/Makefile crunch3.0/GPL.TXT crunch3.0/crunch.1 crunch3.0/charset.lst crunch3.0/crunch.cArşivin açılmasıyla oluşan crunch3.0/ dizinine geçelim ve ardından make komutunu vererek derleme işlemini başlatalım.
harun@gondor:~$ cd crunch3.0/ harun@gondor:~/crunch3.0$ make Building binary... /usr/bin/gcc -Wall -lm -pthread -std=c99 -m32 -D_LARGEF…

Captive Portal Ek Özellikler

PfSense üzerinde gelen Captive Portal özelliği hot spot çözümü olarak kullanılabilecek güzel bir özelliktir. Captive Portal, kablosuz ağınıza dahil olan kullanıcıların tüm internet erişimlerini engeller ve web sayfalarına erişmek isteyen kullanıcılara bir karşılama ekranı getirerek oturum açmalarını ister.

İnternete erişmek isteyen kullanıcı, kendisine ait kullanıcı adı ve parolası ile oturum açarak internet erişimi sağlayabilir. Bu nedenler kafeler, oteller ve benzeri yerler ile misafirlerini kendi yerel ağlarına bağlamak istemeyen şirketler için oldukça güzel bir çözümdür. Ancak hali hazırda var olan özellikleriyle Captive Portal yeterince kullanışlı değildir.

Bu nedenle  PfSense üzerinde bir şeyler yazmam ve sistemi modifiye etmem gerekmişti. Bu çalışma sırasında aşağıdaki özellikler sisteme eklemiştim...
Captive Portal da kullanıcı hesapları açabilen ancak sistemin geri kalan ayarlarına ulaşamayan bir sınırlı kullanıcı hesabı.Saat sınırlamalı kullanıcı hesabı açılabil…

Ubuntu, Aireplay-ng, Atheros AR9285, mon0 Channel -1 Problemi

Bir süre önce kullandığım Intel 4965 kablosuz ağ kartı ile "Channel -1" sorunu yaşadığımı ve bu sorunu çözmek için neler yaptığımı yazmıştım. Aireplay-ng ile paket sokuşturma yapmaya çalıştığımda aireplay-ng aşağıdaki hatayı veriyor ve çalışmıyordu.

21:09:28  mon0 is on channel -1, but the AP uses channel 1
Daha sonra emektar dizüstü bilgisayarımın ekran sorunları nedeniyle yeni bir makine almak zorunda kaldım. Tabii doğal olarak yeni makine (Asus N53SN) yeni bir kablosuz ağ arabirimi (Atheros 9285) demekti.

root@gondor:~# lspci | grep Wireless 03:00.0 Network controller: Atheros Communications Inc. AR9285 Wireless Network Adapter (PCI-Express) (rev 01)

Aynı sorunu bu kez "AR9285 Atheros wireless network adapter" için çözmek zorunda kaldım. Aynı şeyleri Intel 4965 için daha önce de yazdığımdan, bu kez yapılacakları kısaca özetliyorum.

İlk olarak yeni sürücümüzü indirilerim wireless.kernel.org adresinden indirelim ardından da gerekli yamaları indirip sürücü kayna…