Bu sitede bulunan bütün bilgi ve araçlar SADECE eğitim amaçlıdır, ne niyetle kullandığınız sizi bağlar ve sizin sorumluluğunuzdadır! [Demedi deme]

Hacker'ın Olmazsa Olmazı - Kernel #3 Naber Hafız

Tarih 13 Ağustos 2015. KATEGORI Bilisim

Uzuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunca bir aradan sonra kaldığımız yerden devam ediyoruz arkadaşlar. Konumuza geçmeden evvel yüksek müsadenizle biraz tatava yapma hakkımı kullanmak istiyorum.Malumunuz verilen arayla alakalı, çok detaya girmeyecek olsam da, sizinle paylaşmak istediğim şeyler var.

Beş kuruş para vermeden elde ettiğimiz bedenlerimiz ve bitiş vadesi belirlenmiş yaşam sürelerimiz biz ademoğullarına sizin de bildiğiniz üzere imtihan gereği verilmektedir. [Bknz Mülk Suresi 2. ayet] Şartlarınız nasıl olursa olsun Ali Imran Suresi 14. ayette belirlenmiş olan maddelerden en az biriyle şu an imtihan ediliyoruz ve başımıza gelen iyi ya da kötü olaylara verdiğimiz tepkiler kayıt altına alınıyor.Gün gelecek bu tepkilerin karşılığı önümüze konulacak. Allah hepimizi kazananlardan eylesin. [aminnnnn]

Hakkımda kısmını okuyan arkadaşlar bilir, girdiğim birçok üniversiteyi yarıda bırakarak hayatıma fahri diplomalı olarak devam ediyordum.Bu sene itibariyle Bilgisayar Programcılığı [Uzaktan Eğitim] bölümünü bitirerek önlisans diploması almaya hak kazandım. Yaşasınnnnn çoook mutluyum modunda olmasam da geçirdiğim 2 sene boyunca hafızamda yer edinen, ve her daim memnuniyetle anacağım tek kişi olan Hatice AKKAYA hocama buradan sizlerin huzurunda tekrar teşekkür etmek istiyorum. Hocam bu yazımı size ithaf ediyorum.

Sözel mevzuları hallettiğimize göre azlafçokiş kısmına geçelim ve konumuz olan Memory Management yani hafıza yönetimine yumuşak ama bir o kadar da çakal bir giriş yapalım.Aslında niyetim önce teorik bilgilere yüklenip sonrasında uygulamalı kısma geçmekti fakat hem verilen uzun ara hem de üzerimdeki ölü toprağından rahat kurtulabilme adına uygulamalı kısmı öne alıyorum. [itirazı olan ?!]
Bu yazı bundan sonraki yazı kim bilir belki ondan sonraki yazı da hafıza yönetimi ile alakalı olacak deyuu deyuu tütütü 41 kere maşaAllahla beraber okuyucularımızı gözden nazardan arındırarak yazımıza geçiyoruz.

Neredeyim Ben?

Önce hayali senaryomuzu yazalım, sonra yazdığımızı güzelce bi oynayalım.Bir makineye oturduk, tabii ki de linux kurulu bir makine, kısıtlı yetkileri olan kullanıcı girişimiz var ama bilmediğimiz bir sebepten ötürü nereyi bırkalamak istesek engelleniyoruz. Ultra süpersonik akıllı admin belirli komutların çalıştırılmasını engelleyen bir program hazırlamış ve bizim de bundan kurtulmamız gerekiyor.Farzı misal ya engelleyen programın PID numarasını bulsak yetecek bize.Neyimiz var neyimiz yok diye baktığımızda admin gardaş programını bulamayalım diye ps komutuna erişimimizi engellemiş durumdayken dmesg ile kernel mesajlarını okuyabildiğimizi varsayalım.Pekala neler yapabiliriz diye düşündüğümüzde elimizde bir metin editörümüz ve yazıp derleyebileceğimiz tonlarca C kodumuz mevcut, hayde bakam parmaklara kuvvet.

