尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

DVWA文件包含漏洞实战:从LFI/RFI原理到高级利用与防御

DVWA文件包含漏洞实战:从LFI/RFI原理到高级利用与防御 1. 项目概述从靶场到实战理解文件包含漏洞的本质如果你正在学习网络安全尤其是Web安全那么“DVWA-文件包含File Inclusion”这个标题对你来说一定不陌生。DVWADamn Vulnerable Web Application是一个著名的、故意设计得漏洞百出的PHP/MySQL应用是无数安全从业者和爱好者的“练功房”。而“文件包含”漏洞则是Web安全领域中一个极具代表性且危害巨大的漏洞类型它允许攻击者将服务器上的任意文件甚至远程文件包含到当前脚本中执行。这听起来可能有点抽象我打个比方你家里的水管Web应用本来只应该从自家的水龙头指定目录取水包含文件但因为这个漏洞水管工攻击者可以偷偷把水管接到隔壁邻居家甚至接到化工厂的排污口系统敏感文件或远程恶意脚本结果可想而知。我接触DVWA和文件包含漏洞已经很多年了从最初照着教程点点鼠标到后来在真实渗透测试项目中遇到它的各种变体深知这个漏洞的狡猾与危险。很多人觉得在靶场里通关很简单但到了真实、复杂的生产环境往往就束手无策。这篇文章我将以一个老鸟的视角带你彻底拆解DVWA中的文件包含漏洞。我们不止步于完成靶场任务更要深挖其背后的四种包含类型本地文件包含LFI、远程文件包含RFI、PHP相关配置的深层影响、绕过各种防护限制的技巧以及如何将靶场经验转化为实战能力。无论你是刚入门的新手还是想巩固基础的中级选手这篇超过5000字的深度解析都将为你提供从原理到实战的完整地图。2. 漏洞原理深度剖析为什么“包含”会变得危险在深入操作之前我们必须先搞清楚文件包含漏洞到底是怎么产生的。这不仅仅是知道“怎么利用”更重要的是理解“为什么能被利用”这是你未来进行代码审计和漏洞挖掘的基础。2.1 PHP包含函数的工作机制文件包含漏洞的核心在于PHP或其他服务端语言如JSP、ASP提供的文件包含函数。在PHP中主要有四个include()require()include_once()require_once()它们的本意是优秀的代码复用工具。想象一下你有一个网站每个页面的头部导航栏和尾部版权信息都是一样的。聪明的做法是把这些公共部分写成header.php和footer.php然后在每个页面里只需要写一行include(‘header.php’);就行了。这样既便于维护也减少了代码冗余。这些函数在执行时会读取指定路径的文件内容并将其中的PHP代码当作当前脚本的一部分来执行。关键就在这里如果开发者能够严格控制这个“指定路径”那就安全但如果这个路径的一部分或全部可以由用户通过URL参数、表单输入等方式来控制危险就产生了。在DVWA的File Inclusion模块中模拟的正是这种场景。通常它会有一个类似这样的脆弱代码$file $_GET[‘page’]; // 直接从用户输入获取文件名 include($file . ‘.php’); // 直接包含该文件攻击者可以通过构造?page../../../../etc/passwd这样的参数让$file变量变成../../../etc/passwd最终拼接成../../../etc/passwd.php。虽然加了.php后缀但通过路径遍历../跳出了程序设定的目录去包含系统敏感文件/etc/passwd。由于/etc/passwd不是PHP文件include()函数会将其内容以文本形式读出并显示在页面上从而造成信息泄露。2.2 本地文件包含与远程文件包含根据包含文件的来源漏洞分为两类本地文件包含包含的是服务器本地的文件如上文的/etc/passwd。这是最常见的情况。远程文件包含包含的是远程服务器上的文件。例如攻击者在自己控制的服务器上放置一个包含PHP代码的文本文件然后通过漏洞让目标服务器去包含这个远程URL。如果成功目标服务器会下载并执行该文件中的恶意代码相当于直接获得了Webshell。RFI的危害比LFI大得多因为它意味着攻击者可以从外部注入任意代码。但RFI的实现需要一个关键前提PHP的allow_url_include配置项必须为On默认是Off。在DVWA中你可以通过调整安全等级来模拟该配置开启或关闭的环境。2.3 文件包含漏洞的常见危害理解了原理我们来看看它能做什么敏感信息泄露读取服务器配置文件如/etc/passwd,/etc/shadow,.env数据库配置文件、应用程序源码、日志文件等。获取Webshell结合文件上传漏洞上传一个图片马将PHP代码嵌入图片然后通过LFI包含这个图片文件其中的PHP代码会被执行。或者在RFI开启时直接包含远程的恶意脚本。执行系统命令包含一些存储了命令输出的特殊文件如/proc/self/environ环境变量、日志文件如果其中写入了用户输入在特定条件下可导致命令执行。拒绝服务包含一个巨大的文件或设备文件如/dev/zero可能导致服务器资源耗尽。注意在真实环境中进行未经授权的渗透测试是违法行为。所有学习研究都应在像DVWA这样的授权靶场或自己搭建的隔离环境中进行。3. DVWA环境搭建与配置要点工欲善其事必先利其器。一个稳定、配置正确的DVWA环境是实验的基础。网络上教程很多但坑也不少我结合自己的经验梳理几个关键点。3.1 选择你的“练功房”搭建方式主要有三种路径集成环境包如XAMPP、PHPStudy。这是对新手最友好的方式特别是在Windows系统上。以PHPStudy为例你只需要下载安装启动Apache和MySQL然后将下载的DVWA压缩包解压到www目录下访问localhost/DVWA即可。但要注意PHPStudy的不同版本可能集成的PHP版本也不同需要调整DVWA的配置文件以匹配。Docker方式这是目前最干净、最推荐的方式。一条命令就能拉起一个包含所有依赖的DVWA环境与宿主机环境隔离玩坏了删掉容器重来就行。docker run -d --name dvwa -p 80:80 vulnerables/web-dvwa访问http://localhost即可。Docker镜像通常已经做好了最佳配置。手动搭建在Linux如Kali或macOS上手动配置Apache、PHP、MySQL。这个过程能让你更深入地理解Web服务的运行机制适合希望夯实基础的学习者。3.2 必须解决的常见配置问题无论哪种方式第一次访问DVWA时大概率会遇到红字报错。别慌这是正常步骤。数据库连接配置这是第一个拦路虎。你需要编辑DVWA/config/config.inc.php文件Docker方式可能不需要。关键参数是$_DVWA[ ‘db_server’ ] ‘127.0.0.1’; // 数据库地址Docker内可能是‘db’ $_DVWA[ ‘db_user’ ] ‘root’; // 数据库用户名 $_DVWA[ ‘db_password’ ] ‘pssw0rd’; // 数据库密码PHPStudy默认可能是‘root’或空实操心得密码错误是最常见的问题。用PHPStudy的去它的“MySQL管理器”里查看或修改密码用Docker的默认密码通常是pssw0rd手动搭建的就是你安装MySQL时设定的密码。PHP函数禁用问题DVWA的某些模块如命令执行需要用到system(),passthru()等函数这些函数可能在php.ini的disable_functions列表中被禁用。你需要找到所用的PHP版本的php.ini文件将相关函数从禁用列表中移除并重启Web服务。查找php.ini路径在DVWA的phpinfo()页面/DVWA/phpinfo.php里搜索“Loaded Configuration File”。文件权限问题DVWA/hackable/uploads/目录需要写入权限用于文件上传模块。在Linux下可能需要执行chmod 777 hackable/uploads/。安全等级设置DVWA左下方可以设置安全等级Low, Medium, High, Impossible。务必从Low开始否则很多漏洞的防护机制会让你无从下手。我们的实验主要在Low和Medium下进行。3.3 给你的环境“装个镜子”——配置浏览器代理单纯在页面上操作你只能看到输入和输出看不到背后的HTTP请求和响应细节。强烈建议配置一个代理工具如Burp Suite或OWASP ZAP。将浏览器代理设置为127.0.0.1:8080这样所有流量都会经过代理工具你可以拦截、查看、修改每一个请求这对于理解漏洞利用过程和构造复杂Payload至关重要。这是从业余走向专业的关键一步。4. 通关实战DVWA文件包含四重奏现在让我们进入DVWA将安全等级设为“Low”点击“File Inclusion”开始实战。页面通常有两个链接“file1.php”和“file2.php”。查看URL你会发现类似?pagefile1.php的参数。这就是我们的攻击入口。4.1 Low级别毫无防护的“裸奔”Low级别的代码几乎没有任何过滤就像我们前面原理中提到的那样。我们的目标是读取服务器上的/etc/passwd文件Linux系统。直接路径遍历将URL中的参数改为?page../../../../etc/passwd。你可能需要尝试不同数量的../来跳出Web根目录。成功的话页面上会显示系统的用户列表。利用PHP封装协议这是更强大的技巧。PHP内置了一些“封装协议”可以像访问文件一样访问各种数据流。读取PHP源码使用php://filter协议。?pagephp://filter/readconvert.base64-encode/resourceindex.php。这个Payload的意思是用php://filter对index.php文件进行读取并将其内容用base64编码后输出。为什么要编码因为如果直接包含index.php其中的PHP代码会被执行我们看不到源代码。Base64编码后我们拿到一串字符解码后就能得到纯净的源码。这是审计代码、寻找其他漏洞的利器。包含日志文件获取Shell进阶如果服务器开启了错误日志并且我们能知道其路径如/var/log/apache2/access.log我们可以尝试在User-Agent或请求参数中插入一段PHP代码比如 。然后去包含这个日志文件?page../../../../var/log/apache2/access.log。服务器执行日志文件时就会执行我们插入的代码。这需要日志文件有可读权限并且其中存储的内容能被解析。注意事项php://input协议允许你读取POST请求的原始主体数据并执行。在Low级别且allow_url_includeOn时你可以用Burp Suite拦截请求将GET改为POST然后在请求体里写?php system(‘whoami’);?同时将URL参数改为?pagephp://input。但这在DVWA默认配置下往往受限于allow_url_include设置。4.2 Medium级别初级的字符串过滤将安全等级调到Medium刷新页面。你会发现之前的Payload可能失效了。查看源码DVWA提供了“View Source”按钮你会看到类似这样的过滤$file str_replace( array( “../”, “..\” ), “”, $_GET[ ‘page’ ] );代码试图将../和..\替换为空字符串。这是一种非常幼稚的过滤很容易绕过。双写绕过既然它删除一次我们就写两次。构造?page….//….//….//….//etc/passwd。经过str_replace处理后相邻的两个..和/中间的//会被留下当第一次删除../后剩下的/会和后面的..再次组合成新的../从而成功绕过。最终….//在处理后会变成一个../。绝对路径绕过如果知道目标文件的绝对路径可以直接使用。例如?page/etc/passwd。但这通常需要信息收集猜解路径。利用PHP封装协议php://filter等协议路径通常不包含../所以依然可以直接使用?pagephp://filter/readconvert.base64-encode/resourceindex.php。4.3 High级别白名单机制的挑战High级别的防护看起来强了很多通常采用白名单机制$file $_GET[ ‘page’ ]; if( !fnmatch( “file*”, $file ) $file ! “include.php” ) { echo “ERROR: File not found!”; exit; } include( $file );代码要求page参数必须以 “file” 开头或者等于 “include.php”。这似乎堵死了所有外部文件包含的可能。但是漏洞依然存在关键在于路径截断但此技巧受PHP版本影响较大。在PHP版本小于5.3.4且magic_quotes_gpcOff的情况下可以利用空字符%00进行截断。因为include()在读取文件时会认为空字符是字符串的结束。假设代码是include($file . ‘.php’)我们传入?page../../../../etc/passwd%00那么拼接后就是../../../../etc/passwd%00.phpinclude()读到%00就停止了实际去包含的就是/etc/passwd。然而需要注意的是现代PHP环境5.3.4已经修复了空字符截断的问题且DVWA的High级别代码不一定有后缀拼接因此此方法在现代靶场中可能无效。那么在High级别下真正的突破口往往不在这里而在于利用已有的、合法的“file”开头文件。例如如果服务器上存在一个叫fileupload.php的文件并且存在文件上传功能我们可以先上传一个包含恶意代码的图片文件然后通过文件包含去调用这个上传的文件。因为文件名可能是file_xxxx.jpg符合“file*”的白名单规则。这需要结合其他漏洞属于组合拳。4.4 Impossible级别如何从根本上防御Impossible级别的代码展示了最佳实践$file $_GET[‘page’]; // 只允许包含“include.php”或“file1.php”、“file2.php” switch ($file) { case ‘include.php’: case ‘file1.php’: case ‘file2.php’: break; default: $file ‘include.php’; break; } include( DVWA_WEB_PAGE_TO_ROOT . $file );它使用一个严格的switch-case白名单只允许包含预设的几个文件。用户输入根本无法改变包含的目标。同时它使用了DVWA_WEB_PAGE_TO_ROOT这个绝对路径常量进行拼接彻底杜绝了路径遍历。这就是最有效的防御方式不要信任任何用户输入对包含的文件名采用严格的白名单控制。5. 实战扩展与高级利用技巧在真实世界中漏洞很少像Low级别那样赤裸裸。我们需要更多技巧。5.1 利用日志文件包含获取Shell这是一个经典的LFI到RCE远程代码执行的案例。前提是你知道Web服务器如Apache、Nginx访问日志的绝对路径。该日志文件对Web进程可读。你能将PHP代码注入到日志内容中。步骤信息收集通过报错、已知漏洞或常见路径列表猜解日志路径。如/var/log/apache2/access.log,/var/log/nginx/access.log,C:\xampp\apache\logs\access.log等。注入代码在浏览器请求、User-Agent、Referer等HTTP头中插入PHP代码。例如使用Burp Suite或Curl发送一个请求其中User-Agent设置为 。包含日志发起文件包含请求?page../../../../var/log/apache2/access.log。服务器执行日志时就会执行phpinfo()。升级为Webshell将注入的代码改为一句话木马。然后就可以用中国菜刀或蚁剑等工具连接http://target/shell.php?cmdwhoami来执行命令。实操心得日志文件通常很大包含时可能超时或返回空白。可以尝试先截断日志如果有权限或注入代码后立即进行包含以提高成功率。另外注意日志的编码和特殊字符转义问题。5.2 PHP封装协议全解析php://filter和php://input只是冰山一角。PHP封装协议是一个宝库。zip://可以包含ZIP压缩包中的文件。例如你上传了一个ZIP文件里面有个shell.php你可以用?pagezip://path/to/archive.zip%23shell.php注意#要编码为%23来包含执行它。这常用于绕过文件上传的后缀检查。data://一个更强大的协议可以直接在URL中嵌入数据。格式data://text/plain;base64,。例如?pagedata://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg即?php system(‘whoami’);?的base64编码。这通常需要allow_url_includeOn。expect://可以用来执行系统命令如?pageexpect://ls但该模块默认不安装非常罕见。重要提示allow_url_include和allow_url_fopen是两个不同的配置。后者允许fopen()打开URL是很多协议如http://能用的前提前者特指include/require系列函数能否包含URL。在生产环境中务必确保两者都为Off。5.3 绕过路径限制与编码技巧当简单的../被过滤时可以尝试URL编码../可以编码为%2e%2e%2f或..%2f。有时双重编码可能有效%252e%252e%252f%25是%的URL编码。操作系统特性在Windows下路径分隔符是\也可以尝试..\。或者利用Windows的UNC路径\\?\C:\...或8.3短文件名格式。容器/环境变量包含/proc/self/environ文件其中包含了环境变量。如果User-Agent等HTTP头信息被记录在此并且我们能够控制它比如通过Burp修改就可以注入代码。6. 从靶场到实战防御方案与代码审计视角学习攻击是为了更好的防御。作为开发者你应该严格使用白名单像DVWA的Impossible级别一样只允许包含预设的、确定的文件。这是最有效的方法。避免动态包含如果业务逻辑允许尽量使用静态包含或模板引擎。净化用户输入如果必须动态包含要对用户输入进行严格过滤。但记住黑名单过滤../等永远会有遗漏应作为辅助手段。设置PHP安全配置确保php.ini中allow_url_include和allow_url_fopen为Off。将open_basedir限制在Web目录防止跨目录访问。使用绝对路径在包含文件时使用基于项目根目录的绝对路径避免相对路径遍历。降低权限Web服务器进程如www-data, apache用户应以最低必要权限运行避免其读取系统敏感文件。作为安全人员在进行代码审计时要全局搜索include(),require(),include_once(),require_once()这些函数检查它们的参数是否用户可控是否经过严格校验。不仅要看GET/POST参数还要注意$_COOKIE,$_SERVER中的某些变量如$_SERVER[‘PHP_SELF’]也可能被利用。文件包含漏洞就像一扇不该被打开的后门。在DVWA中的练习让我们熟悉了这扇门的各种锁芯和撬锁工具。但现实中的系统门可能藏在更隐蔽的地方锁也可能更复杂。真正的能力是在代码中一眼认出这扇门并知道如何为它装上最坚固的锁。希望这篇长文能成为你手中那把打开Web安全大门的钥匙之一。最后一个小建议在DVWA通关后不妨去尝试一下更复杂的综合靶场比如“Web for Pentester”或“HackTheBox”上的简单机器在那里文件包含往往只是整个攻击链中的一环你会对它的实战价值有更深的理解。
返回列表