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://filte
r,事实上,这也是我们常常使用的一个伪协议,在任意文件读取,甚至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 |