前言:
最近打比赛,经常遇到php各种协议和伪协议的运用,因此抽时间总结一波。
php中支持的常用的协议有这些:
1 | file:// — 访问本地文件系统 |
file://协议:
1 | PHP.ini: |
file:// 访问本地文件系统:
说明:
1 | 文件系统 是 PHP 使用的默认封装协议,展现了本地文件系统。 当指定了一个相对路径(不以/、\、\\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录。 在很多情况下是脚本所在的目录,除非被修改了。 使用 CLI 的时候,目录默认是脚本被调用时所在的目录。 |
例如下面的index.php:
1 |
|
用下面的方式包含:
1 | http://localhost/test/index.php?cmd=file:///D:/PhpStudy/PHPTutorial/WWW/phpinfo.php |
http://由于见的太多了就不总结了。
ftp:// – ftps:// — 访问 FTP(s) URLs协议:
说明:
1 | 允许通过 FTP 读取存在的文件,以及创建新文件。 |
用法:
1 | ftp://example.com/pub/file.txt |
php://协议:
1 | php://filter在双off的情况下也可以正常使用; |
说明:
1 | PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。 |
php://filter:
1 | php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 |
1 | resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
举个例子:
1 | php://filter/read=convert.base64-encode/resource=upload.php |
过滤器:
过滤器有很多种,有字符串过滤器、转换过滤器、压缩过滤器、加密过滤器 <字符串过滤器>
1 | string.rot13 |
例子如下:
1 |
|
结果如下:
1 | rot13:Guvf vf n grfg. |
转换过滤器:
1 | 如同 string.* 过滤器,convert.* 过滤器的作用就和其名字一样。 |
例子如下:
1 |
|
结果如下:
1 | base64-encode:VGhpcyBpcyBhIHRlc3QuCg== |
压缩过滤器:
1 | 虽然 压缩封装协议提供了在本地文件系统中 创建 gzip 和 bz2 兼容文件的方法,但不代表可以在网络的流中提供通用压缩的意思,也不代表可以将一个非压缩的流转换成一个压缩流。 |
例子如下:
1 |
|
运行的结果如下:
1 | The original text is 70 characters long. |
加密过滤器:
1 | mcrypt.*和 mdecrypt.*使用 libmcrypt 提供了对称的加密和解密。这两组过滤器都支持 mcrypt 扩展库中相同的算法,格式为 mcrypt.ciphername,其中 ciphername是密码的名字,将被传递给 mcrypt_module_open()。有以下五个过滤器参数可用: |
加密过滤器的读写:
1 |
|
如下php://filter读取以base64:
1 |
|
读取的内容如下:
1 | PD9waHANCiRmbGFnPSJmbGFne2xpYW5namllfSI7DQo= |
在php中一般变量用单引号解析为字符串,而双引号如:
1 |
|
运行的结果如下:
1 | 121 |
php://input协议:
1 | php://input 是个可以访问请求的原始数据的只读流,可以读取到post没有解析的原始数据, 将post请求中的数据作为PHP代码执行。 |
需要的环境:
1 | PHP.ini: |
例如:
1 |
|
php://output协议:
说明:
1 | php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。 |
运行的结果如下:
1 | 通过访问:http://localhost/test/index.php/?cmd=php://output |
zip://, bzip2://, zlib://协议:
使用环境:
1 | PHP.ini: |
他们处理的文件:
1 | 3个封装协议,都是直接打开压缩文件。 |
zip://协议:
1 | php 版本大于等于 php5.3.0 |
测试:
新建一个zip.txt文件其中写入<?php phpinfo();?>压缩成zip文件然后改名为zip.jpg用如下的payload进行测试:
1 |
|
最后执行成功:
bzip2://协议:
1 | 使用方法: |
由于没有什么疑问就没有截图了:
data://协议:
说明:
1 | data:资源类型;编码,内容 |
需要的环境:
1 | PHP.ini: |
测试代码:
1 |
|
如下测试payload:
1 | 1: http://localhost/test/index.php/?cmd=data://text/plain,%3C?php%20phpinfo()?%3E |
上面的payload都是可以访问到phpinfo的。
举个例子通过data://协议进行xss:
测试代码如下:
1 |
|
我们可以用下面的payload绕过并通过返回<script>alert(1)</script>给页面造成xss:
1 | http://localhost/test/index.php?url=data://baidu.com/plain;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo= |
bytectf的一道题目:
1 |
|
第一要绕过域名的限制,第二只能执行如a(b(c()))这样的函数:
可以通过买一个xxxbaidu.com这样的baidu.com结尾的域名来绕过第一步:
绕过第二步可以参考一叶飘零的总结https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/:
感觉做题还是要多读文档。
glob://协议:
说明:
1 | glob:// — 查找匹配的文件路径模式 |
代码示例:
1 |
|
运行的结果如下:
1 | index.php: 0.0K |