php伪协议
前言
PHP伪协议在CTF中经常出现,也经常跟文件包含,文件上传,命令执行等漏洞结合在一起,所以本文章对常见的一些协议进行总结。
| 1 | file:// — 访问本地文件系统 | 
今天着重研究php://
有两个比较重要的配置在php.ini中,allow_url_fopen 和allow_url_include会影响到fopen等等和include等等函数对于伪协
议的支持,而allow_url_include依赖allow_url_fopen,所以allow_url_fopen不开启的话,allow_url_include也是无法使用的。
php伪协议
php://input
php://input代表可以访问请求的原始数据,简单来说POST请求的情况下,php://input可以获取到post的数据。
- 使用条件:include()、include_once()、file_get_contents()
比较特殊的一点,enctype=”multipart/form-data” 的时候 php://input 是无效的。
php://output
php://output 是一个只写的数据流,允许你以 print 和 echo 一样的方式写入到输出缓冲区。
php://filter(重点)
这篇文章的关键在于讨论php://filter,事实上,这也是我们常常使用的一个伪协议,在任意文件读取,甚至getshell的时候都有利用的机会。
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用,也就是作为一种过滤器,可以使用在数据流产生的地方。
这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
事实上,在include函数的使用上,经常会造成任意文件读取漏洞,而file_get_contents()和file_put_contents()这样函数下,常常会构成getshell等更严重的漏洞。
URL中包含点的常见形式
- ?file = xxx 或者 ?file = xxx.php- 那么源码中的写法: - include($file.'php') 或者 include($file)- 这里直接使用伪协议包含: - ?file=php://filter/read=convert.base64-encode/resource=login
- ?action = xxx & mode = xxx- 这里形式就是文件夹加上文件名的方法 - http://www.example.com/index.php?action=front&mode=login- 那么源码中的写法: - include($action.'/'.$mode.'.php');- 那么对于这种情况使用的伪协议包含形式: - ?action=php://filter/read=convert.base64-encode/resource=./&mode=login
举个例子
题目链接:http://level3.tasteless.en/
题目直接给出了源码:
| 1 | <?php | 
用php://input直接就能执行任意代码
绕过waf的方法
在一些ctf中会对一些伪协议的关键词进行过滤,如read、resource等等,下面总结了几条绕过方法,在实战总作为字典来跑。
| 1 | ?f=php://filter/convert.base64-encode/resource=login.php(过滤了操作名read) | 
截断包含
截断
这里技巧现在应该是用的比较少了,因为利用截断要满足下面的两个条件:
- php版本小于5.3.4 
- magic_quotes_gpc为off 
./ 截断
点号和路径截断以及./截断,也就是填充大量的./使url长度超过最大值,来达到截断的目的。
具体可以看下面的文章:https://blog.csdn.net/zvall/article/details/8951925
zip协议和phar协议
在实战过程中,若发现存在文件上传但是没有办法直接上传php文件,可以传zip压缩文件,我们就利用这两个协议,将php文件打包成zip文件来包含里面的php脚本。
phar://、zip://,都可以看到在phpinfo中有相应的描述。
例如脚本文件为1.php,打包成1.zip,然后再改名为1.jpg,上传之后包含1.jpg中的php文件即可。
| 1 | zip://..(当前脚本的绝对路径).../1.jpg#1.php |