Hack nedir sorusuna Assembly serisindeki Badi Buyuldink yazısında zaten cevap vermiştik, ama bazı arkadaşların okumadığını varsayarak konumuzla alakalı kısmı tekrarlayalım. Bize verilen yetki seviyesini beğenmediğimizden ötürü öyle ya da böyle engellerden kurtulmanın yolunu bulmak zorundayız. Exploit denilen meret de bu işe yaramıyor mu zaten. Her ne kadar bu yazımızda bir exploit yazmayacak olsak da sistemin güvenliği için kernele eklenmiş bir özelliği çıkarımıza kullanarak ps komutuna erişmemizin engelleniyor olmasını bertaraf etmeyi başaracağız diye hayaller kuruyorum.Vakit hayalleri gerçeğe çevirme vaktidir. [kısa süreli politikacı modu]

Bu kadar geyikten sonra merak katsayısı yükselmeyen sayın okuyucu acilen bu siteyi terket diyerek son tehditimizi de savurduğumuza göre artık bu işi nasıl yapıcaz tarifine başlayalım. Bahsi geçen özelliğin adı OOM Killer yani OutofMemory Killer yaniyani Hafızadaboşyerkalmadıbenelatıyorumreis gibisinden tercüme edebiliriz.Peki ne iş yapar bu reis kardeş; kullanıcı işin cılığını çıkartacak seviyede sistemin hafızasını doldurursa belirli bir algoritmayla şanslı bir programı seçerek öldürüyor.Peki bunun bizim konumuzla alakası nedir diye soran arkadaşımıza ne cevap veririz derseniz; OOM Killer devreye girdiğinde sadece öldürdüğü programı değil sistemdeki bütün programları gösteriyor. Sonuç olarak süpersonik akıllı adminimiz bizi engelleyen programın ismini ve PID numarasını bulamayacağımızı zannetmeye devam etsin.

İntihar saldırılarının bu kadar popüler olduğu dönemde bir intihar bombacısı da biz kodlayalım diyorum.Bunun için sistemdeki mevcut hafızayla alakalı bütün bilgileri toplayan, sonrasında da ne kadar boş alan varsa tamamını sistemden söküp koparan programımızı yazalım.Öncelikle sistem hakkında bilgi toplayabileceğimiz fonksiyonlara bir göz atalım.İlk akla gelenler sysinfo ve sysconf fonksiyonları oluyor.Hayatımda ilk defa duyuyorum bunları diyenler hemencecik man sysinfo ve man sysconf yazıp cehellikten acilen kurtuluyor.Topladığımız bilgiler neticesinde bir sonraki başlıkta detayına gireceğimiz engelleri de aşarak OOM Killer'ı ateşlemeye çalışacağız.

Alırım Bi Dal

Fazlasıyla detay verdiğimize göre direk kodlamaya geçelim ve bilgi toplamaya başlayalım.Barnak basmamız gereken bir husus daha var ki; sysinfo ile topladığımız bilgilerin, programın çalışması sırasında, değişmesini engellemek adına bazı değişkenlerimizi sabitlememiz gerekiyor.[tecrübe ile sabit]

#define PAGE_SIZE       (unsigned int)(sysconf(_SC_PAGESIZE))

#define PHY_PAGES	(unsigned int)(sysconf(_SC_PHYS_PAGES))


struct sysinfo info;
	
int ret = sysinfo(&info);

// Bilgiler hazııır ve nazııır sabitleyelim

unsigned int free_ram = info.freeram;

unsigned int free_swap = info.freeswap;

Sistemdeki saldırmamız gereken boş hafıza miktarını, bu arada swap alanını da [bu da neyin nesi deme git googledan araştır] unutmadan hesapladığımıza göre önümüze çıkan ilk engeli inceleyelim.Sebebini bir sonraki yazıma bırakmakla beraber iki cigabayttan fazla taleplerimiz direk ENOMEM uyarısıyla birlikte reddedilmektedir.Bu yüzden iki cigabayttan azı ve fazlası için iki farklı metoda ihtiyacımız olduğunu belirtmek zorundayım.Önce basit olan kısmına el atalım.

void *ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// İstemesine istedik de alabildik mi ?

memset(ptr, 0,size);
// Ne gerek vardı bu memsete acaba ?

