Başlangıç > Saldırı teknikleri > 64 bit Vista Kernel Rootkit çalıştırmak

64 bit Vista Kernel Rootkit çalıştırmak

https://i2.wp.com/cdn2.digitaltrends.com/wp-content/uploads/2011/04/security-breach-hack-hackers-epsilon.jpg
Kötü niyetli yazılımlarla savaşmaya niyetli olan Microsoft normal kullanıcılar için tasarladığı Vista da birçok yeni güvenlik önlemi getirdi. Bu güvenlik amaçlı özelliklerden ilk akla gelenler UAC (user account control), DEP(Data Execution Prevention), ASLR(Address Space Layout Randomization), bitlocker, yeni firewall ayarları, vb…[1]. Ama bu saydığım özelliklerin hepsi kullanıcı (user) mod da geçerli olan özellikler.

Tespit edilmesi ve temizlenmesi en güç olan Kernel modda çalışacak olan rootkitler için ise en dikkat çekici özellikler KMCS(kernel mode code signing) ve Patchguard[2]. Maksat bilineni değil bilinmeyi göstermek. Ben de bu yazımda bu iki güvenlik önlemini aşıp, acaba bir rootkit yükleyelebilir miyiz dedim ve araştırdım. Sonuç olarak biraz uzun sürdü, ama sanırım bir şeyler başardık. Bu çabamı da şimdi yazıya dökmeye çalışacağım.

Kernel Mode Code Signing (KMCS) özelliğini aşma
Diğer adıyla “Code integrity verification” kısaca; eğer kernel de çalışacak bir aygıt sürücüsünü (device driver) bilgisayarınıza yüklemek istiyorsanız, o driver kodunun güvenilir sertifikasyon makamlarından alınmış bir sertifikayla imzalanmış olması gerekir[3]. Tabiki bu güvenilir sertifikasyon makamları Microsoft tarafından güvenilir olanlar. Sonuç olarak belki herkes sürücü (driver) yazabilir ama 64 bit Vista’da çalıştıramaz. Diğer bir deyişle, öyle her önüne gelen bir kernel mode rootkit veya kötü niyetli bir sürücü yazıp çalıştıramaz. Şu anki rootkit popülasyonuna bakarsak da bu yeniliğin gerçekten de işe yaradığını söyleyebilirsiniz.
Evet, Microsoft iyi düşünmüş. Fakat maalesef her şey onlarda bitmiyor. Siz güvendiniz ve bir şirkete sertifika verdiniz, ama bu adamların yazdıkları sürücülerin içeriğini nasıl kontrol edeceksiniz. Ya kötü niyetli bir çalışanları varsa veya kötü niyeti bırakın sadece yazdıkları kodda bir hata varsa? Evet, yüz binlerce aygıt (device) olunca milyonlarca sürücü (driver) olacaktır. Bu milyonlar içinden de yüzlerce ve hatta binlerce hata çıkacağını düşünmek garip değil bir gerçektir. Öyle de oldu, belki binlerce olan hatalı sürücüden birisini Joanna Rutkowska ve ekibi tespit etti [4]. Sağ olsunlar, bu açıklığı sunmakla da kalmadılar. Bu açıklığı kullanarak Vista’daki bu yeni özelliği nasıl devre dışı bırakabiliriz, onun da yolunu gösterdiler.

Tabi hazır elde hatalı bir güvenilir sertifikalı sürücü ve “KMCS özelliğini nasıl kapabiliriz?” sorusuna teorik de olsa bir cevap olduğunda, birilerinin exploitini yazması uzun sürmeyecektir. Tahmin ediyoruz ki malware yazarları boş durmadılar ve biliyoruz ki güvenlik uzmanları da boş durmadılar. Alex Ionescu da bunlardan belki de ilki [5]. Alex, kendi sitesinde PoC(proof of concept) bir kod yayınladı fakat daha sonra driver yazarı şirketin henüz bir yama yayınlamadığını öğrenince sayfasında yayınladığı kodu kaldırdı. Fakat belki birkaç saat sitede kalan kod baya büyük bir hit aldı ve adı “purple pill” olarak nam saldı.

Sanırım bu kadar hikâye yeter. Ben ne yaptım ona dönelim. Ben maalesef “purple pill”e yetişemedim. Ama şunu öğrendim ki bu iş yapılabilir. Üzerinden baya zaman geçti ama şunu gayet iyi hatırlıyorum. Benim gibi bu tür bir işe yeni başlayan birisi için hiç de kolay olmadı. İlk önce Windows sistemlerini, kernel mode – user mode farkını, device driverların ne olduğu, nasıl kullanıldığını, uzmanlık düzeyinde olmasa da iyi düzeyde debug tekniklerini ve normal olarak biraz assembly ve C programlamasını bilmek gerekiyor. Ben sıkıcı öğrenme kısmını atlayayım, özetle bu exploiti nasıl yazarız onu anlatayım.

