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

 

metin, ekran görüntüsü içeren bir resim

Açıklama otomatik olarak oluşturuldu

İ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

 

metin, ekran görüntüsü, ekran, görüntüleme içeren bir resim

Açıklama otomatik olarak oluşturuldu

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

 

metin, ekran görüntüsü, yazı tipi, yazılım içeren bir resim

Açıklama otomatik olarak oluşturuldu

 

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

 

metin, ekran görüntüsü, menü içeren bir resim

Açıklama otomatik olarak oluşturuldu

 

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.

 

metin, ekran görüntüsü, yazılım, sayı, numara içeren bir resim

Açıklama otomatik olarak oluşturuldu

 

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.