mmap komutuyla talep ettiğimiz hafıza miktarını başarıyla alsak bile OOM Killer'ın devreye girmesi için dürtmemiz şart olduğundan memset ile kıpraştırıyoruz. Bunun da haricinde kernelin tehditi farkedip sistemi kurtarmak adına harekete geçmesini sağlayacak uzunlukta bir süre hafızayı işgal ederek baskımıza devam edicez.Bunu nasıl yapıcaz, tabii ki programın bitişini engelleyerek, en basitinden getchar fonksiyonu yeter de artar bile.

İki cigabayttan az hafıza durumları, kaynak kodunda göreceğiniz üzere, çok basit olmasına rağmen mevzu iki cigabaytın üstüne çıktığında olay karmaşık bir hal alıyor.Programın bu kısmını SANA bırakıyorum.Nasıl yani diye soran arkadaşlar; hem ilgili arkadaşları desteklemek hem de konularımızı daha eğlenceli hale getirmek adına ödüllü bir yarışma düzenlemeye karar verdim. Yarışma detaylarını en sondaki başlığa bırakarak niye yaptık şimdi biz bunu diye düşünen arkadaşlara birazcık vaaz vermek istiyorum.

Burada başarmaya çalıştığımız şey; önümüze bir engel çıktığında bunu aşmak için saldırdığımız sistemi iyi tanımamız gerektiğini ortaya koyabilmektir.PID numarasını bildiğiniz bir uygulamayı sonlandırma şansımız yok, sonuçta yetkimiz ona da yetmeyecek fakat NASIL saldırabileceğimiz hakkında bilginiz varsa, işte o zaman böyle olmadı şöyle denerim, şöyle olmadı böyle dalarım deme şansınız oluyur.Yani neticeden ziyade şu an için derdimiz HATİCE [hürmetler hocam] ile olduğunu anlamış bulunuyorsunuz diye ummaktayım.Vaazımız bittiğine göre hafızayla alakalı temel oluşturma adına farklı bir konuya ahanda az aşağıda giriş yapıyoruz.

Çarşaf Liste

Binlerce sayfalık kitapların anlattığı konuları birkaç blog yazısıyla sizlere aktaramayacağımıza göre, en azından temel oluşturabilecek bilgileri hafif dozda enjekte etmeye çalışıyoruz. Mesela yazdığımız programlarda dinamik hafıza kullanımı için kullandığımız bölüme heap diyoruz.Forekzampıl malloc ile azıcık yer isterken free ile al senin olsun lazım değil dediğimiz fonksiyonların tamamı heap ile alakalı mevzulardır.Peki bu heap nasıl yönetiliyor, yani arka planda neler dönüyor onu biraz bırkalayalım istiyorum.

Heap Overflow diye bi ton zaafiyetten bahsediliyor ya, konuyu anlamak daha da önemlisi sömürebilmek adına bu işin temeline ineceğiz arkadaşlar.Başlıktan anlayacağınız üzere ortada bir liste yönetimi var.C programlama konusunda fazlasıyla mürekkep yalamış, zaman harcamış arkadaşlar bilir, linked list yani bağlanmış listeler denen bi hikayemiz var. Bu konuya her ne kadar heap ile alakalı diye girdiysem de kernelin birçok yerinde [bayaaaa birçok] kullanıldığını da hatırlatayım.Önce seçenekleri listeyelim,sonrasında da kernel bu liste olayına nasıl el atmış alakalı yerlerden bahsedelim.

Liste yönetimi için kullanabileceğimiz üç tane seçeneğimiz var; single linked list yani bizdegerivitesyokgardaş modu, double linked list yanihemilerihemgeri modu ve son olarak da circular linked list yani baştansonasondanbaşa modu gibisinden açıklayabileceğimiz sizin de bi cacık anlamadık diyebileceğiniz seçenekler.Programcılık tecrübesi olanlar ya da algoritmalara meraklı arkadaşların bu konulara hakim olabilir, fakat hakim olmayanlar için başlıkları paylaştığımıza göre hemen gidip googledan örneklere bakıyoruz, mümkünse kendimiz de birkaç örnek yapıyoruz.[Zahmet olcak biraz ama]

