12 Nisan 2015

Web Uygulama Denetimi - Bölüm-17: Dizin Aşım (Directory Traversal) Saldırıları

Dizin aşım açıklıkları kullanıcı girdisinin web sunucusu veya başka bir sistem üzerindeki dosyalara okuma veya yazma amacıyla güvensiz biçimde kullanılması sonucu ortaya çıkar. Ancak bu açıklıklar uzun zamandır bilindiği için uygulama geliştiriciler saldırı amacıyla kullanılabilecek girdileri büyük ihtimalle filtrelerler. Yine de yetersiz biçimde tasarlanan filtreleri aşmak mümkün olabilmektedir.


Öncelikle bu tür bir açıklığa basit bir örnek verelim:

Örneğin bir web uyguması statik resim dosyalarını istemciye görüntülemek amacıyla bir dinamik sayfaya sahip olsun. İstenen resim dosyasının adı da istek parametreleri arasında aşağıdaki gibi belirtilsin:

https://hedefuygulama.com/scripts/GetImage.aspx?file=diagram1.jpg

Sunucu bu isteği işlerken şu adımları gerçekleştirir:
  1. Sorgu’dan “file” parametresinin değerini alır.
  2. Bu değeri şu dizin adına ekler: “C:\uygulama\images\”.
  3. Oluşturulan dosya ismiyle dosyayı açar.
  4. Dosya içeriğini okuyarak istemciye görüntüler.

Eğer kullanıcı dosya ismi değeri içinde çift nokta ve ters taksim karakterleri ile üst dizinlere çıkabilirse 2. adımda istediği dosya ismini oluşturabilir. Bu şekilde dosya sistemi içindeki herhangi bir dosyayı okuyabilir. Örneğin aşağıdaki girdi ile SAM dosyası istemci tarafından elde edilebilir:

https://hedefuygulama.com/scripts/GetImage.aspx?file=..\..\windows\repair\sam

yukarıdaki girdi ile oluşturulan dosya ismi şu hali alır:

C:\uygulama\images\..\..\windows\repair\sam

ve aslında şu dosya ismini ifade eder:

C:\windows\repair\sam

Dizin Aşım Açıklıklarının Tespiti


Dizin aşım açıklıklarının tespiti oldukça zor olduğundan uygulama haritalama sırasında elde edilen fonksiyonalite bilgisi kullanılarak önceliklendirme yapılması faydalıdır.

Saldırı Hedeflerinin Belirlenmesi


En açık dizin aşım hedefi dosya görüntüleme ve yükleme fonksiyonalitesi sunan sayfalardır. Bu fonksiyonalite genellikle iş akış (workflow), doküman yönetim sistemi, blog ve açık artırma siteleri gibi resim yüklenebilen uygulamalarda bulunabilir.

Bu tür fonksiyonaliteye ek olarak dosya sistemi ile çalışmayı ifade eden diğer uygulama davranışlarını tespit etmek için aşağıdaki adımlar izlenebilir:
  • Uygulama haritası çıkarılırken elde edilen veriler aşağıdakileri tespit etmek için incelenir:
    • Bir dosya veya dizin adını içeriyormuş gibi görünen tüm parametreler (örneğin “include=main.inc” ya da “template=/en/sidebar”).
    • Ofis dokümanı veya resim gösterme gibi bir veritabanı yerine dosya sisteminden veri çeken uygulama fonksiyonalitesi
  • Test sırasında oluşan hatalar sonrası alınan mesajlarda dosya sistem API’lerine ilişkin işaretler ya da işletim sistemi komutları gönderildiğine ilişkin belirtiler tespit edilir.

