Selamlar Sevgili Siberatay Mensupları,
Web Güvenliği serimizin beşinci partına hepiniz hoş geldiniz.
Şimdiye kadar konuştuğumuz zafiyetler (SQLi, XSS, CSRF, IDOR) genelde tarayıcıyı manipüle etme, veritabanından veri sızdırma veya kurbanın adına istek atma odaklıydı. Evet, bunlar bir sistemi mahvetmek için fazlasıyla yeterli silahlardır; ancak bugün işi üst seviyeye taşıyoruz. Artık hedefimiz sadece veritabanı satırları veya çerezler değil; doğrudan uygulamanın barındığı sunucunun anahtarlarını cebimize indirmek.
Bir geliştiricinin sistemine koyduğu en masum görünümlü özellik nedir biliyor musunuz? Dosya yükleme (File Upload) alanı. Profil resmi değiştirme, e-posta ekleme, PDF faturası yükleme veya avatar güncelleme modülleri... Geliştirici oraya bir dosya yükleme input'u koyarken rahat bir nefes alır: "Alt tarafı kullanıcı kendine resim yüklüyor, ne olabilir ki?"
İşte siber güvenlik dünyasında "ne olabilir ki" denilen her yer, birer felaket senaryosunun doğum lekesidir. Bugün, o masum resim yükleme alanlarından sızıp sunucu üzerinde komut çalıştırma (RCE - Remote Code Execution) noktasına nasıl geldiğimizi, arkasındaki tüm teknik mekanizmayı, bypass yöntemlerini ve kod seviyesindeki zafiyetleri adeta bir lab masasına yatırır gibi inceleyeceğiz.
Çaylar kahveler hazırsa, sunucunun kök dizinine doğru kabloyu çekiyoruz.
Hadi başlayalım...
1. BÖLÜM: DOSYA YÜKLEME MANTIĞI VE FELAKETİN BAŞLANGICI
Önce olayın fiziksel ve mantıksal altyapısını kafamızda oturalım. Geliştirici bir web uygulaması yazar (PHP, Python/Django, Node.js, ASP.NET fark etmez). Kullanıcı arayüzüne de bir form koyar:
Kullanıcı dosyayı seçer, "Yükle" butonuna basar. İstek sunucuya multipart/form-data formatında gönderilir. Sunucu tarafındaki kod (
İşte zafiyetin patladığı ilk nokta tam burada, sunucunun şu soruyu sor(a ma)masında başlar:
HTML:
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="avatar">
<input type="submit" value="Yükle">
</form>
Kullanıcı dosyayı seçer, "Yükle" butonuna basar. İstek sunucuya multipart/form-data formatında gönderilir. Sunucu tarafındaki kod (
upload.php) bu dosyayı alır, geçici bir dizine (/tmp) kaydeder, ardından kalıcı olarak saklanacağı bir klasöre (örneğin /var/www/html/uploads/) taşır.İşte zafiyetin patladığı ilk nokta tam burada, sunucunun şu soruyu sor(a ma)masında başlar:
- "Ben bu dosyayı aldım ama bu gerçekten bir resim mi, yoksa içinde arka planda sunucu komutları çalıştıran bir canavar mı?"
Eğer geliştirici sadece tarayıcıdan gelen dosya uzantısına (.jpg, .png) veya HTTP paketindeki Content-Type başlığına (image/jpeg) güveniyorsa, o sunucu düşmüştür. Çünkü HTTP paketleri istemci (attacker) tarafından saniyeler içinde manipüle edilebilir. Tarayıcı "Bu bir resimdir" der, sunucu da boyun eğip dosyayı çalıştırılabilir dizine kaydeder.
2. BÖLÜM: RCE (REMOTE CODE EXECUTION) NEDİR VE NASIL TETİKLENİR?
Dosya yükleme açığının tek başına var olması güzeldir ama asıl olay o yüklenen dosyanın sunucu tarafından yorumlanması (parsed) ve çalıştırılmasıdır.
Diyelim ki hedef sunucu PHP diliyle yazılmış ve Apache veya Nginx + PHP-FPM mimarisini kullanıyor. Saldırgan, içi tamamen PHP kodlarıyla dolu bir dosyayı hazırlar ve uzantısını .php veya sunucunun yorumlayabileceği farklı bir uzantı (.php5, .phtml) yaparak sisteme yükler.
Dosyanın içeriği saf bir arka kapı (Web Shell) kodudur:
Bu dosya sunucuya shell.php adıyla yüklenir ve
Arka planda ne olur biliyor musunuz?
Sunucu o URL'ye gelen isteği işlerken shell.php dosyasıyla karşılaşır. PHP yorumlayıcısı (Interpreter) devreye girer, dosyayı okur, içindeki
Artık saldırgan için tarayıcı, sunucunun terminal ekranıdır. İstediği gibi komut çalıştırır, dosya siler, veritabanı şifrelerini okur veya içeride yatay hareket (lateral movement) başlatır. İşte RCE budur: Uzaktan, kod yazarak kaleyi içeriden fethetmek. :d
Diyelim ki hedef sunucu PHP diliyle yazılmış ve Apache veya Nginx + PHP-FPM mimarisini kullanıyor. Saldırgan, içi tamamen PHP kodlarıyla dolu bir dosyayı hazırlar ve uzantısını .php veya sunucunun yorumlayabileceği farklı bir uzantı (.php5, .phtml) yaparak sisteme yükler.
Dosyanın içeriği saf bir arka kapı (Web Shell) kodudur:
PHP:
<?php
if(isset($_GET['cmd'])) {
system($_GET['cmd']);
}
?>
Bu dosya sunucuya shell.php adıyla yüklenir ve
/uploads/shell.php dizinine kaydedilir. Saldırgan tarayıcısını açıp şu adrese gider:[https://hedef-site.com/uploads/shell.php?cmd=cat+/etc/passwd](https://hedef-site.com/uploads/shell.php?cmd=cat+/etc/passwd)Arka planda ne olur biliyor musunuz?
Sunucu o URL'ye gelen isteği işlerken shell.php dosyasıyla karşılaşır. PHP yorumlayıcısı (Interpreter) devreye girer, dosyayı okur, içindeki
system($_GET['cmd']) fonksiyonunu görür ve URL'den gelen cat /etc/passwd komutunu doğrudan işletim sisteminin terminalinde (bash/cmd) çalıştırır! Sunucunun terminal çıktısını da ekrana direkt basar.Artık saldırgan için tarayıcı, sunucunun terminal ekranıdır. İstediği gibi komut çalıştırır, dosya siler, veritabanı şifrelerini okur veya içeride yatay hareket (lateral movement) başlatır. İşte RCE budur: Uzaktan, kod yazarak kaleyi içeriden fethetmek. :d
3. BÖLÜM: FİLTRE DUVARLARINI AŞMA SANATI (BYPASS TEKNİKLERİ)
Geliştiriciler tabii ki tamamen savunmasız bırakmıyor sistemi; ancak aldıkları önlemler genellikle yanlış yerlerden deliniyor. Saldırganların bu filtreleri nasıl baypass ettiğine yakından bakalım.
A. İstemci Tarafı (Client-Side) Filtreleme Bypass
Bazı amatör yazılımcılar dosya uzantısı kontrolünü JavaScript ile tarayıcı tarafında yapar. Kullanıcı .php seçtiğinde ekrana uyarı verip "Sadece resim yükleyebilirsin" der.
- Nasıl Aşılır? JavaScript istemcide çalışır. Saldırgan tarayıcının geliştirici konsolundan o JavaScript fonksiyonunu silebilir, isteği Burp Suite gibi bir proxy aracıyla yakalayıp uzantıyı anında .php olarak değiştirebilir veya doğrudan curl ile sunucuya istek atabilir. İstemci tarafındaki hiçbir kural güvenlik kuralı değildir!
B. Uzantı (Extension) Kara Listesi (Blacklisting) Bypass
Geliştirici der ki: "Kullanıcılar .php yüklemesin, o yüzden sistemde uzantısı .php olan dosyaları engelleyeyim."
- Nasıl Aşılır? Kara liste yaklaşımı her zaman delinmeye mahkumdur. Geliştirici .php'yi engellemiştir ama sunucunun yorumladığı alternatif uzantılardan haberi yoktur:
- .php5, .phtml, .shtml, .pHp, .p.php gibi varyasyonlar.
- Özellikle Apache sunucularda .htaccess dosyası yükleme izni varsa, saldırgan önce içinde
AddType application/x-httpd-php .icoyazan bir .htaccess dosyası yükler, ardından shell.ico adında PHP kodları içeren bir dosya yükler. Apache artık o .ico uzantılı dosyayı bir PHP scripti gibi çalıştırır!
C. MIME-Type / Content-Type Kontrolü Bypass
Sunucu, yüklenen dosyanın başındaki HTTP Header (
Content-Type: image/jpeg) değerine bakıp "Evet bu resimdir" diyerek kabul ediyorsa:
- Nasıl Aşılır? Burp Suite ile istek yakalanır. Dosya içeriği saf PHP kodu (
<?php ... ?>) olmasına rağmen, HTTP isteğindeki başlık bilgisi şu şekilde değiştirilir:
HTTP:
Content-Type: image/jpeg
- Sunucu başlığa bakıp aldanır, dosyayı kaydeder.
D. Sihirli Baytlar (Magic Bytes / File Signatures) Bypass
Geliştiriciler daha akıllıca davranıp dosyanın içeriğinin ilk birkaç baytına (Magic Bytes) bakar. Örneğin JPEG dosyaları her zaman FF D8 FF baytlarıyla başlar.
- Nasıl Aşılır? Saldırgan, zararlı PHP kodunun en başına gerçek bir JPEG imzasını (FF D8 FF E0) ekler. Dosyanın geri kalanına ise kendi PHP shell kodunu yazar. Dosya hem geçerli bir resim imzasına sahip olur (görsel görüntüleyiciler onu resim olarak açabilir) hem de içinde PHP kodu barındırır. Sunucu imza kontrolünden geçirip dosyayı kaydeder, daha sonra yorumlayıcı o dosyayı çalıştırdığında aradaki PHP kodunu patlatır.
4. BÖLÜM: DOSYA YÜKLEME ZAFİYETLERİ NASIL ÖNLENİR? (DEFANSİF MİMARİ)
Bu devasa belayı kökünden kurutmak ve sunucuyu güvenceye almak için geliştiricilerin uygulaması gereken altın kurallar şunlardır:
- Beyaz Liste (Whitelist) Yaklaşımı Kullanın: Hangi uzantıların yüklenemeyeceğini değil, kesinlikle hangilerinin yüklenebileceğini tanımlayın (Örn: Sadece .jpg, .png). Bunun dışındaki her uzantıyı reddedin.
- Dosya Adlarını ve Uzantılarını Asla Kullanıcıya Bırakmayın: Kullanıcı dosyayı shell.php adıyla yüklese bile, sunucu dosyayı alır almaz orijinal adını çöpe atmalıdır. Kriptografik olarak güvenli, rastgele isimler üretilmelidir (Örn: UUID veya SHA-256 hash: 8f4343d...png).
- Web Shell Dosyalarının Çalışmasını Engelleyin (Execution Disabling): Yüklenen dosyaların saklandığı dizinlerde (örneğin /uploads/) kod yorumlayıcılarının (PHP, Python vb.) çalışması sunucu yapılandırması (Nginx/Apache config) seviyesinde kesinlikle kapatılmalıdır. O dizin sadece statik dosya sunmalıdır.
- Dosyaları Web Kök Dizininin (Web Root) Dışında Tutun: Mümkünse yüklenen hassas dosyalar web sunucusunun dışındaki bir dizinde saklanmalı, kullanıcıya sunulurken özel bir aracı script üzerinden yetki kontrolüyle servis edilmelidir.
- Dosya İçeriğini Derinlemesine Doğrulayın: Sadece uzantıya veya başlığa bakmak yetmez; kütüphaneler (örneğin PHP'deki getimagesize() veya GD kütüphanesi) kullanılarak dosyanın gerçekten bir görsel olup olmadığı matematiksel olarak parse edilerek doğrulanmalıdır.
ÖZET VE TOPARLAMA
Bugün siber güvenliğin en sert ve sonuçları en yıkıcı zafiyetlerinden birini masaya yatırdık:
- Masum dosya yükleme alanlarının arka planda nasıl birer ölümcül silaha dönüştüğünü gördük.
- RCE (Remote Code Execution) kavramının sunucu terminaline uzanan yolculuğunu teknik detaylarıyla ele aldık.
- İstemci filtreleri, kara liste mantığı, MIME-Type ve Magic Bytes gibi filtrelerin nasıl baypas edildiğini inceledik.
- Beyaz liste, rastgele dosya isimleri ve dizin izinleri ile sunucumuzu nasıl çelikten bir kaleye dönüştüreceğimizi konuştuk.
Pratik yapmadan bu işlerin oturmayacağını tekrar hatırlatmak isterim. Kendi lab ortamlarınızda File Upload ve RCE senaryolarını bizzat test etmek, o baypas tekniklerini kendi ellerinizle denemek vizyonunuzu tamamen değiştirecektir.
Bu içerikte yer alan teknik bilgiler yalnızca eğitim, farkındalık ve yetkili güvenlik testleri amacıyla paylaşılmıştır. Anlatılan yöntemlerin yalnızca kendi sistemlerinizde veya açıkça izin verilmiş laboratuvar/test ortamlarında uygulanması tavsiye edilir. |
Bir sonraki bölümde, sunucunun iç ağındaki gizli servisleri hedef alan ve dışarıdan erişilemeyen sistemleri vuran SSRF ve XXE Zafiyetleri dünyasına adım atacağız. Hazırlıkları şimdiden yapın.
Bu günkü konumuz bu kadardı.
Kodunuz bug'sız, kahveniz koyu olsun.
İyi Forumlar Dilerim.