Gelelim kernelin bu mevzuya nasıl el attığına; bunun için ilk başvuracağımız kaynak serimizin başından beri yaptığımız gibi cross reference kullanmak.Araştırma neticesinde mevzunun kaynağını include/linux/list.h adresinde buluyoruz.Liste yönetimi için kullanılan macrolara ve fonksiyonlara göz gezdiriyoruz, mesela şunun gibi.

117  * list_replace - replace old entry by new one
118  * @old : the element to be replaced
119  * @new : the new element to insert
120  *
121  * If @old was empty, it will be overwritten.
122  */
123 static inline void list_replace(struct list_head *old,
124                                 struct list_head *new)
125 {
126         new->next = old->next;
127         new->next->prev = new;
128         new->prev = old->prev;
129         new->prev->next = new;
130 }
131 

Konuyu bırkaladınız, örneklere baktınız, kesmedi siz de basitinden örnek yaptınız şimdi gidip Heap Overflow mevzusu neyin nesiymiş, free fonksiyonundaki unlink metoduyla daha sene 2001 yılı iken Solar Designer Reis nasıl exploitler hazırlamış anlamanız birazcık daha kolaylaşır [üzgünüm ama kaynaklar tamamen ingilizce].Adamlar bu mevzuyu anlatmak için eşşek yükü anlatım yapmış, bi ton kod yazmış ne yapayım yani ben de anca yol gösteriyorum.Müsadenizle bir sonraki başlığa geçiyor, yazımıza devam ediyoruz.

Al Senin Olsun

Yarışmanın detaylarına geçmeden evvel çıkarımıza kullandığımız OOM Killer hikayesinin, ihtiyaç duyabilecek sistem admini arkadaşlar için, savunma kısmına da bir göz atalım.Çünkü süpersonik akıllı olan admin ufak bir parametre değişikliği ile bütün yaptıklarımızı boşa çıkartabilirdi, görelimmm.

root@kali:~/ cat /proc/sys/vm/oom_dump_tasks
1   <--- [OOM Killer devreye girerse herşeyi dökerim ortaya]

root@kali:~/ sysctl vm.oom_dump_tasks=0
vm.oom_dump_tasks=0
[Geçmiş olsun biladeerrr]

Yarışmanın detaylarına gelecek olursak sevgili arkadaşlar; sadece ve sadece üçbeş hadi olsun sekizon satır kod yazarak iki cigabayt üstündeki hafızalar için OOM Killerı tetiklemeyi başaran kodu ilk gönderen talihlimize bir adet Raspberry Pi Model B hediye ediyorum.Zaman sınırlaması yok fakat ilk gönderen kazanır, kazanan arkadaşın yazdığı kodu da, kendisi de onaylarsa, buradan sizlerle paylaşmayı planlıyorum.

Spotlight Image
Resimde yok ama kabıyla hediye ediyorum.

Verdiğin uzun ara boyunca birçok arkadaştan mesajlar aldım, yazılara devam etme konusunda, her birine tek tek teşekkür ediyorum.Vaktim oldukça, hevesim de tabii, en azından bu seriyi tamamlama konusunda kararlıyım.Bunun haricinde yardım istediğiniz birçok email aldım, bazılarına cevap verdim, bazılarını ise direk sildim. Buradaki belirleyici unsur tamamen kullandığınız uslüp ve sorduğunuz sorunun kalitesinden kaynaklanmaktadır.Unutmayın ben sadece yardım edebilirim, işi gücü bırakıp sizinle uğraşamam, malumunuz hepimizin kendi meşguliyetleri var.En derin saygı ve hürmetlerimle, bir sonraki yazıda görüşmek dileğiyle.[bu sefer arayı çok açmıcam inşaAllah]

Oynatalım Uğurcum

Yazı için hazırlanan videoyu YouTube'dan izleyebilirsiniz.

Yazı için hazırladığımız OOM Killer tetikleyici programını bu adresten indirebilirsiniz.

