June 5, 2023

Path Traversal yoxsa LFİ?

Salam hər kəsə,Bu mövzumda çox adamın, əsas da bu mövzuları təzə öyrənən şəxslərin qarışdırdığı, məntiq olaraq oxşar amma bir-birindən fərqli olan iki güvənlik açığı haqqında qısa olaraq yazmağa çalışacam.Path Traversal və LFİ.
İlk olaraq hansının adını eşitməyimizdən asılı olmayaraq ağlımıza gələn yəqin ki ../../../../../etc/passwd payloadı olur.Bəs LFİ və Path Traversal sadəcə /etc/passwd faylındanmı ibarətdir? təbii ki xeyr.
Düzdür ki hər iki güvənlik açığı vasitəsilə serverdə müəyyən faylları oxuya bilirik,lakin LFİ-də edə biləcəklərimiz daha da dərinləşir.Çünki Path Traversalda sadəcə faylın kontentini oxuya bildiyimiz halda,LFİ-da bu sadəcə fayl oxumaqla bitmir,adından da göründüyü kimi biz faylı oxumuruq sadəcə funksiyanın olduğu fayla başqa bir faylı "include" edirik yəni daxil edirik.Bununla da əgər bizim daxil etdiyimiz faylın kontenti istifadə etdiyimiz proqramlaşdırma dilində yazılmış bir scriptdirsə artıq bizə faylın kontentini göstərmir birbaşa faylın içərisinə daxil edərək çalışdırır.Path Traversal-da sadəcə fayl oxumaqla limitlənərkən,LFİ fayl oxumaqla başlayıb sonu RCE-ə qədər gedir.Bura qədər yazdığım cümlələrdə əgər başınız qarışdısa,indi verəcəyim kod nümunələrindən sonra ümid edirəm ki bu mövzunu tam anlayacaqsız.
İlk olaraq Path Traversal-a aid bir kod nümunəsi yazaq,kodları PHP-də yazacam ki sırf bu güvənlik açığını ən yaxşı PHP-də anlamaq olur.Kodları isə geniş,sayt səhifəsi şəklində yazmayacam,sırf güvənlik açığının yarandığı hissəyə aid nümunə yazacam ki qarışıqlıq olmasın.

<?php if(isset($_GET['file'])){ $file = $_GET['file']; $content = file_get_contents($file); echo $content;} else { echo "<h1>Bu İndex səhifəsidi.</h1>"; } ?>

Bu index.php faylının məzmunudur.Kodda yazılıb ki əgər GET metodu ilə file parametri göndərilərsə ( index.php?file= və ya /?file= ) həmin parametrin aldığı dəyəri file_get_contents() funksiyası ilə çalışdır əks halda Bu İndex səhifəsidi yazısını ekrana çıxar,yəni biz file parametrinə nə dəyər versək bizə onun məzmununu göstərəcək.Gəlin praktiki göstərək.

file parametrinə message.txt dəyərini yazdıqda yekun olaraq echo file_get_contents("message.txt") kimi nəticə çıxır və bizə message.txt faylının kontentini göstərir.Bəs biz file message.txt yerinə serverdə olan başqa bir PHP faylını çağırsaq nə olacaq?Gəlin birlikdə baxaq.

Serverimizdə about.php adında bir fayl var və məzmunu aşağıdakı kimidir.

<?php echo "<h1>Bu About səhifəsidir</h1>"; ?>

Normal olaraq faylı açanda belə görüntü çıxır qarşımıza.İndi isə file parametri ilə çağıraq.

about.php faylının məzmununu olduğu kimi bizə verir yəni text formasında.Path Traversal bundan ibarətdir yəni icazəmiz olan istənilən faylın məzmununu text formatında oxuya bilirik.Artıq LFİ-a keçdikdə işlər qarışır və güvənlik açığının kritikliyi artır.LFİ üçün bir kod nümunəsi verək

<?php if(isset($_GET['file'])){ $file = $_GET['file']; include($file);} else { echo "<h1>Bu İndex səhifəsidi.</h1>"; } ?>

Ümumiyyətlə include() funksiyasının məqsədi başqa fayllarda olan kodları hər hansı digər faylın içində yenidən təkrar yazmamaqla istifadə etməkdi,məsələn,file1.php faylında $x = "salam" adında dəyişən yaratdız sonra da file2.php faylinda include("file1.php") yazıb sonra echo $x yazsaz artıq salam sözünü çap etdirəcək,nümunə kimi Pythondakı modulları da göstərə bilərik.

Hər iki nümunədə artıq PHP faylını txt kimi deyil Render edərək PHP kimi çalışdırdığını gördük,LFİ-i RCE-ə çevirməyi yolları çoxdur buna nümunə kimi Log Poisoning-i göstərə bilərik,Log Poisoning-də loglara php payloadlarının düşməsini təmin edərək(auth.log faylını oxuya biliriksə ssh useri yerinə php kodu yazmaq,access.log faylını oxuya biliriksə User-Agent yerinə php payloadı yazmaq və s.) logları php faylının içərisinə include edib php payloadlarımızı çalışdıra bilirik,digər nümunə kimi əgər Web Server root userində çalışırsa /proc/self/environ faylını include edərək User-Agent yerinə php payloadı yazıb çalışdıra bilirik(Amma bu çox az hallarda olur çünki /proc/self/environ faylının yetkisi 400 olur ona görə mütləq web server gərək root userində çalışsın).

Ümid edirəm ki bura qədər yazdıqlarımdan sonra bu güvənlik açıqları haqqında əgər bilmirdizsə ilkin məlumatları öyrənə bildiz.

İndi isə keçək güvənlik açığının qarşısının alınmasına

Ən güvənli yolu bir list yaradıb sadəcə müəyyən faylların çağırılmasına icazə verməkdir.Nümunə kimi aşağıdakı kimi kod yazmaq olar.

<?php if(isset($_GET['file'])){ $file = $_GET['file']; if ($file != "message.txt" && $file != "about.php"){ echo "Fayl tapılmadı";} else{ include($file); } } else { echo "<h1>Bu İndex səhifəsidi.</h1>"; } ?>

Oxuduğunuz üçün təşəkkürlər.