从零学习Php伪协议

以前一直有用到,根据php官方文档来详细讲下php://协议


php://

php:// — 访问各个输入/输出流(I/O streams)
常用于一些文件系统函数,如下但不限于

1
2
3
4
5
6
7
8
file_put_contents()
file_get_contents()
file_exists()
readfile()
fopen()
copy()
file()
...

还可以用于include、require语句

分类

php://stdin, php://stdout 和 php://stderr

php://stdin、php://stdout 和 php://stderr 允许直接访问 PHP 进程相应的输入或者输出流。 数据流引用了复制的文件描述符,所以如果你打开 php://stdin 并在之后关了它, 仅是关闭了复制品,真正被引用的 STDIN 并不受影响。
php://stdin 是只读的, php://stdout 和 php://stderr 是只写的。
这三个分别可以用常量STDIN、 STDOUT 和 STDERR代替

例子

这三个东西我不是很感兴趣,拿一个来看看

1
2
3
while($line = fopen('php://stdin','r')){
echo fgets($line);
}

stdin这里就是你输入啥它输出啥

php://input

php://input可以读取没有处理过的POST数据。相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要特殊的php.ini设置。
php://input 可以读取http entity body中指定长度的值,由Content-Length指定长度,不管是POST方式或者GET方法提交过来的数据。但是,一般GET方法提交数据 时,http request entity body部分都为空。
php://input 与$HTTP_RAW_POST_DATA读取的数据是一样的,都只读取Content-Type不为multipart/form-data的数据。

例子

1
2
$data=file_get_contents("php://input");
echo $data;


php://input在指定情况下构造好语句可执行php语句甚至getshell

php://output

php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。

例子

1
2
3
$f = fopen("php://output","w");
fwrite($f, "Test\n");
fclose($f);

php://filter

例子

用几个个例子说明php://filter的参数
读取base64后index.php的内容:

1
php://filter/read=convert.base64-encode/resource=index.php

将test字符串先rot13后再全部转化成大写写入test.txt文件:

1
file_put_contents("php://filter/write=string.rot13|string.toupper/resource=test.txt","test");

实现将POST内容转换成base64编码并输出:

1
readfile("php://filter/read=convert.base64-encode/resource=php://input");

php://filter 目标使用以下的参数作为它路径的一部分。 复合过滤链能够在一个路径上指定。

名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

限制

封装协议摘要(针对 php://filter,参考被筛选的封装器。)

属性 支持
受限于 allow_url_fopen No
受限于 allow_url_include 仅 php://input、 php://stdin、 php://memory 和 php://temp
允许读取 仅 php://stdin、 php://input、 php://fd、 php://memory 和 php://temp
允许写入 仅 php://stdout、 php://stderr、 php://output、 php://fd、 php://memory 和 php://temp
允许追加 仅 php://stdout、 php://stderr、 php://output、 php://fd、 php://memory 和 php://temp(等于写入)
允许同时读写 仅 php://fd、 php://memory 和 php://temp
支持 stat() 仅 php://memory 和 php://temp
支持 unlink() No
支持 rename() No
支持 mkdir() No
支持 rmdir() No
仅仅支持 stream_select() php://stdin、 php://stdout、 php://stderr、 php://fd 和 php://temp

More

翻到了几个有关于这个协议的利用方式
传送门0x00,传送门0x01,传送门0x02

Contents
  1. 1. php://
  2. 2. 分类
    1. 2.1. php://stdin, php://stdout 和 php://stderr
      1. 2.1.1. 例子
    2. 2.2. php://input
      1. 2.2.1. 例子
    3. 2.3. php://output
      1. 2.3.1. 例子
    4. 2.4. php://filter
      1. 2.4.1. 例子
  3. 3. 限制
  4. 4. More