Yorumlar (20)

  • atilla

    atilla

    14 Ağustos 2015 20:15 zamanında |
    ilk yoruma bi ödül yok mu hocam malumunuz bu yazdıklarınızın sadece geyik kısmını anlayabilen bi okurunuz olarak yapmam olanak dışı ama nefis işte çekiyore :)

    yanıtla

    • K.A.

      K.A.

      15 Ağustos 2015 13:04 zamanında |
      Atilla kardeşim,
      Gönül ister ki herkese hediyeler verelim ama çözüm için uğraşanlara haksızlık olur :)

      yanıtla

  • Furkan Sandal

    Furkan Sandal

    18 Ağustos 2015 15:39 zamanında |
    Kenan abicim, öncelikle yazıların için teşekkür ediyorum. Bir linux kullanıcısı olsamda, linux kullanmayı bilmiyorum sizin tabirinizle :) Üç beş bişeyler öğreneyim dedim de onuda beceremedim :) İlk serinizi sonuna kadar okuyup dinledim. Heykırın olmazsa olmazı bölümünü. Malum Mint kullanıyordunuz ben ise, Kali linux. :)

    Kusura bakmayın abicim videonuzun birini yani tek anladığımı almıştım ancak şimdi silmiş bulunuyorum blogumda ise, alıntı linkinizi vermiş olsamda izniniz olmadan paylaştığımdan konuyu siliyorum. Emeğe saygı diyelim.

    Ellerinize sağlık anlatımlarınız için.

    yanıtla

    • Furkan Sandal

      Furkan Sandal

      18 Ağustos 2015 15:41 zamanında |
      Taglarınızdan, beleş raspberry pi de dikkatimi çekmedi değil ne alemsiniz abicim :) :) :) :) :)

      yanıtla

      • K.A.

        K.A.

        18 Ağustos 2015 16:03 zamanında |
        Al senin olsun Furkan? :)

        yanıtla

    • K.A.

      K.A.

      18 Ağustos 2015 16:03 zamanında |
      Kaynak göstererek yazıları da videoları da paylaşabilirsin Furkan, "Anasayfa" en altta da belirttim, hiç umrumda değil. Yeter ki kimse çıkıp "ben" yaptım demesin..

      yanıtla

      • Furkan Sandal

        Furkan Sandal

        18 Ağustos 2015 17:07 zamanında |
        Abicim, tam olayı kavrayamadım. Benim pc 2gb 1982mb ram var. oom tetikleyici devreye girmiyor. Amaç bunu devreye sokmakmı ? Eğer 1982 az ise, +2gb ram cloud sunucudamı test edeyim ? Videoyu izledim yazıyı okudumda, amaç bunu devreye sokmak mıdır ?

        yanıtla

        • K.A.

          K.A.

          18 Ağustos 2015 17:59 zamanında |
          Furkan,
          Şu an devreye girmiyorsa, cloud sunucuya gerek yok. Kendi bilgisayarında devreye sokabildiğin an, kodunu gönder bakalım.Aynı kodu 4 GB bir sanal makinede test edicem, OOM Killer tetiklerse Raspberry senin :)
          32 bit her makine uygundur..

          yanıtla

          • Furkan Sandal

            Furkan Sandal

            18 Ağustos 2015 19:09 zamanında |
            Beceremedim abi ya sağlık olsun :) Sadece limit değerlerini değiştirince çalıştı o kadar. Ama aynı şey cloud için söyleyemem. :'(

            yanıtla

  • Furkan Sandal

    Furkan Sandal

    18 Ağustos 2015 17:09 zamanında |
    Abicim birde, 32bit kullanıyorum serverda.

    yanıtla

  • L.A

    L.A

    19 Ağustos 2015 05:59 zamanında |
    #include
    #include
    #include
    #include

    #define SIZE 1024 * 1024
    main( int argc, char *argv[] )
    {

    while(1) {
    void *ptr;
    fork();
    ptr = malloc( SIZE );
    printf("addr = %X\n" , ptr);
    }


    return 0;
    }

    yanıtla

  • L.A

    L.A

    19 Ağustos 2015 06:04 zamanında |
    stdio.h
    stdlib.h
    unistd.h
    sys/types.h

    yanıtla

    • K.A.

      K.A.

      19 Ağustos 2015 07:01 zamanında |
      Fork bomb tercih etmişsin, karar senin, kodu test edip onaylıcaz sonrasında Raspberry senindir, sonuçta ilk gelen cevap sana ait..

      yanıtla

      • K.A.

        K.A.

        19 Ağustos 2015 15:56 zamanında |
        Malesef yöntem doğru olsa da bazı eksiklerden dolayı OOM Killer tetiklenmiyor, yarışma devam etmektedir.

        yanıtla

  • Ömer Göktaş

    Ömer Göktaş

    23 Ağustos 2015 03:14 zamanında |
    C Kodunu yazdım, aşağıdaki linkten temin edebilirsiniz.
    https://yadi.sk/d/ekQA9cZliboiB

    Hafıza ayırma işlemlerini parça parça child process ler içerisinde yaptım. Her bir process bitiminde getchar ile duruyor, yani programı sonlandırmak için en son konsolda bir kaç kez enter lamanız gerekebilir. Önemli değil, Ctrl+C de yapabilirsiniz. Program neredeyse var olan tüm boş belleği sömürüyor ve dolayısıyla OOM Killer devreye giriyor ve belirli bir skorlamaya göre bazı process leri sonlandırıyor. Ancak şöyle bir durum var, OOM Killer'ın sonlandırmak için seçtiği process genelde child process oluyor, dolayısıyla OOM Killer devreye girip belleği açmak için child process i öldürdüğünde ana programda "Killed" diye bir yazı beklemeyin, çünkü öldürülen ana program değil, child process oluyor. Bir önemi de yok, nasıl olsa OOM Killer devreye giriyor ve dmesg ile kernel mesajlarına baktığınızda diğer tüm processlerin pid leri ile birlikte öldürülen child process in de pid sini görebiliyorsunuz. Yani hack amacına ulaşıyor. OOM Killerin devreye girmesi için programda bellek ayırma işlemlerinin tamamlanmasının ardından "Bitti: OOM Killer bekleniyor" yazısını gördükten sonra yaklaşık 10 saniye bekleyin. Daha sonra programı sonlandırabilirsiniz, zaten büyük ihtimalle child processlerden birisi öldürülmüştür çoktan. Ayrıca unutabilme ihtimalinize karşı programı en az 3 GB ve üstü ram olan bi linuxde denemeniz gerekir, malum yarışma koşulları, "OOM Killer'ı 2GB ve üzeri allocation larla devreye sokma".

    Saygılarımla
    Ömer Göktaş

    yanıtla

    • K.A.

      K.A.

      23 Ağustos 2015 16:03 zamanında |
      Tebrikler Ömer, kodun gayet düzgün çalışıyor ve böylece Raspberry Pi senin oluyor. Açıklaman da gayet güzel olmuş, eline sağlık..

      yanıtla

      • Ömer Göktaş

        Ömer Göktaş

        23 Ağustos 2015 16:21 zamanında |
        Ülkemizde böylesine teknik konularla ilgilenip, ilgilenmekle de yetinmeyip insanımızı teşvik etmek için böylesine güzel videolar ve yarışmalar düzenlediğiniz için ben teşekkür ederim.

        yanıtla

  • Kerim Can Kalıpcıoğlu

    Kerim Can Kalıpcıoğlu

    21 Şubat 2016 18:17 zamanında |
    Abicim,

    Ben her şartta zorlamayı kendine ilke edinmiş bir kardeşinizim ve yazılımını değiştirerek koşul yerinde bildiğin cayır cayır prosesleri kopyalayarak başarıyı elde ettim -bildiğin fork bombası gibi oldu- yukarıdaki çözüm tabiyiki daha kaliteli ve hoş olmuş -RPI'yi de kapmış- onu da inceledim. Yukarıdaki fork bombası kardeşin/abinin hatası da proseslerin bitmesi olmuş sanırsam. Garbage collector yok diye çok güvenmemek lazım. Ben de çözümümü paylaşmak istedim, ellerine sağlık.

    yanıtla

    • K.A.

      K.A.

      25 Şubat 2016 13:25 zamanında |
      Kerim,
      Bak görüyorsun değil mi, zamanında siteden haberin olaydı RPI senin olacaktı ama herşey nasip. Neyse ya yeni yazıya da bir ödüllü soru koyarız :)

      yanıtla

Bir yorum yapın

Misafir olarak yorum yapıyorsunuz.