Dinamik
Bağlantı Kitaplığı (Dynamic Link
Library) Mantığı
Eskiden, işletim sistemlerinin çok gelişmemiş olduğu zamanlarda, bir programcı
programını yazarken o programa özgü kütüphanelerden yararlanırdı. O kütüphanelerde çeşitli işlevler ve veri yapıları bulunurdu. Böylece programcı her
şeyi kendisi yapmadan, kütüphanelerdeki hazır işlevleri
kullanarak verimliliğini arttırırdı. Kütüphanelerden çağrılan işlevler, derleme
(compile) aşamasında programın dosyasına (exe dosyası) yerleştirilirdi. İlgili exe
dosyası kendi başına bütünlüğe sahipti: Kurulduğu bilgisayarda çok şey istemezdi: Gerek duyduğu hemen hemen her şey
zaten exe dosyasının içindeydi.
Bu durumun çeşitli
sakıncaları da vardı. Birincisi, exe dosyası
işlevlerin hepsini içerdiği için büyük oluyordu. İkincisi, exe
dosyasının içine konulan ve onun büyümesine neden olan bir
işlev çalışma zamanında hiç kullanılmayabiliyordu. Üçüncüsü, aynı kütüphaneleri kullanan birden
fazla program varsa aynı işlevler her birinin içinde
bulunuyordu. Dördüncüsü, kütüphaneler değişik
firmalardan geliyor bu kütüphanelerin güncellenmesi sorun
olabiliyordu.
Bu sorunların çaresi olarak Dinamik Bağlantı Kitaplığı
teknolojisi geliştirildi. Bu teknolojide DLL dosyaları işlevleri içeriyordu. Programlar bu DLL dosyalarındaki işlevlerden
yararlanıyordu (onları çağırıyordu). İşlevler exe dosyasının içine
yerleştirilmiyordu, çalışma sırasında
ilgili DLL dosyasından çağrılıyordu. Ek olarak,
programın içinde bulunan ama çalışma
zamanında gerek duyulmayan bir işlev ortalığı bulandırmıyordu. Son olarak, aynı
DLL dosyaları birden fazla program tarafından kullanılabiliyordu.
Tabii, bu yöntemin de bir sakıncası var: Artık programlar
kendi başına bir bütünlüğe sahip değiller. Çalışmak
için DLL dosyalarına gerek duyuyorlar. Hem de çok sayıda DLL dosyasına (kullandıkları işlevler çok sayıda DLL dosyasına dağıldığı için). Eğer bir programın çalışması için gereken DLL
dosyası o anda bilgisayarda bulunamıyorsa o program çalışamıyor.
Tasklist komutuyla çalışmakta olan uygulamaların hangi DLL dosyalarından
yararlandığını görebiliyoruz. Vermemiz gereken
komut tasklist /m:
Şekil:
tasklist /m komutu ile programların yararlandıkları
DLL dosyalarının görüntülenmesi
İlk dikkatimizi çeken
şey her uygulamanın DLL dosyalarından yararlanmıyor oluşu. Şekilde başlarda görülen uygulamalar ya hiç DLL dosyasına
gerek duymuyor ya da o anda bir DLL dosyasındaki bir işlevi kullanmıyorlar.
Basit bazı programların bile çok sayıda DLL dosyasından yararlandığını görmek şaşırtıcı. Örneğin, tasklist /m komutunun çıktısında aşağılara doğru gittiğimizde
calculator.exe dosyasının kullandığı DLL dosyalarını görebiliyoruz:
Şekil:
calculator.exe dosyasının kullandığı DLL dosyalarının listesi
Tüm listeyi incelemek yerine tek bir
uygulamanın kullandığı DLL dosyalarının listesini de alabiliriz. Örneğin, şu
anda çalışmakta olan Notepad.exe’nin hangi DLL
dosyalarını kullandığını görmek için vermemiz gereken komut tasklist
/m /fi "imagename eq
notepad.exe" şeklindedir. Aşağıdaki şekle bakınız:
Şekil:
Notepad.exe programının kullandığı dll dosyalarının görüntülenmesi
Bir
uygulamanın kullandığı DLL dosyalarını görmek için Powershell
ortamında da get-process komutunu -module parametresiyle kullanabiliriz. Notepad programının
kullandığı DLL dosyalarını görmek için verilecek Powershell
komutu şu şekilde olacaktır: get-process notepad -module
Not:
Klasik komut satırında tasklist komutunda uygulamanın
uzantısını yazarken (Notepad.exe gibi) Powershell
ortamındaki get-process komutunda uygulamanın
uzantısını yazmadığımıza dikkat ediniz.
Şimdi de bir DLL dosyasının hangi
uygulamalar tarafından kullanıldığını görelim. Bunu görmek için
tasklist /m komutundan sonra dll dosyasının adını
yazmamız gerekiyor. Örneğin, ntdll.dll
dosyasının içindeki işlevleri çağıran uygulamaları görmek için
vermemiz gereken komut tasklist /m
ntdll.dll şeklindedir:
Şekil:
ntdll.dll kütüphanesini kullanmakta olan uygulamaların listesi
DLL dosyaları çalıştırılabilir
kod içerdikleri için zararlı
yazılımların sıklıkla hedefi durumuna gelirler. Bu yüzden sistemdeki DLL dosyalarına göz aşinalığı geliştirmek, sıradışı
adlara sahip DLL dosyalarını saptamak için
iyi olacaktır. Örneğin,
hApp_Web_logoimagehandler.ashx.b6031896.dll şeklindeki DLL dosyası bir zararlı
yazılıma aittir.
Ama her zararlı yazılım DLL'i bu tür adlara sahip
olmayabilir. Hatta zararlı yazılım üretenler ilk bakışta kuşku
yaratacak dosyalar yerine yasal gibi görünen hatta yasal olan DLL dosyalarını da kullanabilir.
DLL Dosyalarını Arama Sırası
Bir uygulama yazılırken kullanacağı DLL
dosyaları belirtilir. Ama bilgisayarda belli bir addaki DLL dosyasının birden
fazla kopyası bulunabilir. Bu durumda uygulama hangi DLL dosyasını
kullanacaktır?
Uygulamanın kullanacağı DLL dosyaları için
bir arama sırası vardır. Bu sıra da şöyledir: Uygulama yazılırken DLL
dosyasının adının yanı sıra klasörü de belirtilmiş olabilir, bu durumda
belirtilen klasördeki DLL dosyası kullanılacaktır. Eğer uygulama bir klasör
belirtmiyorsa o zaman uygulamanın bulunduğu klasörde belirtilen adda bir DLL
dosyasının bulunup bulunmadığına bakılır. Uygulamanın klasöründe belirtilen DLL
dosyası varsa o dosya kullanılır. Uygulamanın bulunduğu klasörde DLL dosyası
yoksa o zaman \Windows\system32 klasörüne bakılır, bu klasörde DLL dosyası
bulunursa ondan yararlanılır. Bu belirtilen yerlerin hiçbirinde belirtilen DLL
dosyası bulunamazsa uygulama hata mesajı verip sonlanır.
Bu sıralama kötüye kullanılabilir. Yasal
bir programın ntdll.dll dosyasındaki işlevlerden yararlandığını düşünelim. Bu
DLL dosyası \Windows\system32 klasöründe bulunur. Ama kötü niyetli birileri söz
konusu programın bulunduğu klasöre kendi yazdıkları ntdll.dll dosyasını
yerleştirirse, arama sırası nedeniyle zararlı içeriğe sahip ntdll.dll dosyası
kullanılacaktır. Bu tür işlemler DLL haydutluğu (DLL hijacking)
olarak adlandırılır. Bu durum DLL dosyalarının yeri hakkında dikkatli olmamız
gerektiğini anlatır. \Windows\system32 klasörü dışındaki DLL dosyalarına
kuşkuyla yaklaşma gerekir. Tabii ki bir uygulamanın kendisine özel DLL
dosyaları da kendi klasöründe bulunabilir. Bu nedenle sistemimizi ve
uygulamalarımızı iyi tanımamız önem taşımaktadır.
Şimdi de DLL dosyalarının kötüye kullanımına
ilişkin örnekler görelim.
DLL Dosyalarının Kötüye Kullanımına
İlişkin Bir Örnek: Pingback Zararlı Yazılımı
DLL dosyaları program dosyalarıdır. Eğer
zararlı bir kodu bir DLL haline getirip çalıştırılmasını sağlarsak istediğimiz
zararlı işlemleri gerçekleştirebiliriz. Örnek olarak Pingback
zararlısı bunu yapar.
Pingback’i yazanlar
öncelikle işletim sisteminin bir parçası olan ve çalışırken çeşitli DLL
dosyalarından yararlanan bir öge saptıyorlar. Pingback
için bu öge “Dağıtılmış İşlem Düzenleyicisi” (MSDTC) adındaki hizmet oluyor. Bu
hizmet normalde otomatik başlamıyor, elle sonradan çalıştırılıyor:
Şekil:
Dağıtılmış İşlem Düzenleyicisi hizmetinin görüntülenmesi.
Bu hizmet çalıştırıldığında üç DLL
dosyasını arıyor, bulursa bunlardan yararlanıyor. Aradığı DLL dosyaları
msdtcm.dll, mtxoci.dll ve oci.dll şeklinde. Oci.dll dosyası Microsoft’un değil
Oracle’ın bir dosyası ve Oracle veritabanı istemci
programı yüklendiğinde sisteme geliyor. Bu dosyaların \Windows\System32
klasöründe bulunması gerekiyor. Eğer kurumda Oracle uygulamaları bulunmuyorsa
oci.dll dosyasının da bilgisayarda bulunmaması gerekiyor (çoğunlukla da durum
bu).
Zararlı yazılımı üretenler
\Windows\System32 klasörüne kendi hazırladıkları oci.dll dosyasını kopyalıyor. System klasörüne bir dosya kopyalamak zor bir iş; bunu
nasıl yaptıkları tam bilinmiyor. Sonra da MSDTC hizmetinin çalışmasını
sağlıyorlar. Bunun sonucunda zararlı yazılımları faaliyet göstermeye başlıyor.
System32 klasörüne dosya kopyalamak, bir
hizmeti başlatmak sıradan kullanıcının yapabileceği işler değil. Bunu
yapabilmek için öncelikle sistemde yetkili bir kullanıcı olarak iş
yapabilmeleri gerekiyor. Bu da bizi yönetici hesaplarını koruma gereksinimine
götürüyor: Normalde kullanıcılar yönetici yetkilerine sahip olmamalı ve
yönetici gruplarının üyelikleri sık sık denetlenmeli.