1 file:// — 访问本地文件系统
2 http:// — 访问 HTTP(s) 网址
3 ftp:// — 访问 FTP(s) URLs
4 php:// — 访问各个输入/输出流(I/O streams)
5 zlib:// — 压缩流
6 data:// — 数据(RFC 2397)
7 glob:// — 查找匹配的文件路径模式
8 phar:// — PHP 归档
9 ssh2:// — Secure Shell 2
10 rar:// — RAR
11 ogg:// — 音频流
12 expect:// — 处理交互式的流
不受allow_url_fopen,allow_url_include影响
条件:
allow_url_fopen : off/on
allow_url_include: off/on
作用:
用于访问本地文件系统,在ctf中通常用来读取本地文件
在include() / require() / include_once() / require_once() 参数可控的情况下,即使导入非.php文件,如shell.txt ,依然按照php语法进行解析,这是include()函数所决定的
说明:
file:// 文件系统是php使用的默认封装协议,用于展示本地文件系统。
用法示例:
1.file://[文件的绝对路径和文件名]
http://127.0.0.1/include.php?file=file://E:\phpStudy\PHPTutorial\WWW\phpinfo.txt
2.file://[文件的相对路径和文件名]
http://127.0.0.1/include.php?file=./phpinfo.txt
3.http://网络位置和文件名
http://127.0.0.1/include.php?file=http://127.0.0.1/phpinfo.txt
综上所述,file://后面只能跟绝对路径,跟相对路径的时候就不要写file://了。
查看这个例子:
<?php
$filename = 'file://D:\MyApplication\phpstudy_pro\WWW\example.txt';
$content = file_get_contents($filename);
echo $content;
?>
此时的输出是php解析后的内容:
这个例子中,我们把file://协议写到了file_get_contents()方法中去,该方法主要用来读取文件,使用file协议即可读取本地文件,但实际上,使用还是不使用file://都可以读取本地文件,为什么还要使用file://呢?像下面这也可以成功读取本地文件而没有在方法中使用file协议:
<?php
$filename = 'D:\MyApplication\phpstudy_pro\WWW\example.txt';
$content = file_get_contents($filename);
echo $content;
?>
这问题问的挺有水平的哈哈哈哈,也许是为了规范?不太清楚。听听我导师怎么说吧:
file://开头的是个URL,你理解一下URL是啥意思
好冷漠,行吧,我不该多此一举问的呜呜呜
如何使文件不被解析而只输出文件源代码呢?这点在ctf中常考。这里就会使用到过滤器,但file:// 不支持通过 filter 对文件内容进行过滤处理,可以使用 php://filter 对这些流进行过滤处理。下面就让我们看看php://吧
条件
allow_url_open : off/on allow_url_include: 仅 php://input php://stdin
php://memory php://temp 需要on
作用:
php:// 访问各个输入/输出流 (I/O streams), 在ctf中经常使用的是 php://filter 和 php://input
php://filter 用于读取源码
php://input 用于执行php代码
说明
php提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流,标准输入输出流和错误描述符.
协议参数
读链是一系列过滤器的组合,它们按顺序应用于输入流。这些过滤器可以执行各种操作,如解码、解压缩、替换等。
常用方式:
php://filter/read=convert.base64-encode/resource=index.php
php://filter/resource=index.php
php://filter使用
php://filter/read=convert.base64-encode/resource=[文件名]
利用filter协议读文件,将index.php通过base64编码后进行输出。这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。
而使用的convert.base64-encode,就是一种过滤器。
下面来看一个例子,使用了过滤器编码:
<?php
$filename = 'D:\MyApplication\phpstudy_pro\WWW\example.txt';
$content = file_get_contents("php://filter/read=convert.base64-encode/resource={$filename}");
echo $content;
?>
如果不使用编码,就不能写过滤器编码了,只能直接读取文件:
<?php
$content = file_get_contents("php://filter/resource=example.php");
echo $content;
?>
运行看看:
我尝试了相对和绝对路径都不行,我又厚脸皮问我导师去了,呜呜我太伤心了,他好像只管他身边的实习生,远在他乡的我好像就被遗忘了,也许是我想多了。
看官网说read是可选参数,我也不知道为啥就是不行:
知道的朋友解答一下捏?
php://input的使用
http://127.0.0.1/include.php?file=php://input
代码:
<?php
// 使用php://input读取POST请求体
$inputData = file_get_contents("php://input");
echo $inputData;
// 打印读取到的数据
echo urldecode($inputData);
?>
url解码之后即可查看post请求的内容。
zip://
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
要用#分隔压缩包和压缩包里的内容,并且#要用url编码%23(即下述POC中#要用%23替换)
只需要是zip的压缩包即可,后缀名可以任意更改。
相同的类型的还有zlib://和bzip2://
总之要代码被解析就用file协议,想看源代码就用php协议编码。
相关问题:exit利用php伪协议绕过;