在完成檔案上傳漏洞後,今天我們接著學習常與上傳漏洞搭配的File Inclusion(檔案包含漏洞)。在許多模化開發的Web應用中,開發者常會用一個主頁面(如 index.php)透過參數動態載入不同的頁面模組(如 header.php、about.php)。如果沒有對傳入的檔名進行過濾,就會產生嚴重的安全漏洞。
File Inclusion發生在程式碼使用包含函式(如 PHP 的 include、require、include_once)時,將使用者可控的變數直接當成檔名傳入。
主要分為兩種型態:
LFI (Local File Inclusion,本地檔案包含):攻擊者只能讀取或包含伺服器本機上已存在的檔案。
RFI (Remote File Inclusion,遠端檔案包含):攻擊者可以傳入外部網址。
進入DVWA左側選單File Inclusion。
?page=include.php
?page=file1.php
這確認了後端採用了 $_GET['page'] 參數來動態載入目標檔案。
3.進階危害:LFI 轉 RCE (Log Poisoning 概念)
在真實滲透測試中,若攻擊者能透過LFI讀取Apache/Nginx的Access Log(存取日誌),只要在發送HTTP請求時將 User-Agent改成PHP木馬:
User-Agent:
日誌就會記錄這段 PHP 程式碼。接著攻擊者再利用 LFI 去 include 該日誌檔(如 /var/log/apache2/access.log),就能將 LFI 升級為遠端指令執行(RCE)!
在 Low 安全等級下,後端的 PHP 程式碼極度危險:
$file = $_GET[ 'page' ];
include( $file );
後端完全信任 $file 變數,導致攻擊者可以使用 ../ 任意穿越目錄,或是透過 PHP Pseudo-wrapper(如 php://filter)來讀取 PHP 原始碼的 Base64 編碼。
1.避免動態包含檔案:
盡可能將需要包含的頁面固化寫死,不要讓使用者輸入決定檔名。
2.實施強烈的白名單機制(Whitelist):
建立可被包含檔案的白名單列舉:
$allowed_pages = [
'page1.php' => 'page1.php',
'page2.php' => 'page2.php',
];
if (isset($allowed_pages[$_GET['page']])) {
include($allowed_pages[$_GET['page']]);
}
3.過濾路徑穿越符號:
使用basename()只保留檔名,剝離 ../ 或 / 等目錄轉移字元。
4.關閉遠端檔案包含 (針對 RFI):
在php.ini設定檔中,確保將 allow_url_include 設定為 Off(預設通常為 Off)。