材料包含漏洞

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. 1.发现文件包含点:找到一个参数,如 ?file=index.php

  2. 2.构造 Payload:将参数值替换为

    • ?file=php://filter/convert.base64-encode/resource=index.php

  3. 3.发送请求并获取结果:页面上会显示一串 Base64 编码的字符串。

  4. 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>:实际的数据内容

例子:

  1. 普通文本:data:text/plain,Hello%20World%21(这表示一个纯文本,内容是 "Hello World!")

  2. Base64 编码的文本:data:text/plain;base64,SGVsbG8gV29ybGQh(这是 "Hello World!" 的 Base64 编码形式)

  3. Base64 编码的 PHP 代码(这是攻击中常见的形式):

  4. data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+(这段 Base64 解码后是 <?php phpinfo();?>)

攻击原理

  1. 漏洞产生条件:当 PHP 代码使用 include, require等函数包含一个用户可控的参数,并且没有对参数进行严格的过滤(例如,允许包含远程文件或特殊协议)时,就产生了文件包含漏洞。

    漏洞代码示例

  2. 利用 data 协议:攻击者可以构造一个特殊的 URL,将 file 参数指向一个包含恶意 PHP 代码的 data

    攻击载荷:(base64编码解析成<?php phpinfo();?>)

  3. 攻击结果:当 PHP 执行 include($file) 时,它看到 data:// 协议,于是不去读取磁盘上的 welcome.php,而是直接解析 data URI 中的内容 <?php phpinfo();?>,并将其作为 PHP 代码执行。这样,攻击者就可以在服务器上执行任意代码。

攻击成功的关键条件:

  1. 存在文件包含漏洞:用户输入未被正确过滤。

  2. PHP 部署允许allow_url_include 配置项必须为 On(默认是 Off)。这是最关键的条件。如果 allow_url_include=Off,PHP 将不允许通过 include 等函数使用 datahttp 等 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配置、系统路径、环境变量等敏感信息。

攻击成功的条件:

  1. 存在文件包含漏洞:用户输入未被正确过滤。

  2. PHP 配置允许allow_url_include 配置项必须为 On(默认是 Off)。这是最关键的条件。如果 allow_url_include=Off,PHP 将不允许通过 include 等函数使用 datahttp 等 URL 包装器。

5.应对策略

5.1 白名单策略(最有效方案)

绝对不要使用用户输入直接包含文件。取而代之的是,建立一个允许访问的文件列表(白名单)。将用户输入(如参数?page=home)与一个预定义的白名单进行匹配,如果输入不在白名单内,则返回错误页面或默认页面。

5.2 严格验证和过滤所有用户输入

使用正则表达式等手段,只允许输入特定类型的字符。例如,如果页面名应该是英文,就只允许字母、数字、下划线和连字符,任何特殊符号(如 /, ., \)都应被拒绝。

  1. 去除恶意序列: 主动过滤掉输入中的目录遍历序列,如 ../..\,防止攻击者跳转到上级目录。

  2. 使用基础文件名函数: 使用 basename() 函数。这个函数会剥离任何路径信息,只返回文件名部分。例如,即使用户输入 ../../../etc/passwd,经过 basename() 处理后也只会剩下 passwd,从而使其无法跳出当前目录。

  3. 长度限制:对输入的长度进行限制,过长的输入很可能是攻击载荷,应直接拒绝。

5.3 PHP部署加固

  1. 禁用远程涵盖(最关键): 在PHP配置文件(php.ini)中将 allow_url_include 设置为 Off。这直接关闭了“远程文件包含(RFI)”漏洞的大门,使得攻击者无法从外部URL加载恶意代码。

  2. 限制记录操作范围: 使用 open_basedir 指令,这个指令可以将PHP脚本的文件操作(包括包含文件)限制在指定的目录树中。即使攻击者成功利用了漏洞,也无法跳出这个范围去访问像 /etc/passwd 这样的系统敏感文件。

  3. 禁用危险函数: 通过 disable_functions 配置,禁用一些不必要的但危险性很高的函数,如 eval(), exec(), system() 等。这可以防止文件包含漏洞进一步演变成执行系统命令的严重漏洞

posted @ 2025-10-11 10:04  ycfenxi  阅读(4)  评论(0)    收藏  举报