Atdcm64a.sys Exploit
Exploit yazımına geçmeden önce kullandığımız araçlardan biraz da olsa bahsetmekte fayda var. Reverse engineering (tersine mühendislik) yapacağım. Bu yüzden ilk gerekli araç IDA pro programı olsa gerek [6]. Zaten bu yazıda gösterdiğim assembly kodlarının hepsi IDA pro aracılığıyla unassembly yapılmış kod parçaları. Diğer gerekli araç bir debug programı. Benim önerim WinDbg [7]. Onun dışında sürücü derlemek için ve sürücüler hakkında bilgi edinmek için en son WinDDK gerekli [8].

Bu işe başlarken elimizde öyle iki önemli bilgi var ki bunlar aslında işe başlamak için gerek ve yeter şart olan bilgiler. Birincisi hangi sürücünün hatalı olduğunu ve hatanın bu sürücünün neresinde olduğunu biliyoruz. Ayrıca, bu açıklıkla kernel hafızasındaki herhangi bir yerdeki değeri istediğimiz gibi değiştirebileceğimizi biliyoruz. İkinci bilgi olarak elimizde değiştirmek isteyebileceğimiz çok güzel bir hedef var. Bu hedefi tutturursak KMCS özelliğini devre dışı bırakabiliriz. Sonuçta bu bilgiler ışığında amacımız aslında gayet açık: bu bilgileri yerinde kullanarak hedef adresteki değeri hatalı sürücü vasıtasıyla değiştireceğiz, bu değişiklik sonunda KMCS devre dışı kalacak ve istediğimiz bir kernel rootkitini çalıştırabilir hale geleceğiz.

İlk bilgi olarak elimizde Joanna Rutkowska’nın [4] sunumundan Şekil 1’deki bilgi bilgi mevcut:

Şekil 1. Açıklık içeren sürücüden bir kod parçası

Yapmamız gereken şey sürücüdeki bu kod parçasının istediğimiz değerlerle çalışmasını sağlamak. İstediğimiz değerlerle çalışmasını sağlamaktan kastımız bu kodun hangi hafıza adresine hangi değeri yazacağını belirtebilmek. Aslında bu fonksiyona sürücü kodu içerisinde baştan nasıl gelindiği IDA pro yardımıyla takip edildiğinde Şekil 1’deki mov rax,[rsp+38h+Irp_buffer] assembly komutundaki (instruction) değerin doğrudan kullanıcı (user) modda tanımlanan ve doldurulan arabelleğin (buffer) adresi olduğu görülecektir.

Sanırım burada bir not düşmek lazım. Kodu takip etmekten kastım, hangi değişkenin ve değişken adresinin hangi stack adresinde veya registry’e tutulduğunu takip etmek. Ancak bu tür bir takip sonucunda assebmly kodunun biraz olsun ne yapmaya çalıştığı anlaşılabilir. Peki nasıl oldu da kodun başından yukarıdaki fonksiyona kodun nasıl geldiğini takip ettik? İşte orası biraz uzun ve sıkıcı. Meraklısı çıkarsa onun hakkında ayrı bir yazı yazabilirim.

Tamam, peki yukarıda edindiğimiz bu bilgi ne işe yarar? Bu bilgi ışında aslında şunu öğrendik. User modda bu sürücüyü kullanan programımızda göndereceğimiz arabelleğin ikinci ve sekizinci baytları (byte) arasına yazmak istediğimiz adres değerini (64 bit olduğu için adresler sekiz bayt uzunluğunda), dokuzuncu baytına da yazmak istediğimiz değeri girmemiz yeterli.

Gayet kolay değil mi. Fakat asıl sorun başka. Bir kere yukarıdaki kod parçasını sürücünün çalıştırmasını nasıl sağlayacağız? Sürücüleri kullanmak için I/O (input output) control code (IOCTL) denilen kodlar kullanılmakta [9]. IOCTL koduyla bağlandığınız sürücünün ne yapmasını istediğinizi belirtiyorsunuz. Bizim de yapacağımız bu. Öyle bir IOCTL kodu oluşturmamız lazım ki sürücü kendi içinde istediğimiz bölüme ulaşsın ve çalıştırsın.

Şekil 2. #define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)

Normalde yine “IDA pro yardımıyla programın akışının kontrol kodlarına göre değişmesini takip etmenin” işimizi görmesi gerekir (aşağıdaki çıkmaz sokağa ulaşıncaya kadar):

Şekil 3. Programdaki çıkmaz sokak