Eğer denetlenen uygulamaya yerel erişim varsa (denetim sırasında web sunucusunun ele geçirilmesi veya kristal kutu denetimi dolayısıyla) uygulama ile dosya sistemi etkileşimi yerel olarak izlenebilir. Bunun için aşağıdaki işlemler gerçekleştirilebilir:
  • Dosya sistem aktivitesini izlemek için uygun bir araç kullanılabilir. Örneğin Linux için “ltrace/strace”, Windows için SysInternals’ın “Filemon” aracı gibi.
  • Her seferinde tek bir parametre hedeflenerek her sayfadaki her parametreye “traversaltest” gibi karıştırılmayacak bir ifade enjekte edilebilir. Bu işlemler yapılırken dosya sistemini izleyen araçta bu kelime filtre olarak kullanılarak dosya sistemine ulaşan komutlar arasında kullanıcı tarafından girilen bir verinin içinde yer alıp almadığı araştırılır.
  • Eğer test ifadesinin dosya sistemiyle ilişkili bir komutta yer aldığı tespit edilirse bu durumun dizin aşma açıklığı barındırıp barındırmadığı incelenir.

Dizin Aşma Açıklıklarının Tespiti


Muhtemel saldırı noktalarının tespitinden sonra herhangi bir filtreleme işlemi yapılıp yapılmadığını tespit etmek amacıyla “traversal sequence”lerinin bloklanıp bloklanmadığı test edilir. İlk test genellikle uygulama dizinini aşmadan ulaşılabilen dizinlerden birinin içinde gerçekleştirilir. Bu çalışma için izlenebilecek adımlar aşağıdaki gibidir:
  • Gönderdiğiniz dosya isminin uygulama tarafından önceden belirlenmiş bir dizin ismiyle birleştirildiği varsayımı ile parametre değerine varolmayan bir dizin ismi eklendikten sonra çift nokta ve ters taksim işaretleri eklenir. Örneğin uygulama şu parametreyi gönderiyorsa: “file=foo/file1.txt” şöyle bir test değeri gönderilir: “file=foo/bar/../file1.txt”.
  • Eğer uygulama davranışı her iki durumda da aynı ise uygulama açıklık taşıyor olabilir. Bu durumda uygulama başlangıç dizininin dışına çıkmaya çalışılabilir.
  • Eğer yukarıdaki iki girdi için farklı davranışlar oluşuyorsa uygulama aşım karakterlerini blokluyor ve geçersiz bir dizin oluşmasına neden oluyor olabilir. Bu durumda aşağıda belirtilen aşım kontrollerini bertaraf etme saldırıları düzenlenebilir.
  • “bar” dizini olmasa da bu parametrenin çalışmasının nedeni dosya erişim komutuna verilmeden önce bu parametrenin “canonicalize” edilmesidir.

Yukarıdaki test sırasında uygulama davranışı değişmiyor ve hata alınmıyorsa başlangıç dizinini aşmak için aşağıdaki adımlar uygulanır:
  • Eğer saldırılan fonksiyonalite dosya okumaya izin veriyorsa aşağıdaki girdiler kullanılarak herkes tarafından okunabilen (world-readable) bir dosyaya erişmeye çalışılır:
    • ../../../../../../../../../../../../../../etc/passwd
    • ../../../../../../../../../../../../../../boot.ini
  • Eğer saldırılan fonksiyonalite dosya yazmaya izin veriyorsa bu durumun bir açıklığa yol açıp açmadığını tespit etmek daha zor olabilir. Bu durumu test etmek için farklı davranışlara yol açabilecek 2 yazma denemesi bir dosyanın herkes tarafından yazılabilecek bir dizine yazılması bir diğerinin de sadece sistem yöneticisi (root veya Administrator) tarafından yazılabilecek bir dizine yazılmaya çalışılması şeklinde gerçekleştirilebilir.

Örneğin Windows platformu için aşağıdakilerden ilki yazma ile sonuçlanabilecekken ikinci deneme bu dosyanın üzerine Administrator’ın bile yazmasına izin verilmeyeceğinden hata ile sonuçlanacaktır:
  • ../../../../../../../../../../../../../../writetest.txt
  • ../../../../../../../../../../../../../../windows/system32/config/sam

Unix’de de aynı strateji izlenebilir, ancak Unix’in bir dizin altına bu dizinde yer alan bir dizinle aynı isimde bir dosya yaratılmasına izin vermeme özelliği hata oluşturacak durum için kullanılabilir:
  • ../../../../../../../../../../../../../../tmp/writetest.txt
  • ../../../../../../../../../../../../../../tmp

