有关php伪协议的一些特性
php://filter
read和write
读文件时触发read
1  | php://filter/read=convert.base64-encode/resource=xxx  | 
写文件时触发write
1  | php://filter/write=convert.base64-decode/resource=xxx  | 
向xxx写入base64解码的内容
同时,下面的写法也是合法的:
1  | pHp://filter/read=convert.base64-encode/resource=xxx  | 
这说明伪协议不区分大小写
如果使用的不是read或者write,则会报错:
1  | php://filter/abcs=convert.base64-decode/resource=xxx  | 
如果没有写,则会自动推导是write还是read:
1  | php://filter/convert.base64-encode/resource=xxx  | 
可以使用多个过滤器:
1  | php://filter/read=A|B/resource=  | 
1  | php://filter/read=A/write=B/resource=  | 
绕过死亡exit
谈一谈php://filter的妙用 | 离别歌 (leavesongs.com)
1  | php://filter/read=convert.base64-decode/resource=xxx  | 
这两种协议都会先对内容进行处理,再进行base64的解码
其实就是在解码的过程中,字符<、?、;、>、空格、单双引号等会被忽略
假如我有一个file_put_contents
1  | $filename = $_GET['filename'];  | 
此时它会把我们的恶意代码提前写入<?php die("nononon");?>,导致我们的恶意代码被提前结束
此时我们可以利用php伪协议的特性:
1  | php://filter/write=convert.base64-decode/resource=shell.php  | 
此时会向shell.php写入伪协议处理后的decode的内容
经过处理后就会变成phpdienononon加上我们的内容
此时由于base64解码是4字节一组的解码方式,我们需要在前面加上任意字符使得xxxphpdienononon刚好是四的倍数个长度
此时前面就会被解码成乱码,后面会被正常解码成我们的shell
其他的过滤器:
convert.quoted-printable-encode打印不可见字符convert.iconv.utf-8.utf-16beuft8 -> utf16convert.iconv.utf8.utf-7(可去除等号) utf8 -> utf7convert.iconv.ASCII.UCS-2BEascii -> UCS-2BEstring.strip_tags去除html和php的标签
…
url编码
php会对过滤器decode多一次,所以可以用url编码绕过(?)
1  | php://filter/read=conv%65rt.b%61se64-encode/resource=flag.php  |