最近在做ctf的时候,碰见了好几次关于php伪协议的妙用,所以通过学习整理出相关知识
文档:http://cn2.php.net/manual/zh/wrappers.php.php#refsect2-wrappers.php-unknown-descriptioo
php伪协议,事实上是其支持的协议与封装协议
支持的种类有这12种
* file:// — 访问本地文件系统
* http:// — 访问 HTTP(s) 网址
* ftp:// — 访问 FTP(s) URLs
* php:// — 访问各个输入/输出流(I/O streams)
* zlib:// — 压缩流
* data:// — 数据(RFC 2397)
* glob:// — 查找匹配的文件路径模式
* phar:// — PHP 归档
* ssh2:// — Secure Shell 2
* rar:// — RAR
* ogg:// — 音频流
* expect:// — 处理交互式的流
先整理一下关于php://的用法
php://
PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。
php://stdin, php://stdout 和 php://stderr
php://stdin、php://stdout 和 php://stderr 允许直接访问 PHP 进程相应的输入或者输出流。 数据流引用了复制的文件描述符,所以如果你打开php://stdin并在之后关了它, 仅是关闭了复制品,真正被引用的 STDIN 并不受影响。 推荐简单使用常量 STDIN、 STDOUT 和 STDERR 来代替手工打开这些封装器。
php://stdin是只读的,php://stdout 和 php://stderr 是只写的。
举例:
php://stdin
1 php 2 while($line = fopen('php://stdin','r')) 3 {//open our file pointer to read from stdin 4 echo $line."\n"; 5 echo fgets($line);//读取 6 } 7 ?>
可以看到打开了一个文件指针进行读取
php://stdout
1 php 2 $fd = fopen('php://stdout', 'w'); 3 if ($fd) { 4 echo $fd."\n"; 5 fwrite($fd, "这是一个测试"); 6 fwrite($fd, "\n"); 7 fclose($fd); 8 } 9 ?>
可以看到打开了一个文件指针进行写入
php://stderr
1 php 2 $stderr = fopen( 'php://stderr', 'w' ); 3 echo $stderr."\n"; 4 fwrite($stderr, "lalala" ); 5 fclose($stderr); 6 ?>
可以看到打开了一个文件指针进行写入
php://input
php://input 是个可以访问请求的原始数据的只读流。因为它不依赖于特定的 php.ini 指令。
注:enctype=”multipart/form-data” 的时候 php://input 是无效的。
举例:
就拿最近的HBCTF的一道题吧
相关源码:
1