LOADING

加载过慢请开启缓存 浏览器默认开启

php伪协议

2023/11/28

伪协议这玩意挺重要的,挺多地方都用得到,之前一直都没有系统的学一下,现在学学做个记录
他有两个前提条件allow_url_fopen 默认是ON和 allow_url_include 默认是OFF,后面有些是需要两个ON的,当然也有一些都不用,需要看具体的协议
他一般用在file_exists()``include()``file_put_contents()``file_get_contents()这些函数
php手册 PHP: 支持的协议和封装协议 - Manual
接下来用这段代码进行测试

<?php
    if(isset($_GET["file"])){
        @include($_GET["file"]);
    }
?>

file://协议

这个双OFF即可
这个可以用于读取本地文件,只能用绝对路径
对于文本文件其会直接显示内容,对于可以执行的php和js代码会直接执行
直接file://后面跟路径就行
例子?file=file:///var/www/test/flag
image.png

data://协议

这个需要双ON,需要 PHP>=5.2.0
这个主要用于写入代码到当前页面和执行代码
一般是data://text/plain;base64,后面跟文本就行,当然也可以data://text/plain,纯文本是可以嵌入显示的,然后php代码是可以执行的
例子?file=data://text/plain,<?phpinfo();或者?file=data://text/plain;base64,PD9waHBpbmZvKCk7
image.png

php://协议

这个不需要开启allow_url_fopen,仅php://input、php://stdin、 php://memory和php://temp需要开启allow_url_include和allow_url_fopen
image.png
这个用于访问各个输入/输出流

php://filter

这是我们最常用的一个伪协议用于数据流打开时的筛选过滤应用,这是php手册的解释:
image.png
他这个的格式就是php://filter/read=xxx/resource=xxx 每个参数用/隔开,后面跟等号和数据流名称或者过滤器名称
最常用的就是?file=php://filter/read=convert.base64-encode/resource=flag
image.png
接下来我们来说一下过滤器,有字符串过滤器,转换过滤器,压缩过滤器,加密过滤器四种,php手册https://www.php.net/manual/zh/filters.php

  1. 字符串过滤器 string.*

这个就是用来处理字符串的,大小写转换啥的

  • string.rot13:rot13转换
  • string.toupper:大写转换
  • string.tolower:小写转换
  • string.strip_tags:去掉html标记和空字符(php7.3之后废弃)(但是可以绕过例如file_put_contents($_GET['filename'], "<?php exit; ?>".$content);这样的死亡exit,直接把前面的php当作html标签去掉)
  1. 转换过滤器 convert.*

主要是进行编码的转换,用的最多的就是b64转换

  • convert.base64-encode & convert.base64-decode:b64编码解码

文档里的示例如下,可以看出这个过滤器不仅是可以用在php://filter里面的,也可以看出伪协议其实就像是一种对于文件的中间操作
image.png

  • convert.quoted-printable-encode & convert.quoted-printable-decode:转化为8-bit 字符串
  • convert.iconv.*:等同于用 iconv() 处理所有的流数据
  1. 压缩过滤器

在过滤器里的压缩方法,和zip://协议不同

  • zlib.deflate 和 zlib.inflate
  • bzip2.compress 和 bzip2.decompress
  1. 加密过滤器
  • mcrypt.* 和 mdecrypt.*:可以选mode进行加密,但是在PHP 7.1.0起废弃

php://input

这个就是获取post里面的数据,如果是php代码会直接执行,例如

$file=file_get_contents('php://input'); //获取post的数据并赋给$file
file_put_contents("a.txt",urldecode($file)); //写文件,文件名是a.txt,内容是$file

php://output

一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区

php://fd

允许直接访问指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3

php://memory 和 php://temp

类似文件包装器的数据流,允许读写临时数据

php://stdin, php://stdout 和 php://stderr

允许直接访问 PHP 进程相应的输入或者输出流

zip:// & bzip2:// & zlib:// 协议

两个参数没有要求,ON或者OFF都行
这三个协议都属于压缩流,用于访问压缩文件中的子文件,ctf中有些压缩解压缩的题目用得到
zip需要绝对路径,zlib不需要绝对路径,
可以访问压缩包里面的文件
例如?file=zip:///var/www/test/zz.zip/flag
如果需要改压缩包名字的话就在压缩包目录后面加新名字和#(%23)和子文件名字
例如?file=zip:///var/www/test/zz.txt#flag就是把flag压缩成zip之后再重命名为zz.txt,如果flag里面是php代码的话可以直接执行
如果只是压缩的话就用例如compress.bzip2://``compress.zlib://,注意这两个前面要加compress,而且没有绝对路径的限制

phar://协议

phar就相当于php的压缩包,可以用phar://去访问其中的内容(不用绝对路径),例如phar://1.phar/test.txt,然后如果包含的phar文件是序列化文件然后传过去的代码里可以对应上的话也可以用来反序列化
这个主要用于phar反序列化,详细的可以去看phar反序列化学习

http://协议

两个都要ON
允许通过 HTTP 对文件/资源进行可读访问,可以用作远程包含
例如?file=http://127.0.0.1/phpinfo.txt

glob://协议

两个OFF即可
这玩意有点意思,作为数据流包装器可以查找匹配的文件路径模式,在查找文件的时候很有用
很多像是include() 或者file_exist()函数都可以用glob去进行文件的筛选,然后找到flag到底在哪