Eğer yukarıdaki çiftlere gelen yanıtlar farklı ise muhtemelen dizin aşım açıklığı bulunmaktadır.
  • Dosya yazma açıklığının bulunup bulunmadığını anlama yollarından biri de web uygulama kök dizinine bir dosya yazmak ve tarayıcı ile bu dosyaya erişmektir. Ancak bu kök dizinin bilinmediği veya uygulama kullanıcısının kök dizine yazma hakkının bulunmadığı durumlarda çalışmayacaktır.

Yukarıdaki testler gerçekleştirilirken taksim işareti hem düz hem de ters olarak kullanılmalıdır. Bunun nedeni bazı uygulamaların düz taksimi bloklarken diğerini bloklamaması, Windows platformunun hem düz hem de ters taksimi desteklemesidir. Uygulama bir Unix ortamında çalışsa bile dosya sistemi arka tarafta çalışan bir Windows platformu üzerinde bulunabilir, o yüzden bu durumda da her iki şekli de denemekte fayda vardır. Ayrıca hemen tüm sistemler gereğinden fazla çift nokta ve taksim işaretini tolere ettiğinden fazla işaret kullanmak yanlış dizinlere girmeye çalışma riskini azaltır.

Aşım Kontrollerini Bertaraf Etme Yöntemleri


Eğer yukarıda belirtilen ilk dizin aşım denemeleri başarısız olduysa bu dizin aşım açıklığı olmadığı anlamına gelmeyebilir. Dizin aşım tekniği iyi bilinen bir teknik olduğundan pek çok uygulama geliştirici özellikle çift nokta ve taksim işaretini bloklar. Ancak bu ve diğer filtrelerin bazı zayıflıkları bulunabilir. Bunların başında farklı kodlamalarla filtreleri atlatma yöntemi gelir.

Aşım kontrollerinin test edilmesi için aşağıdaki adımlar izlenebilir:
  • Yukarıda da belirtildiği gibi her zaman hem düz hem de ters taksim işaretleri testler sırasında kullanılmalıdır. Uygulamalar birini kontrol ederken diğerini etmiyor olabilir.
  • Aşım karakterlerinin basit URL kodlanmış halleri kullanılır. Tüm nokta ve taksim işaretlerini kodlandığından emin olunur:
    • Nokta             %2e
    • Düz taksim     %2f
    • Ters taksim     %5c
  • 16 bit Unicode kodlama kullanılır:
    • Nokta             %u002e
    • Düz taksim     %u2215
    • Ters taksim     %u2216
  • Çift URL kodlama denenir:
    • Nokta             %252e
    • Düz taksim     %252f
    • Ters taksim     %255c
  • Çok uzun (overlong) UTF-8 Unicode kodlama denenir:
    • Nokta             %c0%2e          %e0%40%ae   %c0ae             vd.
    • Düz taksim     %c02f             %e0%80%af   %c0%2f          vd.      
    • Ters taksim     %c05c             %e0%80%5c  vd.

Normalde UTF-8 unicode kodlamanın gerektirdiği minimum koddan daha uzun UTF-8 kodlama testi Burp Intruder’ın “illegal Unicode” test girdileri ile gerçekleştirilebilir. Bu gösterim Unicode kurallarına karşı olmakla birlikte başta Windows platformu olmak üzere pek çok dekoder bu gösterimi destekler.
  • Eğer uygulama aşım karakterlerini temizliyor ancak bunu döngüsel olarak gerçekleştirmiyorsa karakterleri birbirinin içine yerleştirerek filtreyi aşmak mümkün olabilir:
    • ....//
    • ....\/
    • ..../\
    • ....\\

Bir ikinci filtre tipi girdi içinde dosya uzantısı (yani dosya tipi) veya başlangıcı (yani dizin ismi) bulunup bulunmadığının kontrolüdür. Bu kontrol yukarıda bahsedilen kontrollerle birlikte kullanılabilir. Böyle bir kontrolün varlığını test etmek ve aşmaya çalışmak için aşağıdaki adımlar izlenebilir:
  • Dosya isminde “jpg” uzantısı olması kontrolü yapan bir uygulamayı aldatmak için dosya isminden sonra “null” byte yazıldıktan sonra “jpg” uzantısının yazılabilir. Örneğin:
    • ../../../../../../boot.ini.jpg
