PHP伪协议
PHP伪协议
0x00 何为伪协议
PHP官网的解释:
PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。 除了这些封装协议,还能通过 stream_wrapper_register() 来注册自定义的封装协议。
支持的协议:
1 | file:// — 访问本地文件系统 |
0x01 用法
file://
PHP.ini:
file:// 协议在双off的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件
且不受allow_url_fopen与allow_url_include的影响
1 | //file.php |
php://
php://filter在双off的情况下也可以正常使用;
php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。
php:// 访问各个输入/输出流(I/O streams)
在CTF中经常使用的是php://filter和php://input
- php://filter用于读取源码
- php://input用于执行php代码。
php://filter
php://filter
是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
1 | resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
过滤器
字符串过滤器
1 | string.rot13 等同于用 str_rot13()函数处理所有的流数据 |
转换过滤器
1 | convert.base64-encode 等同于base64_encode()函数处理所有的流数据 |
压缩过滤器
1 | zlib.deflate 压缩 |
加密过滤器
mcrypt
mdecrypt
用的不多,不说了
php://input
php://input 是个可以访问请求的原始数据的只读流,可以读取到post没有解析的原始数据, 将post请求中的数据作为PHP代码执行。因为它不依赖于特定的 php.ini 指令。
注:enctype=”multipart/form-data” 的时候 php://input 是无效的。
allow_url_fopen :off/on
allow_url_include:on
payload
1 | url:http://127.0.0.1/file.php?page=php://input |
实例
1 | $user = $_GET["user"]; |
php://output
是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。
payload
1 | #file.php |
data://
data:资源类型;编码,内容
数据流封装器
当allow_url_include 打开的时候,任意文件包含就会成为任意命令执行
PHP.ini:
data://协议必须双在on才能正常使用;
allow_url_fopen :on
allow_url_include:on
php 版本大于等于 php5.2
payload
1 | $file.php |
zip://, bzip2://, zlib://
PHP.ini:
zip://, bzip2://, zlib://协议在双off的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
1 | 3个封装协议,都是直接打开压缩文件。 |
注:zip://, bzip2://, zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名。
zip://
php 版本大于等于 php5.3.0
payload
1 | zip://archive.zip#dir/file.txt |
bzip2://
payload
1 | compress.bzip2://file.bz2 |
示例
1 | 用7-zip生成一个bz2压缩文件。 |
zlib://
同理