Ders 5 - Command Injection (Medium Level) | |||||
Bu yazıda güvenlik düzeyi Medium seviyesine yükseltilmiş DVWA'ya karşı Command Injection saldırısı ve güvenlik önlemleri incelenecektir.
Dersin HedefiDVWA'da güvenlik Medium Level'ken Command Injection için ne gibi bir güvenlik önlemi alındığını keşfedin ve bu güvenliği aşarak yine bir Command Injection saldırısı düzenleyin.Command Injection'a Karşı ÖnlemBir önceki derste Command Injection saldırısının nasıl düzenleneceğini göstermiştik. O saldırıda güvenlik seviyesi Low Level'dı. İlk olarak Low Level'ın kullandığı kaynak koda bir bakalım:<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "{$cmd}"; } ?> 5. satırdaki $target değişkeni ekrandaki metin kutusundan gelecek IP adresini ya da domain adresini tutacaktır. if-else yapısı ise DVWA'nın üzerinde çalıştığı işletim sistemine göre ping komutunu belirleyecek, çalıştıracak ve ardından dönen sonucu $cmd değişkenine atayacaktır. Komutun belirlenmesi ifadesinden kasıt şudur: Eğer DVWA'yı siz Windows üzerinde çalıştırıyorsanız shell kod olarak sözgelimi ping www.includekarabuk.com belirlenecektir. Eğer siz DVWA'yı linux bir sistem üzerinde çalıştırıyorsanız bu durumda shell kod olarak ping -c 4 www.includekarabuk.com belirlenecektir. Fark ettiyseniz yukarıdaki kaynak kodda metin kutusundan gelen veri olduğu gibi shell koduna ekleniyor ve shell kod çalıştırılıyor. İşte zafiyet bu işleyişten kaynaklanmaktadır. Metin kutusundan gelen veri olduğu gibi komut satırına gönderilmemelidir. Bir denetlemeye tabi tutulmalıdır. İşte şimdi bunun bir örneğini güvenlik seviyesi Medium Level iken kullanılan kaynak koda bakarak görelim: <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Set blacklist $substitutions = array( '&&' => '', ';' => '', ); // Remove any of the charactars in the array (blacklist). $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "{$cmd}"; } ?> Görüldüğü üzere 8. satırda $substitution dizisi oluşturulmuştur. Bu dizi 14. satırda kullanılmıştır. 14. satırda yapılan şey şudur. $target değişkeninin tuttuğu değerin içerisinde eğer && karakterleri varsa ya da noktalı virgül (;) karakterleri varsa bunları sil ve $target'in arındırılmış halini $target değişkenine ata. Hatırlarsanız önceki derste && operatörü sayesinde enjeksiyon yapmıştık. Şimdi ise && operatörü silinerek metin kutusundaki veri shell_exec() fonksiyonuna gitmektedir. Böylece önceki derste kullandığımız enjeksiyon yöntemi artık başarısız olur. İsterseniz deneyip görebilirsiniz( Metin kutusuna daha önceki derste kullanılan enjeksiyon kodu olan www.includekarabuk.com && cat /etc/passwd girildiği takdirde bu sefer hiçbir çıktı ekrana yansımayacaktır). Medium seviyesinde güvenlik yukarıdaki kaynak koddan da görülebileceği gibi sadece && ve ; karakterlerinin filtrelenmesinden (silinmesinden) ibarettir. Bu zayıf bir güvenlik önlemidir. Çünkü aşağıda yer alan sofistike bir yöntemle bu güvenlik bypass edilebilmektedir ( atlatılabilmektedir): 1 &;& cat /etc/passwd Yukarıdaki &;& karakterlerine dikkat edin. Medium level'da alınan güvenlik önlemi gereği str_replace() fonksiyonu && ve ; karakterlerini silmekteydi. Yukarıdaki sofistike yöntemdeki &;& karakterleri ile str_replace()'i kandırıyoruz. str_replace &;& karakterlerini taradığında ardarda bir ampersand işaretiyle karşılaşmayacağı için ampersand'lara dokunmayacaktır, fakat noktalı virgül (;) karakterini gördüğü an silecektir ve ardından taramaya devam edip taramayı sonlandıracaktır. str_replace()'in sildiği noktalı virgül sonrası geriye kalan kodda enjeksiyon için arzulanan operatör olan && karakterleri meydana gelecektir. 1 && cat /etc/passwd Yukarıdaki kod str_replace()'ten çıktığı gibi $target değişkenine oradan da shell_exec() fonksiyonuna gidecektir ve enjekte edilen cat komutunun çıktısı echo ile ekrana yansıtılacaktır. Yani str_replace() fonksiyonuna noktalı virgülü feda ettik, fakat bunun karşılığında ampersand'ları kazandık. Aklınıza şöyle bir soru takılmış olabilir: Neden str_replace() fonksiyonu noktalı virgül karakterini sildikten sonra ortaya çıkan ardarda ampersand'ları da silmedi? Bunun nedeni str_replace() fonksiyonunun recursive çalışmayışından dolayıdır. Yani enjeksiyon koduna bakan str_replace() fonksiyonu baştan itibaren sırayla, karakter karakter bizim enjeksiyon kodumuzu tarayacaktır. İlk ampersand karakterine geldiğinde ondan sonra ampersand var mı diye bakacaktır. Olmadığından ilk ampersand'ı pas geçecektir. Yeni taranan karakter noktalı virgül olduğundan onu silecektir. Ardından bir sonraki karaktere geçiş yapacaktır. Yeni karakter ampersand'dır. Ondan sonraki karakter ampersand olmadığı için bunu da pas geçecektir. Yani tarama sırasında geriye dönüş yoktur. Dolayısıyla str_replace()'in filtrelemesi ampersand'lara dokun(a)mayacaktır. Bu yeni kodun çalışıp çalışmadığını test etmek için aşağıdaki kodu metin kutusuna girin ve Submit butonuna basın: includekarabuk.com &;& cat /etc/passwd Görüldüğü üzere enjekte edilen cat komutunun çıktısı ekrana yansımıştır. Sayfa güvenliği arttırılmış olmasına rağmen halen Command Injection zafiyeti barındığından dolayı önceki derste bahsedilen sayfa hack'lemek, hedef sistemin dizinlerinlerine not bırakmak, hatta hedef sistemin ethernet kartını devredışı bırakmak gibi türlü türlü şeyler yapılabilir. |
|||||
Bu yazı 15.01.2016 tarihinde, saat 10:49:14'de yazılmıştır. 15.01.2016 tarihi ve 16:32:18 saatinde ise güncellenmiştir. | |||||
|
|||||
Yorumlar |
|||||
|
|||||
|
|||||
Yorum Ekle | |||||