5.1.6. PHP流
5.1.6.1. 简介
流(Streams)的概念是在php 4.3引入的,是对流式数据的抽象,用于统一数据操作,比如文件数据、网络数据、压缩数据等。
流可以通过file、open、fwrite、fclose、file_get_contents、file_put_contents等函数操作。
5.1.6.2. 封装协议
PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。支持的协议可用 stream_get_wrappers()
查看。
file://
访问本地文件系统http://
访问 HTTP(s) 网址ftp://
访问 FTP(s) URLsphp://
访问各个输入/输出流(I/O streams)zlib://
压缩流data://
数据(RFC 2397)glob://
查找匹配的文件路径模式phar://
PHP 归档ssh2://
Secure Shell 2rar://
RARogg://
音频流expect://
处理交互式的流
5.1.6.3. PHP支持流
PHP 提供了一些输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符,内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。
需要注意的是,流不受 allow_url_fopen
限制,但是 php://input
、 php://stdin
、 php://memory
和 php://temp
受限于 allow_url_include
。
5.1.6.3.1. 输入输出流
php://stdin
、 php://stdout
和 php://stderr
允许直接访问 PHP 进程相应的输入或者输出流。数据流引用了复制的文件描述符,所以如果在打开 php://stdin
并在之后关了它,仅是关闭了复制品,真正被引用的 STDIN 并不受影响。
其中 php://stdin
是只读的, php://stdout
和 php://stderr
是只写的。
5.1.6.3.2. fd
php://fd 允许直接访问指定的文件描述符。例如 php://fd/3
引用了文件描述符 3。
5.1.6.3.3. memory与temp
php://memory
和 php://temp
是一个类似文件包装器的数据流,允许读写临时数据。两者的唯一区别是 php://memory
总是把数据储存在内存中,而 php://temp
会在内存量达到预定义的限制后(默认是 2MB)存入临时文件中。临时文件位置的决定和 sys_get_temp_dir()
的方式一致。
php://temp
的内存限制可通过添加 /maxmemory:NN
来控制,NN 是以字节为单位、保留在内存的最大数据量,超过则使用临时文件。
5.1.6.3.4. input
php://input
是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input
来代替 $HTTP_RAW_POST_DATA
,因为它不依赖于特定的 php.ini 指令。而且,这样的情况下 $HTTP_RAW_POST_DATA
默认没有填充,比激活 always_populate_raw_post_data
潜在需要更少的内存。 enctype="multipart/form-data"
的时候 php://input
是无效的。
5.1.6.4. filter
php://filter
是一种元封装器,设计用于数据流打开时的筛选过滤应用。PHP默认提供了一些流过滤器,除此之外,还可以使用各种自定义过滤器。
filter有resource, read, write三个参数,resource参数是必须的。它指定了你要筛选过滤的数据流。 read和write是可选参数,可以设定一个或多个过滤器名称,以管道符(|)分隔。
5.1.6.4.1. 过滤器列表
可以通过 stream_get_filters()
获取已经注册的过滤器列表。其中PHP内置的过滤器如下:
- 字符串过滤器
- string.rot13
- string.toupper
- string.tolower
- string.strip_tags
- 转换过滤器
- convert.base64-encode
- convert.base64-decode
- convert.quoted-printable-encode
- convert.quoted-printable-decode
- convert.iconv.*
- 压缩过滤器
- zlib.deflate
- zlib.inflate
- bzip2.compress
- bzip2.decompress
- 加密过滤器
- mcrypt.
ciphername
- mdecrypt.
ciphername
- mcrypt.
5.1.6.4.2. 过滤器利用tricks
- LFI
php://filter/convert.base64-encode/resource=index.php
- XXE读取文件时会因而解析报错,可用base64编码
- base64编码会弃掉未在码表内的字符,可用于绕过一些文件格式
- 部分 convert 会有大量的资源消耗,可用作DoS
- rot13 / convert 转换 过WAF