Bu nasıl bir çıkmaz sokak? Buraya kadar çalışan program, bundan sonraki akışını hafızadaki bir tablodan okuyacağı değerlere göre belirliyor. Yani IDA pro ile statik analiz yaparak jmp komutunun nelere neye göre atladığını bilemiyoruz. Tek çare (en azından benim bildiğim) sürücüyü yükleyip çalıştırmak ve bir debuggerla sürücünün okuduğu bu tabloyu (table) bulup okumak. Ondan sonrası birkaç denklem çözümü. (Bilemezsiniz ortaokul matematiği olsa da öğrendiğim matematiğin burada işe yaraması beni ne kadar sevindirdi). Ben sizi işin matematiğinden kurtarayım. Sonuç IOCTL Şekil 4’te.

Şekil 4. Sonuç IOCTL

Bundan sonrası gayet açık. Artık istediğimiz hafıza bölgesine user moddan eğer aygıt sürücüsünün yetkisi varsa yazabiliriz. Niye yetkisi varsa diyorum. Çünkü bazı hafıza bölgelerini işletim sistemi özellikle koruyor ve kendisi dâhil herkese sadece salt okunur (read only) yetkisi veriyor. O bölgeler de başka yöntemlerle değiştirilebilir fakat azami dikkat gerektirir.

Peki herhangi bir kullanıcı, yazdığımız exploit programını kullanabilir mi? Hem evet hem hayır. Eğer exploit için kullandığımız sürücü daha önceden bilgisayarda yüklü ise bir kullanıcı administrator olmasa da bu exploiti kullanarak istediği hafıza adresine yazabilir. Fakat eğer bu sürücü daha önceden yüklü değilse, ilk önce yüklenmesi gerekir ki bunun için administrator (yönetici) haklarına ihtiyaç bulunmaktadır.

Administrator haklarına sahip olmayan bir kullanıcın device üzerindeki haklarını görmek için kartoffel programı [10] kullanılabilinir:

Şekil 5.Karroffel programı

Bütün kullanıcılar işin okuma ve yazma hakkı verilmiş ki bu çoğu zaman gereksizdir. Bu yüzden eğer sürücü daha önceden yüklüyse herhangi bir kullanıcı sürücüyü istediği gibi kullanabilir.

Şimdi gelelim yukarıdaki bilgilerle ne yapacağımıza. Amacımız KMCS özelliğini devre dışı bırakmak. Bunun için elimizdeki ikinci önemli bilgiyi kullanacağız [4].

Şekil 6. SeValidateImageHeader fonksiyonu

SeValidateImageHeader fonksiyonu işletim sisteminde sertifikası geçerli olmayan bir aygıt sürücüsünün yüklenip yüklenmeyeceğine karar veren fonksiyondur. Özellikle cmp cs:g_ciEnabled,0 komutu. Manası; eğer g_ciEnabled adresindeki değer 0 ise kontrol etme, onun dışında başka bir değer ise kontrol et. Sanırım mesele anlaşıldı :). Yani yukarıdaki açıklığı kullanarak bu adresteki değeri 0 yaparsak istediğimiz sertifikasız sürücüyü yükleyebiliriz.

Bir Rootkit Demosu
Buraya kadar beni takip edebildiyseniz geldiğimiz noktada artık bir 64 bit Vista’da kernel mode rootkit yükleyebilir konuma geldiğimizi biliyorsunuz. Ben de madem buraya kadar geldik şu işi bitirelim ve bir tane yükleyeyim dedim.

Size ikinci önemli yenilik olan Patchguard’dan çok bahsetmedim [2]. İşte bu noktada kısaca diyebilirim ki KMCS özelliğini devre dışı bırakmanız kernel mode rootkit yazıp rahatlıkla çalıştırabileceğiniz anlamına gelmiyor. Özellikle eski birçok rootkit tekniği artık Patchguard sayesinde etkisiz hale getirilmiş durumda. Eski bir tekniği kullanarak işletim sisteminde yapmış olduğuz bir değişiklik, devamlı çalışan ve önemli sistem tablolarını ve nesnelerini kontrol eden PatchGuard tarafından tespit edilirse karşınıza BSoD (Blue Screen of Dead) çıkacaktır. Yani kernelde neyi çalıştıracağınıza çok dikkat edin.

Bu iki yeni koruma yüzünden benimde İnternet’te yaptığım örnek rootkit kod taramaları sonuçsuz kaldı. Sadece Vista 32 bit için bir kod örneği bulabildim. Bu örnekte IRP Hooking tekniği kullanılarak istenilen ağ bağlantısı normal kullanıcılardan gizlenebiliyordu. IRP Hooking tekniği Patchguard tarafından kontrol edilmeyen bir değişiklik yapıyor o yüzden 64 bit bir Vista’da kullanmak için bir sakınca yok. Fakat 32 bit kernel mode kodun 64 bitte çalışması için önemli değişikliklerin yapılması gerekiyordu. Biraz tersine mühendislik ve debugging çalışması sonucunda o kısmı da hallettim. Ben ayrıntılarını başka bir zamana saklayarak sizinle sonuçlarını paylaşayım.

