← Tüm Yazılar
Senaryo,RCE,Dosya Yükleme,Kritik

Zararsız Görünen Bir 'Profil Fotoğrafı' Alanı Sunucuyu Nasıl Ele Geçirtir? — Kritik RCE Senaryosu

2026-07-14 · REDCELL AR-GE

Güvenlik dünyasında en pahalı cümlelerden biri şudur: "Sadece bir resim yükleme alanı, ne olabilir ki?" Anonimleştirilmiş bu senaryo, o sorunun cevabını veriyor: tüm sunucu.

Sahne: Profil Fotoğrafı

Uygulamada kullanıcılar profil fotoğrafı yükleyebiliyordu. Beklenen: .jpg, .png. Sunucu ise gelen dosyayı /uploads/ klasörüne, gönderilen adla kaydediyor ve bu klasör web'den doğrudan erişilebilir durumda.

İki ölümcül varsayım: (1) dosya adına güveniliyor, (2) yüklenen klasördeki her şey sunucuda çalıştırılabiliyor.

Adım 1: Resim Yerine Kod

Saldırgan bir resim yerine, adı foto.php olan tek satırlık bir dosya gönderir:

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

Uygulama uzantıyı kontrol etmediği için dosyayı kabul eder ve şuraya yazar:

https://uygulama.ornek/uploads/foto.php

Adım 2: Webshell

Artık saldırganın sunucuda komut çalıştırmasına "webshell" denir. Tarayıcıdan ya da curl ile:

curl "https://uygulama.ornek/uploads/foto.php?c=id"
# çıktı: uid=33(www-data) gid=33(www-data) ...

Sunucu, saldırganın gönderdiği id komutunu çalıştırıp cevabı döndürdü. Buna RCE (Remote Code Execution / Uzaktan Kod Çalıştırma) denir — açıkların en kritiği.

Adım 3: Zincirin Sonu

Bir kez komut çalıştıran saldırgan tipik olarak:

"Bir resim alanı", kurumun iç ağına açılan kapıya dönüşür.

Çözüm: Katmanlı Savunma

Tek bir kontrol yeterli değildir; hepsi birlikte uygulanır.

1. Uzantı ve içerik tipi doğrulama (izin listesi). Neyin yasak olduğunu değil, neyin serbest olduğunu tanımlayın:

IZINLI = {"jpg", "jpeg", "png", "webp"}
uzanti = ad.rsplit(".", 1)[-1].lower()
if uzanti not in IZINLI:
    return hata("Yalnızca resim yüklenebilir.")

2. Dosyanın gerçekten resim olduğunu doğrula. Uzantı yalan söyleyebilir; dosyanın "sihirli baytlarına" (magic bytes) bakın veya bir resim kütüphanesiyle açmayı deneyin:

from PIL import Image
try:
    Image.open(dosya).verify()   # açılmıyorsa resim değildir
except Exception:
    return hata("Geçersiz resim.")

3. Adı siz belirleyin. Kullanıcının verdiği adı asla kullanmayın; rastgele bir ad üretin: a91f3c...png.

4. En kritiği — çalıştırmayı engelleyin. Yüklenen klasörü web kök dizininin dışında tutun ya da o klasörde kod yürütmeyi kapatın. nginx örneği:

location /uploads/ {
    location ~ \.php$ { deny all; }
}

Böylece foto.php yüklense bile çalışmaz, sadece metin dosyası olarak durur.

Etik ve yasal not: Webshell yükleme ve komut çalıştırma yalnızca yazılı yetki verilmiş test ortamlarında yapılır. İzinsiz yapıldığında ağır cezai sorumluluk doğurur. REDCELL bu testleri kontrollü, sözleşmeli kapsamda ve geri alınabilir biçimde yürütür.

Sonuç

Dosya yükleme alanları, modern web'in en sık ihmal edilen kritik kapılarıdır. Sitenizde kullanıcı dosya yükleyebiliyorsa — profil fotoğrafı, CV, belge, ne olursa — bu zincirin sizde kurulup kurulamayacağı bugün test edilmelidir. REDCELL, tam da bu zinciri güvenli biçimde deneyip size kapatma reçetesini verir.

Sisteminizin güvenliğinden emin misiniz?

Ücretsiz Ön Değerlendirme →