Bu saldırının çalıştığı durumlar kontrolün yapıldığı API kodunun yönetilen kod olduğu (ve dolayısıyla null karakteri ile metni okumayı kesmediği) gerçekten dosyaya erişim için kullanılan API kodunun yönetilmeyen kod olduğu durumlardır.
  • Yukarıdakine benzer bir başka saldırı yöntemi null byte yerine URL kodlanmış yeni satır karakterinin kullanıldığı yöntemdir. Özellikle Unix sistemlerde bu durum dosya isminin geri kalanının atılmasına neden olacaktır:
    • ../../../../../../etc/passwd%0a.jpg
  • Bazı uygulamalar istemci tarafından gelen parametre değerinin sonuna dosya uzantısı eklerler. Bu durumda da yukarıdaki yöntemler benzer nedenlerden dolayı faydalı olabilir.
  • Bazı uygulamalar istemci tarafından gelen parametre değerinin başında belli bir dizin isminin varlığını kontrol ederler. Tabi bu kontrolü aşım tekniğiyle bertaraf etmek basittir:
    • uygulama/images/../../../../../../etc/passwd
  • Eğer buraya kadar bahsedilen tekniklerden hiçbiri tek başına başarılı olamıyorsa birden fazla kontrol bir arada uygulanıyor olabilir. Bunun için uygulama kök dizini altında denemeler yapılması ve ulaşılabilen bir dosyaya bu teknikler kullanılarak ulaşılmaya çalışılması kontrollerin keşfedilmesine imkan tanır.

Özel Kodlamalarla Başa Çıkma


Bazen sunucudaki bir dosyaya erişmek için sunucuya giden dosya isimlerinin kolay anlaşılmayan biçimde kodlandığını görebilirsiniz. Bu durumda eğer dizin aşım teknikleri çalışıyorsa içinde ulaşmak istediğimiz dosyanın ismi de bulunan bir dizin aşma metnini geçerli bir dosya ismi için oluşturursanız istediğiniz dosya ismini de kodlu metni uygun yerden keserek elde edebilirsiniz.

Dizin Aşım Açıklıklarının Kullanılması


Eğer okuma hakkıyla bir dizin aşım açıklığı tespit ederseniz sistem üzerindeki önemli bilgilere ulaşabilirsiniz. Örneğin:
  • İşletim sistemi veya uygulama parola dosyaları.
  • Sunucu veya uygulama konfigürasyon dosyaları. Bu dosyalardaki bilgiler saldırı yöntemimizi iyileştirmek için gerekli bilgiler, parolalar ve diğer bilgileri içerebilir.
  • Veritabanı erişim şifrelerini içeren “include” dosyaları.
  • Uygulama tarafından kullanılan veri depoları (örneğin XML dosyaları, MySQL veritabanı dosyaları gibi).
  • Uygulama betiklerinin kaynak kodları. Bu kodlar açıklık arama için kullanılabilir.
  • Uygulama log dosyaları. Bu dosyalar içinde oturum bilgileri, kullanıcı kodu, vb. bilgilere erişilebilir.

Eğer yazma hakkıyla bir dizin aşım açıklığı tespit edilirse ilk amaç istediğimiz komutların veya kodun hedef sistem üzerinde çalıştırılmasıdır. Bunun için şu adımlar uygulanabilir:
  • Unix sistemlerde kullanıcının başlangıç dizininde sisteme giriş sırasında çalışacak betikler sisteme yüklenebilir.
  • in.ftpd gibi servis dosyaları bir kullanıcı bağlandığında istediğimiz komutları çalıştıracak biçimde değiştirilebilir.
  • Web uygulaması dizinlerine istediğimiz web betiklerini çalıştıracak bir dosya yüklenebilir.


<<Önceki Bölüm                                                                                                      Sonraki Bölüm>>