İlk önce açıklığından faydalanacağımız sürücüyü yükleyelim:

Şekil 7. Sürücünün yüklenmesi

“mngDrv.exe“ benim yazdığım bir sürücü kayıt programı. Örneklerini rahatlıkla bulabilirsiniz. Sürücü sertifikasını kontrol etmek için kullandığım sigcheck.exe’yi [11] İnternet’ten indirebilirsiniz. Şimdi kaydını yaptığımız sürücüyü çalıştıralım:

Şekil 8. Sürücü servisinin başlatılması

Sürücümüz onaylı bir sertifikaya sahip olduğu için bir sorun çıkmadı. Şimdi yazdığımız yeni rootkiti deneyelim:

Şekil 9. Rootkit’in çalıştırılması

Zaten farklı bir sonuç da beklemiyorduk. Sertifikası olmadığı için sürücümüzü kayıt ettirsek bile çalıştıramıyoruz. Madem öyle, şimdi sıra kerneli hacklemeye geldi.

Şekil 10. Kernelin hacklenmesi

Şimdi rootkit sürücümüzü bir daha çalıştırmayı deneyelim.

Şekil 11. Rootkit’in tekrar çalıştırılması

İşte bu. Fakat sonuç ne oldu? Bu rootkitimiz bilgisayarımızda açılmış olan herhangi bir network bağlantısını normal kullanıcılardan saklamamızı sağlıyor. Bende kodu local (yerel) portu 135 olan TCP bağlantılarını gizleyecek şekilde ayarladım. Bilgisayarımızda normal bir netstat çıktısı aşağıdaki gibi:

Şekil 12. Netstat çıktısı

Rootkitimizi çalıştırdıktan sonra:

Şekil 13. Rootkit çalışırken Netstat çıktısı

İki resim arasındaki farkı buldunuz mu? Evet, yerel portu 135 olan bağlantılar yok oldu. Asıl işin güzelliği ise netstat.exe gibi ağ bağlantılarını bakmak için NSI aygıtını (Vista standart ayfıtı) kullanan her program aynı sonucu dönecektir.

Korunma Yolları ve Sonuç

Sonuç olarak Microsoft’un yeni eklemiş olduğu güvenlik özelliklerinin işe yaradığını rahatlıkla söyleyebiliriz. Yukarıda kullandığımız açıklık Vista’nın kendisinden ziyade sürücüyü yazarı olan firmanın hatası. Peki, biz korunma için ne yapabiliriz?

Güncel sürücüyü indirip yüklemek ve UAC (User Account Control) etkin konumda tutmak bu tür bir saldırı riskini en aza indirecektir. Eğer hatalı sürücüyü kullanıyorsanız bilgisayarınıza bir şekilde ulaşan yetkisiz bir kullanıcı bu açıklığı kullanabilir. Eğer sürücüyü kullanmıyorsanız veya kendi sürücünüzü güncellediyseniz saldırganın ilk önce hatalı sürücüyü yüklemesi gerekir ki bunun için yönetici haklarına sahip olması gerekir. Bu tür bir durumda UAC’ın etkin olması saldırı riskini çok azaltacaktır.

Tamam da biz binlerce sürücümüz içinden hangisini ne zaman güncelleyeceğimizi nereden bileceğiz? İşte bu güzel bir soru. Ama cevabı güzel değil. Çünkü bunun kolay bir yolu yok. Ancak güvenliğe meraklısınızdır ve birkaç güvenlik sitesini takip ediyorsunuzdur. Yoksa normal bir kullanıcının yapabileceği pek fazla bir şey yok. Hele de bu açıklık duyurulduktan yaklaşık üç ay sonra sürücünün güncellendiğini göz önünde bulundurursak. Diğer bir taraftan, bu açıklığı kullanabilmesi için saldırganın yetkisiz bir kullanıcıyla da olsa bilgisayarınıza ulaşması gerekir. Bu da aslında saldırı riskini ciddi bir biçimde azaltmakta. Yetkisiz kullanıcıların bilgisayara erişimi karşı kendinizi nasıl korursunuz sorusunun cevabı ise bu yazının konusu dışında büyük bir konu.

kaynak : bilgiguvenligi.gov.tr

Reklamlar
  1. Henüz yorum yapılmamış.
  1. No trackbacks yet.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s

%d blogcu bunu beğendi: