Windows Vista Service Pack 1 (SP1) desteği 12 Temmuz 2011'de sona erdi. Windows güvenlik güncelleştirmelerini almaya devam etmek için Windows Vista Service Pack 2'yi (SP2) çalıştırdığınızdan emin olun. Daha fazla bilgi için şu Microsoft Web sayfasına bakın: Windows'un bazı sürümlerine yönelik destek sona eriyor.
Bir uygulama tam yol belirtmeden dinamik bağlantı kitaplığını (DLL) dinamik olarak yüklediğinde, Windows iyi tanımlanmış bir dizin kümesinde arama yaparak DLL'yi bulmaya çalışır. Bir saldırgan dizinlerden birinin denetimini ele geçirirse, uygulamayı beklediği DLL yerine DLL'nin kötü amaçlı bir kopyasını yüklemeye zorlayabilir. Bu saldırılar "DLL ön yükleme saldırıları" olarak bilinir ve paylaşılan DLL kitaplıklarının dinamik olarak yüklenmesini destekleyen tüm işletim sistemlerinde ortaktır. Bu tür saldırıların etkisi, bir saldırganın uygulamayı çalıştıran kullanıcı bağlamında kod yürütmesi olabilir. Uygulama Yönetici olarak çalıştırıldığında, bu durum yerel bir ayrıcalık yükselmesine neden olabilir. Bu saldırılara olan ilginin yeniden arttığını biliyoruz. Bu sorunun ortak müşterilerimiz üzerindeki etkisini sınırlandırmak amacıyla, bu sorun hakkında bilgi sahibi olduklarından ve uygulamalarında sorunu çözmek için gerekli araçlara sahip olduklarından emin olmak için bu belgeyi geliştirici topluluğunun kullanımına sunuyoruz.
Özet
DLL önceden yükleme saldırılarının açıklaması
LoadLibrary tabanlı saldırılar
Bir uygulama tam yol belirtmeden bir DLL'yi dinamik olarak yüklediğinde, Windows bu DLL'yi bulmak için DLL Arama Sırası olarak bilinen iyi tanımlanmış bir dizinler kümesinde doğrusal olarak arama yapar. Eğer Windows DLL'yi DLL Arama Sırası içinde bulursa bu DLL'yi yükler. Ancak, Windows DLL Arama Sırasındaki dizinlerin hiçbirinde DLL'yi bulamazsa, DLL yükleme işleminde bir hata döndürür. Aşağıdaki bölüm, DLL'leri dinamik olarak yüklemek için kullanılan LoadLibrary ve LoadLibraryEx işlevlerinin DLL Arama Sırasıdır:
- Uygulamanın yüklendiği dizin
- Sistem dizini
- 16 bit sistem dizini
- Windows dizini
- Geçerli çalışma dizini (CWD)
- PATH ortam değişkeninde listelenen dizinler
Aşağıdaki senaryoyu ele alalım:
- Bir uygulama, bir DLL'yi, uygulamanın CWD'sinde bulmayı beklediği tam yolu belirtmeden yükler.
- Uygulama, DLL'yi bulamadığında vakayı işlemek için tamamen hazırdır.
- Saldırgan, uygulama hakkındaki bu bilgileri bilir ve CWD'yi kontrol eder.
- Saldırgan, kendi özel hazırlanmış DLL sürümünü CWD'ye kopyalar. Bu, saldırganın bunu yapma iznine sahip olduğunu varsayar.
- Windows, DLL Arama Sırasındaki dizinlerde arama yapar ve uygulamanın CWD'sinde DLL'yi bulur.
Bu senaryoda, özel hazırlanmış DLL uygulama içinde çalışır ve geçerli kullanıcının ayrıcalıklarını kazanır.
Öneri
Bu saldırıyı önlemek için, uygulamalar boş bir dize ("") kullanarak SetDllDirectory API'sini çağırarak geçerli çalışma dizinini (CWD) DLL arama yolundan kaldırabilir. Bir uygulama geçerli dizinden bir DLL yüklemeye bağlıysa, lütfen geçerli çalışma dizinini alın ve bunu tam bir LoadLibrary yoluna geçmek için kullanın.
Bazı geliştiricilerin, kullanıcı tarafından çalıştırılan Windows sürümünü belirlemek için belirli bir DLL'nin mevcut olup olmadığını doğrulamak için LoadLibrary'yi kullandığının da farkındayız. Bunun uygulamayı savunmasız hale getirebileceğini bilmelisiniz. Etkilenen kitaplık, uygulamanın yürütüldüğü Windows sürümünde gerçekten mevcut değilse, saldırgan CWD'ye aynı ada sahip bir kitaplık ekleyebilir. Bu tekniği kullanmamanızı şiddetle tavsiye ederiz. Bunun yerine, "Sistem Sürümünü Edinme" adlı MSDN makalesinde açıklanan önerilen teknikleri kullanın.
Üçüncü taraf eklentileri yükleyen ve eklentileri LoadLibrary çağrıları için tam bir yol kullanmaya zorlayamayan bir uygulama, CWD'yi kaldırmak için SetDllDirectory("") öğesini çağırmalı ve ardından eklenti yükleme dizinini DLL arama yoluna eklemek için SetDllDirectory("eklenti yükleme konumu") çağırmalıdır.
SearchPath tabanlı saldırılar
Benzer bir saldırı, bir uygulama bir DLL'yi bulmak ve SearchPath tarafından döndürülen yolu dinamik olarak yüklemek için SearchPath API'sini kullandığında da ortaya çıkar. SearchPath API'si için varsayılan arama sırası aşağıdadır:
- Uygulamanın yüklendiği dizin
- Geçerli çalışma dizini (CWD)
- Sistem dizini
- 16 bit sistem dizini
- Windows dizini
- PATH ortam değişkeninde listelenen dizinler
Güvenli olmadığından bu deseni önermiyoruz. Çıktının amaçlanan kullanımı LoadLibrary işlevine yapılan bir çağrıysa SearchPath işlevini bir .dll dosyasını bulma yöntemi olarak önermiyoruz. SearchPath işlevinin arama sırası LoadLibrary işlevi tarafından kullanılan arama sırasından farklı olduğundan bu yanlış .dll dosyasının bulunmasına neden olabilir. Bir .dll dosyasını bulup yüklemeniz gerekiyorsa, LoadLibrary işlevini kullanın.
ShellExecute ve CreateProcess
Geliştiriciler harici yürütülebilir dosyaları yüklemek için ShellExecute ve CreateProcess gibi benzer işlevleri çağırdıklarında da bu sorunların varyasyonları oluşabilir. Geliştiricilerin ikili dosyaları yüklerken dikkatli olmalarını ve tam yolu belirtmelerini öneririz. Bu, kitaplık yerine ikili dosya yüklediğinizde daha az karmaşıklık oluşturmalıdır.
Yazılım geliştiriciler için önerilen adımlar
Geliştiricilerin aşağıdakileri yapmasını öneririz:
Güvenli olmayan kitaplık yüklemesi örnekleri için uygulamalarını doğrulayın (her birinin örnekleri bu makalenin ilerleyen bölümlerinde verilmiştir). Bunlara aşağıdaki türler dahildir:
- Bir kitaplığın veya bileşenin konumunu belirlemek için SearchPath kullanımı.
- İşletim sisteminin sürümünü tanımlamak için LoadLibrary'nin kullanımı.
Mümkün olan her yerde LoadLibrary, CreateProcess ve ShellExecute'a yapılan tüm çağrılar için tam yollar kullanın.
Geçerli çalışma dizinini gerekli olduğunda varsayılan DLL arama sırasından kaldırmak için boş bir dizeyle ("") SetDllDirectory'ye çağrılar uygulayın. SetDllDirectory'nin tüm süreci etkilediğini unutmayın. Bu nedenle, bunu LoadLibrary'ye yapılan çağrılardan önce ve sonra değil, işlem başlatmanın başlarında bir kez yapmanız gerekir. SetDllDirectory tüm işlemi etkilediğinden, SetDllDirectory'yi farklı değerlerle çağıran birden çok iş parçacığı tanımsız davranışa neden olabilir. Ayrıca, işlem üçüncü taraf DLL'leri yükleyecek şekilde tasarlanmışsa, işlem genelinde bir ayar yapmanın uyumsuzluklara neden olup olmayacağını belirlemek için test yapılması gerekir. Bilinen bir sorun, bir uygulama Visual Basic for ApplicationsVisual Basic for Applications'a bağlı olduğunda, işlem genelindeki bir ayarın uyumsuzluklara neden olabilmesidir.
İşlem için güvenli işlem arama modunu etkinleştirmek için SetSearchPathMode işlevini kullanın. Bu, işlemin ömrü boyunca geçerli çalışma dizinini SearchPath arama listesinde son konuma taşır.
Güvenli arama modu etkin olsa bile tam yol belirtmeden bir DLL'nin varlığını denetlemek için SearchPath kullanmaktan kaçının; çünkü bu, DLL Önceden Yükleme saldırılarına neden olabilir.
Güvenli olmayan kitaplık yüklerini belirleme kılavuzu
Kaynak kodunda, güvenli olmayan kitaplık yüklemelerine örnek olarak şunlar verilebilir:
Aşağıdaki kod örneğinde, uygulama en az güvenli arama yolunu kullanarak "schannel.dll" için arama yapar. Bir saldırgan schannel.dll CWD'ye yerleştirebilirse, uygulama Windows dizinlerinde uygun kitaplığı aramadan önce bile yüklenir.
DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); HMODULE handle = LoadLibrary(result);Aşağıdaki kod örneğinde uygulama, LoadLibrary() çağrısı için bu belgenin başında açıklanan çeşitli uygulama ve işletim sistemi konumlarından kütüphaneyi yüklemeye çalışır. Dosyanın mevcut olmama riski varsa, uygulama dosyayı geçerli çalışma dizininden yüklemeyi deneyebilir. Bu senaryo önceki örnekten biraz daha az tehlikelidir. Ancak, ortamın tamamen öngörülebilir olmaması durumunda uygulama kullanıcısını riske maruz bırakmaya devam eder.
HMODULE handle = LoadLibrary("schannel.dll");
Aşağıdakiler daha iyi, daha güvenli kitaplık yükleme örnekleridir:
Aşağıdaki kod örneğinde, kitaplık tam bir yol kullanılarak doğrudan yüklenir. Saldırganın, uygulamanın hedef dizinine zaten yazma izinleri olmadığı sürece kötü amaçlı kod getirme riski yoktur.
HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");Not Sistem dizinini belirleme hakkında bilgi için aşağıdaki kaynaklara bakın:
GetSystemDirectory
http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspx SHGetKnownFolderPath
http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspxAşağıdaki kod örneğinde, LoadLibrary çağrılmadan önce geçerli çalışma dizini arama yolundan kaldırılır. Bu, saldırganın bir DLL ön yükleme saldırısı kullanmak için uygulama dizinini, Windows dizinini veya kullanıcının yolunda belirtilen dizinleri kontrol etmesi gerekeceğinden, riski önemli ölçüde azaltır.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");Güvenlik güncelleştirmesi 963027 yüklü olan tüm sistemlerde ( MS09-014'te açıklanmıştır), aşağıdaki kod CWD'yi arama sırasında en son noktaya kalıcı olarak taşır. Bu işlemin içinden SetSearchPathMode işlevine yapılan ve arama modunu değiştirmeye çalışan sonraki çağrılar başarısız olur.
SetDllDirectory (""); HMODULE handle = LoadLibrary("schannel.dll");Aşağıdaki kod örneğinde, LoadLibrary çağrılmadan önce geçerli çalışma dizini arama yolundan kaldırılır. Bu, saldırganın bir DLL ön yükleme saldırısı kullanmak için uygulama dizinini, Windows dizinini veya kullanıcının yolunda belirtilen dizinleri kontrol etmesi gerekeceğinden, riski önemli ölçüde azaltır.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT ); HMODULE handle = LoadLibrary("schannel.dll");
Güvenli olmayan yükleri dinamik olarak algılamak için İşlem İzleyicisi'ni kullanma
Microsoft, İşlem İzleyicisi adlı bir araç yayımlar. Bu araç, geliştiricilerin ve yöneticilerin çalışan bir işlemin davranışını yakından izlemesine olanak tanır. İşlem İzleyicisi, uygulamalarınızdan birinin bu tür bir soruna karşı savunmasız olup olmadığını dinamik olarak algılamak için kullanılabilir.
İşlem İzleyicisi'ni karşıdan yüklemek için aşağıdaki Microsoft web sayfasını ziyaret edin:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspxBelirli bir dizine ayarlanmış CWD'yi kullanarak uygulamanızı başlatmayı deneyin. Örneğin, uygulamanıza dosya işleyicisi atanmış olan uzantısına sahip bir dosyaya çift tıklayın.
İşlem İzleyicisi'ni aşağıdaki filtrelerle ayarlayın:
Savunmasız bir yola çarpılırsa, aşağıdakine benzer bir şey görürsünüz:
Bir DLL yüklemek için uzak dosya paylaşımına yapılan çağrı, bunun güvenlik açığı olan bir program olduğunu gösterir.
Daha Fazla Bilgi
Daha fazla bilgi için aşağıdaki Microsoft web sayfalarını ziyaret edin:
Dinamik Bağlantı Kitaplığı Arama Düzeni
http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx SearchPath işlevi ile ilgili MSDN belgeleri
http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspx LoadLibrary işleviyle ilgili MSDN belgeleri
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx SetDllDirectory işleviyle ilgili MSDN belgeleri
http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx SetSearchPathMode işleviyle ilgili MSDN belgeleri
http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspx Microsoft Office Baş Güvenlik Mühendisi David Leblanc'ın blog gönderisi
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx MSRC Mühendislik ekibinden Andrew Roths'un DLL önceden yükleme saldırıları hakkındaki blog gönderisi