材料包含漏洞
1.什么是文件囊括漏洞?
通过资料含有漏洞是指,在Web应用程序的制作过程中,为了代码的灵活性和复用性,程序员会应用“含有”函数,将另一个文件中的代码引入并执行。如果这个要被包含的文件名允许被用户控制,而脚本又没有进行严格的校验,攻击者就能够利用这一点,含有并执行任意文档,从而导致敏感信息泄露、代码执行等严重后果。(以下大家以PHP包括函数为例,最常见)
2.含有函数类型
2.1 include语句
功能:包含并运行指定文件。
特点:如果包含的文件不存在,会抛出一个Warning错误(警告),但脚本会继续执行。
2.2 require语句
功能:涵盖并运行指定文件。
特点这个文件缺失,程序就没有继续运行的意义。就是:要是具备的文件不存在,会抛出一个Compile_Error错误(致命错误),并停止脚本执行。通常用于引入对于程序运行至关重要的文件,比如数据库连接配备。若
2.3 include_once语句
功能:与
include相同,但会检查该文件是否已经被包含过。如果是,则不会再次包含。特点:避免函数重定义、变量重新赋值等问题;同样,文件不存在时产生警告,脚本继续执行。
2.4 require_once语句
功能:与
require相同,但会检查该文件是否已经被包含过。如果是,则不会再次包含。特点:结合了
require的强制性和_once的唯一性;文件不存在时产生致命错误,脚本停止。
3.文件包含漏洞类型
3.1 本地文件包含(LFI)
定义:攻击者能够包含并读取或执行Web服务器本地文件系统上的文件。以下这个代码没有过滤信息,page可以为任何参数。
攻击者如何利用?
攻击者的思路是:经过目录遍历来包含系统上的敏感文件。
读取系统敏感文件:
http://example.com/index.php?page=../../../../etc/passwd
攻击者使用
../向上回溯目录,最终指向了Linux系统的/etc/passwd文件。服务器会尝试包含这个文件,由于其内容是文本,会被直接显示在网页上,造成信息泄露。其他目标文档包括:
../../config/database.php(数据库配置文件,含密码)
../../.env(环境配置文件,通常包含敏感信息)
/proc/self/environ(包含环境变量)Apache/Nginx 的日志档案(可用于注入代码)
结合文件上传获取代码执行:
如果网站有上传功能(如图片),攻击者可以上传一个包含PHP代码的文本文件或图片马(如
shell.jpg)。然后通过LFI漏洞去包含这个上传的文件:
http://example.com/index.php?page=./uploads/shell.jpg服务器会将该图片文件作为PHP代码解析执行,攻击者从而获得一个Webshell。
3.2 远程文件包含(RFI)
通过定义: 攻击者能够包含并执行一个位于远程服务器(例如,攻击者自己的网站)上的文件,条件比较苛刻,配置文件php.ini中参数allow_url_include要设置成On。 以下这个代码没有过滤信息,page能够为任何参数。
攻击者如何利用?
思路:让存在漏洞的服务器去包含一个我放在外部的恶意脚本。
(1)攻击者在自己的服务器上(
http://attacker.com/)创建一个包含PHP后门的文本文件,例如命名为evil.txt,内容为:
(2)攻击者构造一个恶意的URL,诱使目标服务器去包含这个远程材料:
(3)存在漏洞的服务器(
vulnerable-site.com)收到请求后,会尝试从evil.txt下载文件内容。由于是通过include函数引入的,下载下来的文本会被当作PHP代码执行。(4)此时,攻击者就完全控制了目标网站。他可以凭借以下方式执行任意命令,比如:
(这个请求会先包含远程的evil.txt,然后执行whoami命令)
4.PHP伪协议
4.1 php://filter
作用:当数据流经过滤器时,会被进行某种转换(如编码、压缩、字符串替换等)。在 Web 安全,特别是文件包含漏洞中,
php://filter的核心价值在于:即使无法直接执行目标文件的 PHP 代码,也能读取到其源代码。
语法:
php://filter/read=过滤器1|过滤器2/resource=目标文件
php://filter/write=过滤器1|过滤器2/resource=目标文件
read=:应用于读取流时的过滤器。
write=:应用于写入流时的过滤器。
|:用于连接多个过滤器,形成过滤器链。数据会依次经过这些过滤器。
resource=:指定要处理的目标资源。
常用过滤器:
1. 编码类过滤器 - 最常用
convert.base64-encode:
用途:将数据流进行 Base64 编码。这是读取 PHP 源代码的首选方法。
convert.base64-decode:
用途:将数据流进行 Base64 解码。有时可用于绕过对特定关键词的过滤。
string.rot13:
用途:对数据流进行 ROT13 编码。PHP 代码中的字母会被转换,但
<?php中的<?不会被转换,所以如果网站直接显示输出,包含后可能会执行部分代码,不如 base64 稳定。
convert.iconv.*(字符集转换):
用途:非常强大,用于不同字符集间的转换。常用于构造一些特殊的字符串来绕过 WAF(Web 应用防火墙) 的检测。
示例:
convert.iconv.UTF-8.UTF-16:将 UTF-8 转换为 UTF-16。
convert.iconv.UTF-8.UTF-7:将 UTF-8 转换为 UTF-7。通过多次转换,可能将敏感词如
php变成其他形式,绕过简单的正则匹配。2. 字符串处理过滤器
string.toupper:将字符串转换为大写。
string.tolower:将字符串转换为小写。
string.strip_tags:尝试去除流中的 PHP 和 HTML 标签。慎用!如果与include一起用,会导致 PHP 代码被去除,从而无法执行。
实战利用步骤(以读取源码为例):
1.发现文件包含点:找到一个参数,如
?file=index.php。2.构造 Payload:将参数值替换为
?file=php://filter/convert.base64-encode/resource=index.php3.发送请求并获取结果:页面上会显示一串 Base64 编码的字符串。
4.解码:使用
base64_decode函数或在线 Base64 解码工具,还原出文件的原始内容。
4.2 data协议
作用:data协议是一种允许将小型数据项内嵌在URL中的方案。简单来说,它可以把一段数据(比如通过Base64编码的图片/文本等)直接写URL里,而不是指向一个远程服务器上的资源。在 PHP 中,data协议主要与文件处理函数(如include,require等)结合使用,其作用可以概括为:将数据直接作为“文件内容”传递给这些函数,而无需创建一个真实的物理文件;也可以动态地生成一段 PHP 代码或数据,并通过data协议传递给处理函数。核心要点:当 PHP 的文件系统函数遇到一个以
data://开头的 URI 时,它们不会去磁盘或网络上寻找文件,而是直接解析这个 URI 中包含的数据内容。
语法:data:[<media type>][;base64],<data>
各部分说明:
data::协议标识符,固定格式。
<media type>:可选项。指定数据的 MIME 类型,例如text/plain,text/html,image/png。如果省略,默认为text/plain;charset=US-ASCII。
;base64:可选项。如果存在,表示<data>部分是用 Base64 编码过的。如果不存在,则<data>部分是普通的 URL 编码文本。
,:分隔符,用于将元数据与数据本身分开。
<data>:实际的数据内容例子:
普通文本:data:text/plain,Hello%20World%21(这表示一个纯文本,内容是 "Hello World!")
Base64 编码的文本:data:text/plain;base64,SGVsbG8gV29ybGQh(这是 "Hello World!" 的 Base64 编码形式)
Base64 编码的 PHP 代码(这是攻击中常见的形式):
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+(这段 Base64 解码后是
<?php phpinfo();?>)
攻击原理
漏洞产生条件:当 PHP 代码使用
include,require等函数包含一个用户可控的参数,并且没有对参数进行严格的过滤(例如,允许包含远程文件或特殊协议)时,就产生了文件包含漏洞。漏洞代码示例:
利用 data 协议:攻击者可以构造一个特殊的 URL,将
file参数指向一个包含恶意 PHP 代码的data。攻击载荷:(base64编码解析成<?php phpinfo();?>)
攻击结果:当 PHP 执行
include($file)时,它看到data://协议,于是不去读取磁盘上的welcome.php,而是直接解析dataURI 中的内容<?php phpinfo();?>,并将其作为 PHP 代码执行。这样,攻击者就可以在服务器上执行任意代码。攻击成功的关键条件:
存在文件包含漏洞:用户输入未被正确过滤。
PHP 部署允许:
allow_url_include配置项必须为On(默认是Off)。这是最关键的条件。如果allow_url_include=Off,PHP 将不允许通过include等函数使用data、http等 URL 包装器。
4.3 php://input
作用:php://input 是一个只读流,用于访问 HTTP 请求的原始主体。
攻击原理:
第1步:发现漏洞点
找到包含漏洞的URL,如:http://target.com/vuln.php?file=welcome.php第2步:构造攻击URL
将file参数改为php://input:http://target.com/vuln.php?file=php://input第3步:发送POST请求包含恶意代码
使用设备(如burp suite)发送POST请求,在请求体中包含PHP代码:
第4步:服务器执行恶意代码
服务器会执行
phpinfo()函数,泄露PHP配置、系统路径、环境变量等敏感信息。攻击成功的条件:
存在文件包含漏洞:用户输入未被正确过滤。
PHP 配置允许:
allow_url_include配置项必须为On(默认是Off)。这是最关键的条件。如果allow_url_include=Off,PHP 将不允许通过include等函数使用data、http等 URL 包装器。
5.应对策略
5.1 白名单策略(最有效方案)
绝对不要使用用户输入直接包含文件。取而代之的是,建立一个允许访问的文件列表(白名单)。将用户输入(如参数?page=home)与一个预定义的白名单进行匹配,如果输入不在白名单内,则返回错误页面或默认页面。
5.2 严格验证和过滤所有用户输入
使用正则表达式等手段,只允许输入特定类型的字符。例如,如果页面名应该是英文,就只允许字母、数字、下划线和连字符,任何特殊符号(如 /, ., \)都应被拒绝。
去除恶意序列: 主动过滤掉输入中的目录遍历序列,如
../和..\,防止攻击者跳转到上级目录。使用基础文件名函数: 使用
basename()函数。这个函数会剥离任何路径信息,只返回文件名部分。例如,即使用户输入../../../etc/passwd,经过basename()处理后也只会剩下passwd,从而使其无法跳出当前目录。长度限制:对输入的长度进行限制,过长的输入很可能是攻击载荷,应直接拒绝。
5.3 PHP部署加固
禁用远程涵盖(最关键): 在PHP配置文件(php.ini)中将
allow_url_include设置为Off。这直接关闭了“远程文件包含(RFI)”漏洞的大门,使得攻击者无法从外部URL加载恶意代码。限制记录操作范围: 使用
open_basedir指令,这个指令可以将PHP脚本的文件操作(包括包含文件)限制在指定的目录树中。即使攻击者成功利用了漏洞,也无法跳出这个范围去访问像/etc/passwd这样的系统敏感文件。禁用危险函数: 通过
disable_functions配置,禁用一些不必要的但危险性很高的函数,如eval(),exec(),system()等。这可以防止文件包含漏洞进一步演变成执行系统命令的严重漏洞







浙公网安备 33010602011771号